feat(admin/users): add new user and change user password done

This commit is contained in:
haitao(lj) 2022-12-10 16:37:18 +08:00
parent 481d16ba16
commit 79f25466ca
5 changed files with 66 additions and 39 deletions

View File

@ -705,7 +705,7 @@ ui:
update: update success update: update success
update_password: Password changed successfully. update_password: Password changed successfully.
flag_success: Thanks for flagging. flag_success: Thanks for flagging.
fobidden_operate_self: Forbidden to operate on yourself forbidden_operate_self: Forbidden to operate on yourself
review: Your revision will show after review. review: Your revision will show after review.
related_question: related_question:
title: Related Questions title: Related Questions

View File

@ -21,18 +21,19 @@ const useChangePasswordModal = (props: IProps = {}) => {
const { title = t('title'), onConfirm } = props; const { title = t('title'), onConfirm } = props;
const [visible, setVisibleState] = useState(false); const [visible, setVisibleState] = useState(false);
const [userId, setUserId] = useState('');
const schema: JSONSchema = { const schema: JSONSchema = {
title: t('title'), title: t('title'),
required: ['password'], required: ['password'],
properties: { properties: {
new_password: { password: {
type: 'string', type: 'string',
title: t('form.fields.password.label'), title: t('form.fields.password.label'),
}, },
}, },
}; };
const uiSchema: UISchema = { const uiSchema: UISchema = {
new_password: { password: {
'ui:options': { 'ui:options': {
type: 'password', type: 'password',
}, },
@ -50,7 +51,8 @@ const useChangePasswordModal = (props: IProps = {}) => {
setVisibleState(false); setVisibleState(false);
}; };
const onShow = () => { const onShow = (user_id: string) => {
setUserId(user_id);
setVisibleState(true); setVisibleState(true);
}; };
@ -65,27 +67,17 @@ const useChangePasswordModal = (props: IProps = {}) => {
if (onConfirm instanceof Function) { if (onConfirm instanceof Function) {
onConfirm({ onConfirm({
slug_name: formData.slugName.value, password: formData.password.value,
display_name: formData.displayName.value, user_id: userId,
original_text: formData.description.value,
}); });
setFormData({ setFormData({
displayName: { password: {
value: '',
isInvalid: false,
errorMsg: '',
},
slugName: {
value: '',
isInvalid: false,
errorMsg: '',
},
description: {
value: '', value: '',
isInvalid: false, isInvalid: false,
errorMsg: '', errorMsg: '',
}, },
}); });
setUserId('');
} }
onClose(); onClose();
}; };

View File

@ -85,22 +85,22 @@ const useAddUserModal = (props: IProps = {}) => {
if (onConfirm instanceof Function) { if (onConfirm instanceof Function) {
onConfirm({ onConfirm({
slug_name: formData.slugName.value, display_name: formData.display_name.value,
display_name: formData.displayName.value, email: formData.email.value,
original_text: formData.description.value, password: formData.password.value,
}); });
setFormData({ setFormData({
displayName: { display_name: {
value: '', value: '',
isInvalid: false, isInvalid: false,
errorMsg: '', errorMsg: '',
}, },
slugName: { email: {
value: '', value: '',
isInvalid: false, isInvalid: false,
errorMsg: '', errorMsg: '',
}, },
description: { password: {
value: '', value: '',
isInvalid: false, isInvalid: false,
errorMsg: '', errorMsg: '',

View File

@ -1,5 +1,5 @@
import { FC } from 'react'; import { FC } from 'react';
import { Form, Table, Dropdown, Button } from 'react-bootstrap'; import { Form, Table, Dropdown, Button, Stack } from 'react-bootstrap';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -21,7 +21,7 @@ import {
useChangePasswordModal, useChangePasswordModal,
useToast, useToast,
} from '@/hooks'; } from '@/hooks';
import { useQueryUsers } from '@/services'; import { useQueryUsers, addUser, updateUserPassword } from '@/services';
import { loggedUserInfoStore } from '@/stores'; import { loggedUserInfoStore } from '@/stores';
import { formatCount } from '@/utils'; import { formatCount } from '@/utils';
@ -50,8 +50,6 @@ const Users: FC = () => {
const curQuery = urlSearchParams.get('query') || ''; const curQuery = urlSearchParams.get('query') || '';
const currentUser = loggedUserInfoStore((state) => state.user); const currentUser = loggedUserInfoStore((state) => state.user);
const Toast = useToast(); const Toast = useToast();
const userModal = useUserModal();
const changePasswordModal = useChangePasswordModal();
const { const {
data, data,
isLoading, isLoading,
@ -74,11 +72,31 @@ const Users: FC = () => {
callback: refreshUsers, callback: refreshUsers,
}); });
const userModal = useUserModal({
onConfirm: (userModel) => {
addUser(userModel).then(() => {
if (/all|staff/.test(curFilter) && curPage === 1) {
refreshUsers();
}
});
},
});
const changePasswordModal = useChangePasswordModal({
onConfirm: (rd) => {
updateUserPassword(rd).then(() => {
Toast.onShow({
msg: t('update_password', { keyPrefix: 'toast' }),
variant: 'success',
});
});
},
});
const handleAction = (type, user) => { const handleAction = (type, user) => {
const { user_id, status, role_id, username } = user; const { user_id, status, role_id, username } = user;
if (username === currentUser.username) { if (username === currentUser.username) {
Toast.onShow({ Toast.onShow({
msg: t('fobidden_operate_self', { keyPrefix: 'toast' }), msg: t('forbidden_operate_self', { keyPrefix: 'toast' }),
variant: 'warning', variant: 'warning',
}); });
return; return;
@ -96,6 +114,9 @@ const Users: FC = () => {
role_id, role_id,
}); });
} }
if (type === 'password') {
changePasswordModal.onShow(user_id);
}
}; };
const handleFilter = (e) => { const handleFilter = (e) => {
@ -107,21 +128,20 @@ const Users: FC = () => {
<> <>
<h3 className="mb-4">{t('title')}</h3> <h3 className="mb-4">{t('title')}</h3>
<div className="d-flex justify-content-between align-items-center mb-3"> <div className="d-flex justify-content-between align-items-center mb-3">
<div> <Stack direction="horizontal" gap={3}>
<Button
className="me-3"
variant="outline-primary"
size="sm"
onClick={() => userModal.onShow()}>
{t('add_user')}
</Button>
<QueryGroup <QueryGroup
data={UserFilterKeys} data={UserFilterKeys}
currentSort={curFilter} currentSort={curFilter}
sortKey="filter" sortKey="filter"
i18nKeyPrefix="admin.users" i18nKeyPrefix="admin.users"
/> />
</div> <Button
variant="outline-primary"
size="sm"
onClick={() => userModal.onShow()}>
{t('add_user')}
</Button>
</Stack>
<Form.Control <Form.Control
size="sm" size="sm"
@ -206,7 +226,7 @@ const Users: FC = () => {
</Dropdown.Toggle> </Dropdown.Toggle>
<Dropdown.Menu> <Dropdown.Menu>
<Dropdown.Item <Dropdown.Item
onClick={() => changePasswordModal.onShow()}> onClick={() => handleAction('password', user)}>
{t('set_new_password')} {t('set_new_password')}
</Dropdown.Item> </Dropdown.Item>
<Dropdown.Item <Dropdown.Item

View File

@ -29,3 +29,18 @@ export const getUserRoles = () => {
export const changeUserRole = (params) => { export const changeUserRole = (params) => {
return request.put('/answer/admin/api/user/role', params); return request.put('/answer/admin/api/user/role', params);
}; };
export const addUser = (params: {
display_name: string;
email: string;
password: string;
}) => {
return request.post('/answer/admin/api/user', params);
};
export const updateUserPassword = (params: {
password: string;
user_id: string;
}) => {
return request.put('/answer/admin/api/user/password', params);
};