Compare commits
14 Commits
test
...
release/1.7.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 81d9eb136d | |||
| f4b6caea77 | |||
| 570ee76979 | |||
| 48fc64d22f | |||
| 5358650e12 | |||
| c514731c8e | |||
| ab759755ec | |||
| 26ded22131 | |||
| d67c7e2c60 | |||
| b54e734e60 | |||
| 5c2c63f852 | |||
| da27577d9c | |||
| 59b2198499 | |||
| 1295b09ecb |
@@ -1,6 +1,6 @@
|
||||
.PHONY: build clean ui
|
||||
|
||||
VERSION=1.7.0
|
||||
VERSION=1.7.1
|
||||
BIN=answer
|
||||
DIR_SRC=./cmd/answer
|
||||
DOCKER_CMD=docker
|
||||
|
||||
@@ -23,7 +23,7 @@ To learn more about the project, visit [answer.apache.org](https://answer.apache
|
||||
### Running with docker
|
||||
|
||||
```bash
|
||||
docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:1.7.0
|
||||
docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:1.7.1
|
||||
```
|
||||
|
||||
For more information, see [Installation](https://answer.apache.org/docs/installation).
|
||||
|
||||
+2
-3
@@ -1208,9 +1208,7 @@ ui:
|
||||
search:
|
||||
placeholder: Search
|
||||
footer:
|
||||
build_on: >-
|
||||
Powered by <1> Apache Answer </1>- the open-source software that powers Q&A
|
||||
communities.<br />Made with love © {{cc}}.
|
||||
build_on: Powered by <1> Apache Answer </1>
|
||||
upload_img:
|
||||
name: Change
|
||||
loading: loading...
|
||||
@@ -1807,6 +1805,7 @@ ui:
|
||||
branding: Branding
|
||||
legal: Legal
|
||||
write: Write
|
||||
terms: Terms
|
||||
tos: Terms of Service
|
||||
privacy: Privacy
|
||||
seo: SEO
|
||||
|
||||
+2
-2
@@ -1190,8 +1190,7 @@ ui:
|
||||
search:
|
||||
placeholder: 搜索
|
||||
footer:
|
||||
build_on: >-
|
||||
由 <1>Apache Answer</1> 提供动力 - 驱动问答社区的开源软件。<br />用爱制造 © {{cc}}.
|
||||
build_on: 由 <1>Apache Answer</1> 提供动力
|
||||
upload_img:
|
||||
name: 更改
|
||||
loading: 加载中...
|
||||
@@ -1768,6 +1767,7 @@ ui:
|
||||
branding: 品牌
|
||||
legal: 法律条款
|
||||
write: 撰写
|
||||
terms: 服务条款
|
||||
tos: 服务条款
|
||||
privacy: 隐私政策
|
||||
seo: SEO
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
.answer-container {
|
||||
.main-mx-with {
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 95px - 62px);
|
||||
max-width: 1072px;
|
||||
}
|
||||
|
||||
.answer-container {
|
||||
min-height: calc(100vh - 53px - 62px);
|
||||
}
|
||||
|
||||
.page-right-side {
|
||||
flex: none;
|
||||
width: 300px;
|
||||
@@ -31,7 +34,7 @@
|
||||
|
||||
// lg
|
||||
@media screen and (max-width: 1199.9px) {
|
||||
.answer-container {
|
||||
.main-mx-with {
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ import './index.scss';
|
||||
interface IProps {
|
||||
objectId: string;
|
||||
mode?: 'answer' | 'question';
|
||||
commentId?: string;
|
||||
commentId?: string | null;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
import Row from 'react-bootstrap/Row';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { siteInfoStore } from '@/stores';
|
||||
@@ -29,34 +30,37 @@ const Index = () => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'footer' }); // Scoped translations for footer
|
||||
const fullYear = dayjs().format('YYYY');
|
||||
const siteName = siteInfoStore((state) => state.siteInfo.name);
|
||||
const cc = `${fullYear} ${siteName}`;
|
||||
const cc = `${siteName} © ${fullYear}`;
|
||||
|
||||
return (
|
||||
<footer className="py-3 w-100">
|
||||
<p className="text-center mb-0 small">
|
||||
{/* Link to Terms of Service with right margin */}
|
||||
<Link to="/tos" className="me-3">
|
||||
{t('label', { keyPrefix: 'admin.legal.terms_of_service' })}
|
||||
</Link>
|
||||
<Row>
|
||||
<footer className="py-3 d-flex flex-wrap align-items-center justify-content-between text-secondary small">
|
||||
<div className="d-flex align-items-center">
|
||||
<div className="me-3">{cc}</div>
|
||||
|
||||
{/* Link to Privacy Policy with right margin for spacing */}
|
||||
<Link to="/privacy">
|
||||
{t('label', { keyPrefix: 'admin.legal.privacy_policy' })}
|
||||
</Link>
|
||||
</p>
|
||||
<p className="text-center mb-0 small">
|
||||
<Trans i18nKey="footer.build_on" values={{ cc }}>
|
||||
Powered by
|
||||
{/* eslint-disable-next-line react/jsx-no-target-blank */}
|
||||
<a href="https://answer.apache.org" target="_blank">
|
||||
Apache Answer
|
||||
</a>
|
||||
- the open-source software that powers Q&A communities.
|
||||
<br />
|
||||
Made with love. © 2022 Answer.
|
||||
</Trans>
|
||||
</p>
|
||||
</footer>
|
||||
<Link to="/tos" className="me-3 link-secondary">
|
||||
{t('terms', { keyPrefix: 'nav_menus' })}
|
||||
</Link>
|
||||
|
||||
{/* Link to Privacy Policy with right margin for spacing */}
|
||||
<Link to="/privacy" className="link-secondary">
|
||||
{t('privacy', { keyPrefix: 'nav_menus' })}
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<Trans i18nKey="footer.build_on" values={{ cc }}>
|
||||
Powered by
|
||||
<a
|
||||
href="https://answer.apache.org"
|
||||
target="_blank"
|
||||
className="link-secondary"
|
||||
rel="noreferrer">
|
||||
Apache Answer
|
||||
</a>
|
||||
</Trans>
|
||||
</div>
|
||||
</footer>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ const Index: FC<Props> = ({
|
||||
...formData,
|
||||
[name]: {
|
||||
...formData[name],
|
||||
value,
|
||||
value: type === 'number' ? Number(value) : value,
|
||||
isInvalid: false,
|
||||
},
|
||||
};
|
||||
|
||||
+3
-3
@@ -53,7 +53,9 @@ img[src=''] {
|
||||
}
|
||||
|
||||
.page-main {
|
||||
overflow-x: auto;
|
||||
min-width: 0;
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
@@ -127,8 +129,6 @@ img[src=''] {
|
||||
margin-top: auto !important;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
padding-left: 12px !important;
|
||||
padding-right: 12px !important;
|
||||
}
|
||||
|
||||
.bg-f5 {
|
||||
|
||||
@@ -52,7 +52,7 @@ const Badges: FC = () => {
|
||||
const { data, isLoading, mutate } = useQueryBadges({
|
||||
page: curPage,
|
||||
page_size: PAGE_SIZE,
|
||||
q: curQuery,
|
||||
...(curQuery ? { q: curQuery } : {}),
|
||||
...(curFilter === 'all' ? {} : { status: curFilter }),
|
||||
});
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ const Smtp: FC = () => {
|
||||
enumNames: ['TLS', 'SSL', 'None'],
|
||||
},
|
||||
smtp_port: {
|
||||
type: 'string',
|
||||
type: 'number',
|
||||
title: t('smtp_port.label'),
|
||||
description: t('smtp_port.text'),
|
||||
},
|
||||
@@ -160,7 +160,7 @@ const Smtp: FC = () => {
|
||||
from_name: formData.from_name.value,
|
||||
smtp_host: formData.smtp_host.value,
|
||||
encryption: formData.encryption.value,
|
||||
smtp_port: Number(formData.smtp_port.value),
|
||||
smtp_port: formData.smtp_port.value,
|
||||
smtp_authentication: formData.smtp_authentication.value,
|
||||
...(formData.smtp_authentication.value
|
||||
? { smtp_username: formData.smtp_username.value }
|
||||
|
||||
@@ -54,7 +54,7 @@ const Index: FC = () => {
|
||||
</div>
|
||||
<div className="flex-fill w-100">
|
||||
<div className="d-flex justify-content-center px-0 px-md-4">
|
||||
<div className="answer-container">
|
||||
<div className="answer-container main-mx-with">
|
||||
<Row className="py-4">
|
||||
<Col className="page-main flex-auto">
|
||||
<Outlet />
|
||||
@@ -65,7 +65,11 @@ const Index: FC = () => {
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
<div className="d-flex justify-content-center px-0 px-md-4">
|
||||
<div className="main-mx-with">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -169,7 +169,7 @@ const Index: FC<Props> = ({
|
||||
<Comment
|
||||
objectId={data.id}
|
||||
mode="answer"
|
||||
commentId={String(searchParams.get('commentId'))}>
|
||||
commentId={searchParams.get('commentId')}>
|
||||
<Operate
|
||||
qid={data.question_id}
|
||||
aid={data.id}
|
||||
|
||||
@@ -189,7 +189,7 @@ const Index: FC<Props> = ({ data, initPage, hasAnswer, isLogged }) => {
|
||||
<Comment
|
||||
objectId={data?.id}
|
||||
mode="question"
|
||||
commentId={String(searchParams.get('commentId'))}>
|
||||
commentId={searchParams.get('commentId')}>
|
||||
<Operate
|
||||
qid={data?.id}
|
||||
type="question"
|
||||
|
||||
@@ -34,11 +34,15 @@ const Index: FC = () => {
|
||||
</div>
|
||||
<div className="flex-fill w-100 overflow-x-hidden">
|
||||
<div className="d-flex justify-content-center px-0 px-md-4">
|
||||
<div className="answer-container">
|
||||
<div className="answer-container main-mx-with">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
<div className="d-flex justify-content-center">
|
||||
<div className="main-mx-with">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -24,7 +24,7 @@ import request from '@/utils/request';
|
||||
import type * as Type from '@/common/interface';
|
||||
|
||||
export const useQueryBadges = (params) => {
|
||||
const apiUrl = `/answer/admin/api/badges?${qs.stringify(params)}`;
|
||||
const apiUrl = `/answer/admin/api/badges?${qs.stringify(params, { skipNulls: true })}`;
|
||||
const { data, error, mutate } = useSWR<
|
||||
Type.ListResult<Type.AdminBadgeListItem>,
|
||||
Error
|
||||
|
||||
+19
-15
@@ -19,21 +19,25 @@
|
||||
|
||||
-->
|
||||
{{define "footer"}}
|
||||
<footer class="py-3 bg-light w-100">
|
||||
<p class="text-center mb-0 small">
|
||||
<a class="me-3" href="{{$.baseURL}}/tos" data-discover="true">
|
||||
{{translator $.language "ui.admin.legal.terms_of_service.label"}}
|
||||
</a>
|
||||
<a href="{{$.baseURL}}/privacy" data-discover="true">
|
||||
{{translator $.language "ui.admin.legal.privacy_policy.label"}}
|
||||
</a>
|
||||
</p>
|
||||
<p class="text-center mb-0 small text-secondary">
|
||||
{{$cc := (join " " .siteinfo.Year .siteinfo.General.Name) -}}
|
||||
{{- $ft := translator $.language "ui.footer.build_on" "cc" $cc -}}
|
||||
{{templateHTML (replaceHTMLTag $ft "<a href=\"https://answer.apache.org/\" target=\"_blank\"> Answer </a>")}}
|
||||
</p>
|
||||
</footer>
|
||||
<div class="main-mx-with">
|
||||
<div class="row">
|
||||
<footer class="py-3 d-flex flex-wrap align-items-center justify-content-between text-secondary small">
|
||||
<div class="d-flex align-items-center">
|
||||
{{$cc := (join " " .siteinfo.General.Name .siteinfo.Year)}}
|
||||
<div className="me-3">{{- $ft := translator $.language "ui.footer.build_on" "cc" $cc -}}</div>
|
||||
<a class="me-3" href="{{$.baseURL}}/tos" data-discover="true" class="link-secondary">
|
||||
{{translator $.language "ui.admin.legal.terms_of_service.label"}}
|
||||
</a>
|
||||
<a href="{{$.baseURL}}/privacy" data-discover="true" class="link-secondary">
|
||||
{{translator $.language "ui.admin.legal.privacy_policy.label"}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-center mb-0 small text-secondary link-secondary">
|
||||
{{templateHTML (replaceHTMLTag $ft "<a href=\"https://answer.apache.org/\" target=\"_blank\"> Answer </a>")}}
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user