mirror of https://gitee.com/answerdev/answer.git
Merge branch 'ui-v0.3' of git.backyard.segmentfault.com:opensource/answer into ui-v0.3
This commit is contained in:
commit
b6026dae16
|
@ -22,6 +22,11 @@ module.exports = {
|
|||
changeOrigin: true,
|
||||
secure: false,
|
||||
},
|
||||
'/installation': {
|
||||
target: 'http://10.0.10.98:2060',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
},
|
||||
};
|
||||
return config;
|
||||
};
|
||||
|
|
|
@ -258,6 +258,8 @@ export interface AdminSettingsGeneral {
|
|||
name: string;
|
||||
short_description: string;
|
||||
description: string;
|
||||
site_url: string;
|
||||
contact_email: string;
|
||||
}
|
||||
|
||||
export interface AdminSettingsInterface {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FC, memo } from 'react';
|
||||
import { ButtonGroup, Button, DropdownButton, Dropdown } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useSearchParams, useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
@ -11,6 +11,7 @@ interface Props {
|
|||
currentSort: string;
|
||||
sortKey?: string;
|
||||
className?: string;
|
||||
pathname?: string;
|
||||
}
|
||||
const MAX_BUTTON_COUNT = 3;
|
||||
const Index: FC<Props> = ({
|
||||
|
@ -19,8 +20,10 @@ const Index: FC<Props> = ({
|
|||
sortKey = 'order',
|
||||
i18nKeyPrefix = '',
|
||||
className = '',
|
||||
pathname = '',
|
||||
}) => {
|
||||
const [searchParams, setUrlSearchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: i18nKeyPrefix,
|
||||
|
@ -36,7 +39,11 @@ const Index: FC<Props> = ({
|
|||
const handleClick = (e, type) => {
|
||||
e.preventDefault();
|
||||
const str = handleParams(type);
|
||||
setUrlSearchParams(str);
|
||||
if (pathname) {
|
||||
navigate(`${pathname}${str}`);
|
||||
} else {
|
||||
setUrlSearchParams(str);
|
||||
}
|
||||
};
|
||||
|
||||
const filteredData = data.filter((_, index) => index > MAX_BUTTON_COUNT - 2);
|
||||
|
@ -69,7 +76,9 @@ const Index: FC<Props> = ({
|
|||
}
|
||||
: {}
|
||||
}
|
||||
href={handleParams(key)}
|
||||
href={
|
||||
pathname ? `${pathname}${handleParams(key)}` : handleParams(key)
|
||||
}
|
||||
onClick={(evt) => handleClick(evt, key)}>
|
||||
{t(name)}
|
||||
</Button>
|
||||
|
@ -95,7 +104,11 @@ const Index: FC<Props> = ({
|
|||
'd-block d-md-none',
|
||||
className,
|
||||
)}
|
||||
href={handleParams(key)}
|
||||
href={
|
||||
pathname
|
||||
? `${pathname}${handleParams(key)}`
|
||||
: handleParams(key)
|
||||
}
|
||||
onClick={(evt) => handleClick(evt, key)}>
|
||||
{t(name)}
|
||||
</Dropdown.Item>
|
||||
|
|
|
@ -115,6 +115,7 @@ const QuestionList: FC<Props> = ({ source }) => {
|
|||
<QueryGroup
|
||||
data={QuestionOrderKeys}
|
||||
currentSort={curOrder}
|
||||
pathname={source === 'questions' ? '/questions' : ''}
|
||||
i18nKeyPrefix="question"
|
||||
/>
|
||||
</Col>
|
||||
|
|
|
@ -744,6 +744,7 @@
|
|||
"title": "Answer",
|
||||
"next": "Next",
|
||||
"done": "Done",
|
||||
"config_yaml_error": "Can’t create the config.yaml file.",
|
||||
"lang": {
|
||||
"label": "Please choose a language"
|
||||
},
|
||||
|
@ -784,22 +785,42 @@
|
|||
"site_information": "Site Information",
|
||||
"admin_account": "Admin Account",
|
||||
"site_name": {
|
||||
"label": "Site Name"
|
||||
"label": "Site Name",
|
||||
"msg": "Site Name cannot be empty."
|
||||
},
|
||||
"site_url": {
|
||||
"label": "Site URL",
|
||||
"text": "The address of your site.",
|
||||
"msg": {
|
||||
"empty": "Site URL cannot be empty.",
|
||||
"incorrect": "Site URL incorrect format."
|
||||
}
|
||||
},
|
||||
"contact_email": {
|
||||
"label": "Contact Email",
|
||||
"text": "Email address of key contact responsible for this site."
|
||||
"text": "Email address of key contact responsible for this site.",
|
||||
"msg": {
|
||||
"empty": "Contact Email cannot be empty.",
|
||||
"incorrect": "Contact Email incorrect format."
|
||||
}
|
||||
|
||||
},
|
||||
"admin_name": {
|
||||
"label": "Name"
|
||||
"label": "Name",
|
||||
"msg": "Name cannot be empty."
|
||||
},
|
||||
"admin_password": {
|
||||
"label": "Password",
|
||||
"text": "You will need this password to log in. Please store it in a secure location."
|
||||
"text": "You will need this password to log in. Please store it in a secure location.",
|
||||
"msg": "Password cannot be empty."
|
||||
},
|
||||
"admin_email": {
|
||||
"label": "Email",
|
||||
"text": "You will need this email to log in."
|
||||
"text": "You will need this email to log in.",
|
||||
"msg": {
|
||||
"empty": "Email cannot be empty.",
|
||||
"incorrect": "Email incorrect format."
|
||||
}
|
||||
},
|
||||
"ready_title": "Your Answer is Ready!",
|
||||
"ready_description": "If you ever feel like changing more settings, visit <1>admin section</1>; find it in the site menu.",
|
||||
|
@ -976,6 +997,11 @@
|
|||
"msg": "Site name cannot be empty.",
|
||||
"text": "The name of this site, as used in the title tag."
|
||||
},
|
||||
"site_url": {
|
||||
"label": "Site URL",
|
||||
"msg": "Site url cannot be empty.",
|
||||
"text": "The address of your site."
|
||||
},
|
||||
"short_description": {
|
||||
"label": "Short Site Description (optional)",
|
||||
"msg": "Short site description cannot be empty.",
|
||||
|
@ -985,6 +1011,11 @@
|
|||
"label": "Site Description (optional)",
|
||||
"msg": "Site description cannot be empty.",
|
||||
"text": "Describe this site in one sentence, as used in the meta description tag."
|
||||
},
|
||||
"contact_email": {
|
||||
"label": "Contact Email",
|
||||
"msg": "Contact email cannot be empty.",
|
||||
"text": "Email address of key contact responsible for this site."
|
||||
}
|
||||
},
|
||||
"interface": {
|
||||
|
@ -1004,7 +1035,7 @@
|
|||
"msg": "Interface language cannot be empty.",
|
||||
"text": "User interface language. It will change when you refresh the page."
|
||||
},
|
||||
"timezone": {
|
||||
"time_zone": {
|
||||
"label": "Timezone",
|
||||
"msg": "Timezone cannot be empty.",
|
||||
"text": "Choose a UTC (Coordinated Universal Time) time offset."
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { FC } from 'react';
|
||||
import { Card, Row, Col } from 'react-bootstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import type * as Type from '@/common/interface';
|
||||
|
||||
|
@ -38,9 +39,9 @@ const Statistics: FC<IProps> = ({ data }) => {
|
|||
<Col xs={6}>
|
||||
<span className="text-secondary me-1">{t('flags')}</span>
|
||||
<strong>{data.report_count}</strong>
|
||||
<a href="###" className="ms-2">
|
||||
<Link to="/admin/flags" className="ms-2">
|
||||
{t('review')}
|
||||
</a>
|
||||
</Link>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card.Body>
|
||||
|
|
|
@ -23,6 +23,11 @@ const General: FC = () => {
|
|||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
site_url: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
short_description: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
|
@ -33,10 +38,15 @@ const General: FC = () => {
|
|||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
contact_email: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
});
|
||||
const checkValidated = (): boolean => {
|
||||
let ret = true;
|
||||
const { name } = formData;
|
||||
const { name, site_url, contact_email } = formData;
|
||||
if (!name.value) {
|
||||
ret = false;
|
||||
formData.name = {
|
||||
|
@ -45,6 +55,22 @@ const General: FC = () => {
|
|||
errorMsg: t('name.msg'),
|
||||
};
|
||||
}
|
||||
if (!site_url.value) {
|
||||
ret = false;
|
||||
formData.site_url = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('site_url.msg'),
|
||||
};
|
||||
}
|
||||
if (!contact_email.value) {
|
||||
ret = false;
|
||||
formData.contact_email = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('contact_email.msg'),
|
||||
};
|
||||
}
|
||||
setFormData({
|
||||
...formData,
|
||||
});
|
||||
|
@ -61,6 +87,8 @@ const General: FC = () => {
|
|||
name: formData.name.value,
|
||||
description: formData.description.value,
|
||||
short_description: formData.short_description.value,
|
||||
site_url: formData.site_url.value,
|
||||
contact_email: formData.contact_email.value,
|
||||
};
|
||||
|
||||
updateGeneralSetting(reqParams)
|
||||
|
@ -100,7 +128,7 @@ const General: FC = () => {
|
|||
Object.keys(setting).forEach((k) => {
|
||||
formMeta[k] = { ...formData[k], value: setting[k] };
|
||||
});
|
||||
setFormData(formMeta);
|
||||
setFormData({ ...formData, ...formMeta });
|
||||
}, [setting]);
|
||||
return (
|
||||
<>
|
||||
|
@ -120,6 +148,20 @@ const General: FC = () => {
|
|||
{formData.name.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="siteUrl" className="mb-3">
|
||||
<Form.Label>{t('site_url.label')}</Form.Label>
|
||||
<Form.Control
|
||||
required
|
||||
type="text"
|
||||
value={formData.site_url.value}
|
||||
isInvalid={formData.site_url.isInvalid}
|
||||
onChange={(evt) => onFieldChange('site_url', evt.target.value)}
|
||||
/>
|
||||
<Form.Text as="div">{t('site_url.text')}</Form.Text>
|
||||
<Form.Control.Feedback type="invalid">
|
||||
{formData.site_url.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="shortDescription" className="mb-3">
|
||||
<Form.Label>{t('short_description.label')}</Form.Label>
|
||||
<Form.Control
|
||||
|
@ -150,6 +192,20 @@ const General: FC = () => {
|
|||
{formData.description.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="contact_email" className="mb-3">
|
||||
<Form.Label>{t('contact_email.label')}</Form.Label>
|
||||
<Form.Control
|
||||
required
|
||||
type="text"
|
||||
value={formData.contact_email.value}
|
||||
isInvalid={formData.contact_email.isInvalid}
|
||||
onChange={(evt) => onFieldChange('contact_email', evt.target.value)}
|
||||
/>
|
||||
<Form.Text as="div">{t('contact_email.text')}</Form.Text>
|
||||
<Form.Control.Feedback type="invalid">
|
||||
{formData.contact_email.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
|
||||
<Button variant="primary" type="submit">
|
||||
{t('save', { keyPrefix: 'btns' })}
|
||||
|
|
|
@ -6,8 +6,9 @@ import Progress from '../Progress';
|
|||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
siteUrl: string;
|
||||
}
|
||||
const Index: FC<Props> = ({ visible }) => {
|
||||
const Index: FC<Props> = ({ visible, siteUrl = '' }) => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
||||
|
||||
if (!visible) return null;
|
||||
|
@ -17,14 +18,15 @@ const Index: FC<Props> = ({ visible }) => {
|
|||
<p>
|
||||
<Trans i18nKey="install.ready_description">
|
||||
If you ever feel like changing more settings, visit
|
||||
<a href="/">admin section</a>; find it in the site menu.
|
||||
<a href={`${siteUrl}/users/login`}>admin section</a>; find it in the
|
||||
site menu.
|
||||
</Trans>
|
||||
</p>
|
||||
<p>{t('good_luck')}</p>
|
||||
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<Progress step={5} />
|
||||
<Button>{t('done')}</Button>
|
||||
<Button href={siteUrl}>{t('done')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
|||
|
||||
import type { LangsType, FormValue, FormDataType } from '@/common/interface';
|
||||
import Progress from '../Progress';
|
||||
import { getLanguageOptions } from '@/services';
|
||||
import { getInstallLangOptions } from '@/services';
|
||||
|
||||
interface Props {
|
||||
data: FormValue;
|
||||
|
@ -18,8 +18,15 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
const [langs, setLangs] = useState<LangsType[]>();
|
||||
|
||||
const getLangs = async () => {
|
||||
const res: LangsType[] = await getLanguageOptions();
|
||||
const res: LangsType[] = await getInstallLangOptions();
|
||||
setLangs(res);
|
||||
changeCallback({
|
||||
lang: {
|
||||
value: res[0].value,
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
|
|
|
@ -18,6 +18,7 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
let bol = true;
|
||||
const {
|
||||
site_name,
|
||||
site_url,
|
||||
contact_email,
|
||||
admin_name,
|
||||
admin_password,
|
||||
|
@ -33,12 +34,40 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
};
|
||||
}
|
||||
|
||||
if (!site_url.value) {
|
||||
bol = false;
|
||||
data.site_url = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('site_name.msg.empty'),
|
||||
};
|
||||
}
|
||||
const reg = /^(http|https):\/\//g;
|
||||
if (site_url.value && !site_url.value.match(reg)) {
|
||||
bol = false;
|
||||
data.site_url = {
|
||||
value: site_url.value,
|
||||
isInvalid: true,
|
||||
errorMsg: t('site_url.msg.incorrect'),
|
||||
};
|
||||
}
|
||||
|
||||
if (!contact_email.value) {
|
||||
bol = false;
|
||||
data.contact_email = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('contact_email.msg'),
|
||||
errorMsg: t('contact_email.msg.empty'),
|
||||
};
|
||||
}
|
||||
|
||||
const mailReg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
|
||||
if (contact_email.value && !contact_email.value.match(mailReg)) {
|
||||
bol = false;
|
||||
data.contact_email = {
|
||||
value: contact_email.value,
|
||||
isInvalid: true,
|
||||
errorMsg: t('contact_email.msg.incorrect'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -65,7 +94,16 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
data.admin_email = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('admin_email.msg'),
|
||||
errorMsg: t('admin_email.msg.empty'),
|
||||
};
|
||||
}
|
||||
|
||||
if (admin_email.value && !admin_email.value.match(mailReg)) {
|
||||
bol = false;
|
||||
data.admin_email = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('admin_email.msg.incorrect'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -108,6 +146,27 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
{data.site_name.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="site_url" className="mb-3">
|
||||
<Form.Label>{t('site_url.label')}</Form.Label>
|
||||
<Form.Control
|
||||
required
|
||||
value={data.site_url.value}
|
||||
isInvalid={data.site_url.isInvalid}
|
||||
onChange={(e) => {
|
||||
changeCallback({
|
||||
site_url: {
|
||||
value: e.target.value,
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Form.Text>{t('site_url.text')}</Form.Text>
|
||||
<Form.Control.Feedback type="invalid">
|
||||
{data.site_url.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="contact_email" className="mb-3">
|
||||
<Form.Label>{t('contact_email.label')}</Form.Label>
|
||||
<Form.Control
|
||||
|
|
|
@ -6,29 +6,43 @@ import Progress from '../Progress';
|
|||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
errorMsg;
|
||||
nextCallback: () => void;
|
||||
}
|
||||
|
||||
const Index: FC<Props> = ({ visible, nextCallback }) => {
|
||||
const Index: FC<Props> = ({ visible, errorMsg, nextCallback }) => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
||||
|
||||
if (!visible) return null;
|
||||
return (
|
||||
<div>
|
||||
<h5>{t('config_yaml.title')}</h5>
|
||||
<div className="mb-3">{t('config_yaml.label')}</div>
|
||||
<div className="fmt">
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="install.config_yaml.description"
|
||||
components={{ 1: <code /> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<FormGroup className="mb-3">
|
||||
<Form.Control type="text" as="textarea" rows={5} className="fs-14" />
|
||||
</FormGroup>
|
||||
<div className="mb-3">{t('config_yaml.info')}</div>
|
||||
|
||||
{errorMsg?.msg?.length > 0 ? (
|
||||
<>
|
||||
<div className="fmt">
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="install.config_yaml.description"
|
||||
components={{ 1: <code /> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<FormGroup className="mb-3">
|
||||
<Form.Control
|
||||
type="text"
|
||||
as="textarea"
|
||||
rows={8}
|
||||
className="fs-14"
|
||||
value={errorMsg?.default_config}
|
||||
/>
|
||||
</FormGroup>
|
||||
<div className="mb-3">{t('config_yaml.info')}</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="mb-3">{t('config_yaml.label')}</div>
|
||||
)}
|
||||
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<Progress step={3} />
|
||||
<Button onClick={nextCallback}>{t('next')}</Button>
|
||||
|
|
|
@ -3,8 +3,13 @@ import { Container, Row, Col, Card, Alert } from 'react-bootstrap';
|
|||
import { useTranslation, Trans } from 'react-i18next';
|
||||
|
||||
import type { FormDataType } from '@/common/interface';
|
||||
import { Storage } from '@/utils';
|
||||
import { PageTitle } from '@/components';
|
||||
import {
|
||||
dbCheck,
|
||||
installInit,
|
||||
installBaseInfo,
|
||||
checkConfigFileExists,
|
||||
} from '@/services';
|
||||
|
||||
import {
|
||||
FirstStep,
|
||||
|
@ -17,7 +22,11 @@ import {
|
|||
const Index: FC = () => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
||||
const [step, setStep] = useState(1);
|
||||
const [showError] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [errorData, setErrorData] = useState<{ [propName: string]: any }>({
|
||||
msg: '',
|
||||
});
|
||||
const [tableExist, setTableExist] = useState(false);
|
||||
|
||||
const [formData, setFormData] = useState<FormDataType>({
|
||||
lang: {
|
||||
|
@ -26,7 +35,7 @@ const Index: FC = () => {
|
|||
errorMsg: '',
|
||||
},
|
||||
db_type: {
|
||||
value: '',
|
||||
value: 'mysql',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
|
@ -55,12 +64,16 @@ const Index: FC = () => {
|
|||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
|
||||
site_name: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
site_url: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
contact_email: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
|
@ -88,33 +101,107 @@ const Index: FC = () => {
|
|||
setFormData({ ...formData, ...params });
|
||||
};
|
||||
|
||||
const handleStep = () => {
|
||||
const handleErr = (data) => {
|
||||
window.scrollTo(0, 0);
|
||||
setErrorData(data);
|
||||
};
|
||||
|
||||
const handleNext = async () => {
|
||||
setErrorData({
|
||||
msg: '',
|
||||
});
|
||||
setStep((pre) => pre + 1);
|
||||
};
|
||||
|
||||
// const handleSubmit = () => {
|
||||
// const params = {
|
||||
// lang: formData.lang.value,
|
||||
// db_type: formData.db_type.value,
|
||||
// db_username: formData.db_username.value,
|
||||
// db_password: formData.db_password.value,
|
||||
// db_host: formData.db_host.value,
|
||||
// db_name: formData.db_name.value,
|
||||
// db_file: formData.db_file.value,
|
||||
// site_name: formData.site_name.value,
|
||||
// contact_email: formData.contact_email.value,
|
||||
// admin_name: formData.admin_name.value,
|
||||
// admin_password: formData.admin_password.value,
|
||||
// admin_email: formData.admin_email.value,
|
||||
// };
|
||||
const submitDatabaseForm = () => {
|
||||
const params = {
|
||||
lang: formData.lang.value,
|
||||
db_type: formData.db_type.value,
|
||||
db_username: formData.db_username.value,
|
||||
db_password: formData.db_password.value,
|
||||
db_host: formData.db_host.value,
|
||||
db_name: formData.db_name.value,
|
||||
db_file: formData.db_file.value,
|
||||
};
|
||||
dbCheck(params)
|
||||
.then(() => {
|
||||
handleNext();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
handleErr(err);
|
||||
});
|
||||
};
|
||||
|
||||
// console.log(params);
|
||||
// };
|
||||
const checkInstall = () => {
|
||||
installInit()
|
||||
.then(() => {
|
||||
handleNext();
|
||||
})
|
||||
.catch((err) => {
|
||||
handleErr(err);
|
||||
});
|
||||
};
|
||||
|
||||
const submitSiteConfig = () => {
|
||||
const params = {
|
||||
site_name: formData.site_name.value,
|
||||
contact_email: formData.contact_email.value,
|
||||
admin_name: formData.admin_name.value,
|
||||
admin_password: formData.admin_password.value,
|
||||
admin_email: formData.admin_email.value,
|
||||
};
|
||||
installBaseInfo(params)
|
||||
.then(() => {
|
||||
handleNext();
|
||||
})
|
||||
.catch((err) => {
|
||||
handleErr(err);
|
||||
});
|
||||
};
|
||||
|
||||
const handleStep = () => {
|
||||
if (step === 2) {
|
||||
submitDatabaseForm();
|
||||
} else if (step === 3) {
|
||||
checkInstall();
|
||||
} else if (step === 4) {
|
||||
submitSiteConfig();
|
||||
} else {
|
||||
handleNext();
|
||||
}
|
||||
};
|
||||
|
||||
const handleInstallNow = (e) => {
|
||||
e.preventDefault();
|
||||
if (tableExist) {
|
||||
setStep(7);
|
||||
} else {
|
||||
setStep(4);
|
||||
}
|
||||
};
|
||||
|
||||
const configYmlCheck = () => {
|
||||
checkConfigFileExists()
|
||||
.then((res) => {
|
||||
setTableExist(res?.db_table_exist);
|
||||
if (res && res.config_file_exist) {
|
||||
setStep(5);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log('step===', Storage.get('INSTALL_STEP'));
|
||||
configYmlCheck();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="page-wrap2">
|
||||
<PageTitle title={t('install', { keyPrefix: 'page_title' })} />
|
||||
|
@ -124,7 +211,9 @@ const Index: FC = () => {
|
|||
<h2 className="mb-4 text-center">{t('title')}</h2>
|
||||
<Card>
|
||||
<Card.Body>
|
||||
{showError && <Alert variant="danger"> show error msg </Alert>}
|
||||
{errorData?.msg && (
|
||||
<Alert variant="danger">{errorData?.msg}</Alert>
|
||||
)}
|
||||
|
||||
<FirstStep
|
||||
visible={step === 1}
|
||||
|
@ -140,7 +229,11 @@ const Index: FC = () => {
|
|||
nextCallback={handleStep}
|
||||
/>
|
||||
|
||||
<ThirdStep visible={step === 3} nextCallback={handleStep} />
|
||||
<ThirdStep
|
||||
visible={step === 3}
|
||||
nextCallback={handleStep}
|
||||
errorMsg={errorData}
|
||||
/>
|
||||
|
||||
<FourthStep
|
||||
visible={step === 4}
|
||||
|
@ -149,7 +242,7 @@ const Index: FC = () => {
|
|||
nextCallback={handleStep}
|
||||
/>
|
||||
|
||||
<Fifth visible={step === 5} />
|
||||
<Fifth visible={step === 5} siteUrl={formData.site_url.value} />
|
||||
{step === 6 && (
|
||||
<div>
|
||||
<h5>{t('warning')}</h5>
|
||||
|
@ -158,7 +251,10 @@ const Index: FC = () => {
|
|||
The file <code>config.yaml</code> already exists. If you
|
||||
need to reset any of the configuration items in this
|
||||
file, please delete it first. You may try{' '}
|
||||
<a href="/">installing now</a>.
|
||||
<a href="###" onClick={(e) => handleInstallNow(e)}>
|
||||
installing now
|
||||
</a>
|
||||
.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
import { useState } from 'react';
|
||||
import { Container, Row, Col, Card, Button } from 'react-bootstrap';
|
||||
import { Container, Row, Col, Card, Button, Spinner } from 'react-bootstrap';
|
||||
import { useTranslation, Trans } from 'react-i18next';
|
||||
|
||||
import { PageTitle } from '@/components';
|
||||
import { upgradSystem } from '@/services';
|
||||
|
||||
const Index = () => {
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'upgrade',
|
||||
});
|
||||
const [step, setStep] = useState(1);
|
||||
const [step] = useState(1);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleUpdate = () => {
|
||||
setStep(2);
|
||||
const handleUpdate = async () => {
|
||||
await upgradSystem();
|
||||
setLoading(true);
|
||||
};
|
||||
return (
|
||||
<div className="page-wrap2">
|
||||
|
@ -29,9 +32,22 @@ const Index = () => {
|
|||
i18nKey="upgrade.update_description"
|
||||
components={{ 1: <p /> }}
|
||||
/>
|
||||
<Button className="float-end" onClick={handleUpdate}>
|
||||
{t('update_btn')}
|
||||
</Button>
|
||||
{loading ? (
|
||||
<Button variant="primary" disabled className="float-end">
|
||||
<Spinner
|
||||
as="span"
|
||||
animation="border"
|
||||
size="sm"
|
||||
role="status"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span> {t('update_btn')}</span>
|
||||
</Button>
|
||||
) : (
|
||||
<Button className="float-end" onClick={handleUpdate}>
|
||||
{t('update_btn')}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
|
@ -39,7 +55,9 @@ const Index = () => {
|
|||
<>
|
||||
<h5>{t('done_title')}</h5>
|
||||
<p>{t('done_desscription')}</p>
|
||||
<Button className="float-end">{t('done_btn')}</Button>
|
||||
<Button className="float-end" href="/">
|
||||
{t('done_btn')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</Card.Body>
|
||||
|
|
|
@ -248,3 +248,7 @@ export const changeEmailVerify = (params: { code: string }) => {
|
|||
export const getAppSettings = () => {
|
||||
return request.get<Type.SiteSettings>('/answer/api/v1/siteinfo');
|
||||
};
|
||||
|
||||
export const upgradSystem = () => {
|
||||
return request.post('/answer/api/v1/upgradation');
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './admin';
|
||||
export * from './common';
|
||||
export * from './client';
|
||||
export * from './install';
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import request from '@/utils/request';
|
||||
|
||||
export const checkConfigFileExists = () => {
|
||||
return request.post('/installation/config-file/check');
|
||||
};
|
||||
|
||||
export const dbCheck = (params) => {
|
||||
return request.post('/installation/db/check', params);
|
||||
};
|
||||
|
||||
export const installInit = () => {
|
||||
return request.post('/installation/init');
|
||||
};
|
||||
|
||||
export const installBaseInfo = (params) => {
|
||||
return request.post('/installation/base-info', params);
|
||||
};
|
||||
|
||||
export const getInstallLangOptions = () => {
|
||||
return request.get('/installation/language/options');
|
||||
};
|
|
@ -73,7 +73,14 @@ class Request {
|
|||
});
|
||||
}
|
||||
|
||||
if (data.type === 'modal') {
|
||||
if (data.err_type === 'alert') {
|
||||
return Promise.reject({
|
||||
msg,
|
||||
...data,
|
||||
});
|
||||
}
|
||||
|
||||
if (data.err_type === 'modal') {
|
||||
// modal error message
|
||||
Modal.confirm({
|
||||
content: msg,
|
||||
|
|
Loading…
Reference in New Issue