mirror of https://gitee.com/answerdev/answer.git
Merge branch 'feat/ui-0.7.0' of git.backyard.segmentfault.com:opensource/answer into feat/ui-0.7.0
This commit is contained in:
commit
56bb48b80b
|
@ -1094,6 +1094,8 @@ ui:
|
||||||
fields:
|
fields:
|
||||||
password:
|
password:
|
||||||
label: Password
|
label: Password
|
||||||
|
text: The user will be logged out and need to login again.
|
||||||
|
msg: Password must be at 8 - 32 characters in length.
|
||||||
btn_cancel: Cancel
|
btn_cancel: Cancel
|
||||||
btn_submit: Submit
|
btn_submit: Submit
|
||||||
user_modal:
|
user_modal:
|
||||||
|
@ -1102,11 +1104,14 @@ ui:
|
||||||
fields:
|
fields:
|
||||||
display_name:
|
display_name:
|
||||||
label: Display Name
|
label: Display Name
|
||||||
|
msg: display_name must be at maximum 30 characters in length.
|
||||||
email:
|
email:
|
||||||
label: Email
|
label: Email
|
||||||
msg: Email is not valid.
|
msg: Email is not valid.
|
||||||
password:
|
password:
|
||||||
label: Password
|
label: Password
|
||||||
|
msg: Password must be at 8 - 32 characters in length.
|
||||||
|
|
||||||
btn_cancel: Cancel
|
btn_cancel: Cancel
|
||||||
btn_submit: Submit
|
btn_submit: Submit
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ const Index: FC = () => {
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="text-muted">{t('follow_tag_tip')}</div>
|
<div className="text-muted">{t('follow_tag_tip')}</div>
|
||||||
<NavLink className="d-inline-block my-2" to="/tags">
|
<NavLink className="d-inline-block mt-3" to="/tags">
|
||||||
<Button size="sm" variant="outline-primary">
|
<Button size="sm" variant="outline-primary">
|
||||||
{t('follow_a_tag')}
|
{t('follow_a_tag')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -129,7 +129,7 @@ const QuestionList: FC<Props> = ({ source }) => {
|
||||||
{li.status === 2 ? ` [${t('closed')}]` : ''}
|
{li.status === 2 ? ` [${t('closed')}]` : ''}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</h5>
|
</h5>
|
||||||
<div className="d-flex flex-column flex-md-row align-items-md-center fs-14 mb-3 text-secondary">
|
<div className="d-flex flex-column flex-md-row align-items-md-center fs-14 mb-2 text-secondary">
|
||||||
<QuestionLastUpdate q={li} />
|
<QuestionLastUpdate q={li} />
|
||||||
<div className="ms-0 ms-md-3 mt-2 mt-md-0">
|
<div className="ms-0 ms-md-3 mt-2 mt-md-0">
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -6,13 +6,14 @@ import ReactDOM from 'react-dom/client';
|
||||||
|
|
||||||
import type * as Type from '@/common/interface';
|
import type * as Type from '@/common/interface';
|
||||||
import { SchemaForm, JSONSchema, UISchema, initFormData } from '@/components';
|
import { SchemaForm, JSONSchema, UISchema, initFormData } from '@/components';
|
||||||
|
import { handleFormError } from '@/utils';
|
||||||
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
const root = ReactDOM.createRoot(div);
|
const root = ReactDOM.createRoot(div);
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
onConfirm?: (formData: any) => void;
|
onConfirm?: (formData: any) => Promise<any>;
|
||||||
}
|
}
|
||||||
const useChangePasswordModal = (props: IProps = {}) => {
|
const useChangePasswordModal = (props: IProps = {}) => {
|
||||||
const { t } = useTranslation('translation', {
|
const { t } = useTranslation('translation', {
|
||||||
|
@ -29,6 +30,7 @@ const useChangePasswordModal = (props: IProps = {}) => {
|
||||||
password: {
|
password: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
title: t('form.fields.password.label'),
|
title: t('form.fields.password.label'),
|
||||||
|
description: t('form.fields.password.text'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -36,6 +38,14 @@ const useChangePasswordModal = (props: IProps = {}) => {
|
||||||
password: {
|
password: {
|
||||||
'ui:options': {
|
'ui:options': {
|
||||||
type: 'password',
|
type: 'password',
|
||||||
|
validator: (value) => {
|
||||||
|
const MIN_LENGTH = 8;
|
||||||
|
const MAX_LENGTH = 32;
|
||||||
|
if (value.length < MIN_LENGTH || value.length > MAX_LENGTH) {
|
||||||
|
return t('form.fields.password.msg');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -69,7 +79,8 @@ const useChangePasswordModal = (props: IProps = {}) => {
|
||||||
onConfirm({
|
onConfirm({
|
||||||
password: formData.password.value,
|
password: formData.password.value,
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
});
|
})
|
||||||
|
.then(() => {
|
||||||
setFormData({
|
setFormData({
|
||||||
password: {
|
password: {
|
||||||
value: '',
|
value: '',
|
||||||
|
@ -78,8 +89,15 @@ const useChangePasswordModal = (props: IProps = {}) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
setUserId('');
|
setUserId('');
|
||||||
}
|
|
||||||
onClose();
|
onClose();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err.isError) {
|
||||||
|
const data = handleFormError(err, formData);
|
||||||
|
setFormData({ ...data });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnChange = (data) => {
|
const handleOnChange = (data) => {
|
||||||
|
|
|
@ -7,13 +7,14 @@ import ReactDOM from 'react-dom/client';
|
||||||
import pattern from '@/common/pattern';
|
import pattern from '@/common/pattern';
|
||||||
import type * as Type from '@/common/interface';
|
import type * as Type from '@/common/interface';
|
||||||
import { SchemaForm, JSONSchema, UISchema, initFormData } from '@/components';
|
import { SchemaForm, JSONSchema, UISchema, initFormData } from '@/components';
|
||||||
|
import { handleFormError } from '@/utils';
|
||||||
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
const root = ReactDOM.createRoot(div);
|
const root = ReactDOM.createRoot(div);
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
onConfirm?: (formData: any) => void;
|
onConfirm?: (formData: any) => Promise<any>;
|
||||||
}
|
}
|
||||||
const useAddUserModal = (props: IProps = {}) => {
|
const useAddUserModal = (props: IProps = {}) => {
|
||||||
const { t } = useTranslation('translation', {
|
const { t } = useTranslation('translation', {
|
||||||
|
@ -41,6 +42,16 @@ const useAddUserModal = (props: IProps = {}) => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const uiSchema: UISchema = {
|
const uiSchema: UISchema = {
|
||||||
|
display_name: {
|
||||||
|
'ui:options': {
|
||||||
|
validator: (value) => {
|
||||||
|
if (value.length > 30) {
|
||||||
|
return t('form.fields.display_name.msg');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
email: {
|
email: {
|
||||||
'ui:options': {
|
'ui:options': {
|
||||||
type: 'email',
|
type: 'email',
|
||||||
|
@ -55,6 +66,14 @@ const useAddUserModal = (props: IProps = {}) => {
|
||||||
password: {
|
password: {
|
||||||
'ui:options': {
|
'ui:options': {
|
||||||
type: 'password',
|
type: 'password',
|
||||||
|
validator: (value) => {
|
||||||
|
const MIN_LENGTH = 8;
|
||||||
|
const MAX_LENGTH = 32;
|
||||||
|
if (value.length < MIN_LENGTH || value.length > MAX_LENGTH) {
|
||||||
|
return t('form.fields.password.msg');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -88,7 +107,8 @@ const useAddUserModal = (props: IProps = {}) => {
|
||||||
display_name: formData.display_name.value,
|
display_name: formData.display_name.value,
|
||||||
email: formData.email.value,
|
email: formData.email.value,
|
||||||
password: formData.password.value,
|
password: formData.password.value,
|
||||||
});
|
})
|
||||||
|
.then(() => {
|
||||||
setFormData({
|
setFormData({
|
||||||
display_name: {
|
display_name: {
|
||||||
value: '',
|
value: '',
|
||||||
|
@ -106,8 +126,15 @@ const useAddUserModal = (props: IProps = {}) => {
|
||||||
errorMsg: '',
|
errorMsg: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
onClose();
|
onClose();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err.isError) {
|
||||||
|
const data = handleFormError(err, formData);
|
||||||
|
setFormData({ ...data });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnChange = (data) => {
|
const handleOnChange = (data) => {
|
||||||
|
|
|
@ -74,20 +74,34 @@ const Users: FC = () => {
|
||||||
|
|
||||||
const userModal = useUserModal({
|
const userModal = useUserModal({
|
||||||
onConfirm: (userModel) => {
|
onConfirm: (userModel) => {
|
||||||
addUser(userModel).then(() => {
|
return new Promise((resolve, reject) => {
|
||||||
|
addUser(userModel)
|
||||||
|
.then(() => {
|
||||||
if (/all|staff/.test(curFilter) && curPage === 1) {
|
if (/all|staff/.test(curFilter) && curPage === 1) {
|
||||||
refreshUsers();
|
refreshUsers();
|
||||||
}
|
}
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const changePasswordModal = useChangePasswordModal({
|
const changePasswordModal = useChangePasswordModal({
|
||||||
onConfirm: (rd) => {
|
onConfirm: (rd) => {
|
||||||
updateUserPassword(rd).then(() => {
|
return new Promise((resolve, reject) => {
|
||||||
|
updateUserPassword(rd)
|
||||||
|
.then(() => {
|
||||||
Toast.onShow({
|
Toast.onShow({
|
||||||
msg: t('update_password', { keyPrefix: 'toast' }),
|
msg: t('update_password', { keyPrefix: 'toast' }),
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
});
|
});
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -108,7 +108,7 @@ const Index: FC = () => {
|
||||||
<Form.Control
|
<Form.Control
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
required
|
required
|
||||||
type="text"
|
type="email"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
value={formData.e_mail.value}
|
value={formData.e_mail.value}
|
||||||
isInvalid={formData.e_mail.isInvalid}
|
isInvalid={formData.e_mail.isInvalid}
|
||||||
|
|
Loading…
Reference in New Issue