feat: cannot change current logged user status and role

This commit is contained in:
shuai 2022-11-30 17:17:58 +08:00
parent fa7ade2a24
commit 9884a1d23f
5 changed files with 102 additions and 124 deletions

View File

@ -678,6 +678,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
related_question: related_question:
title: Related Questions title: Related Questions
btn: Add question btn: Add question
@ -1022,15 +1023,6 @@ ui:
title: Change user role to... title: Change user role to...
btn_cancel: Cancel btn_cancel: Cancel
btn_submit: Submit btn_submit: Submit
user:
name: User
description: Default with no special access.
admin:
name: Admin
description: Have the full power to access the site.
moderator:
name: Moderator
description: Has access to all posts except admin settings.
users: users:
title: Users title: Users
name: Name name: Name
@ -1049,6 +1041,9 @@ ui:
suspended: Suspended suspended: Suspended
deleted: Deleted deleted: Deleted
normal: Normal normal: Normal
Moderator: Moderator
Admin: Admin
User: User
filter: filter:
placeholder: "Filter by name, user:id" placeholder: "Filter by name, user:id"
set_new_password: Set new password set_new_password: Set new password

View File

@ -444,3 +444,9 @@ export interface ReviewResp {
count: number; count: number;
list: ReviewItem[]; list: ReviewItem[];
} }
export interface UserRoleItem {
id: number;
name: string;
description: string;
}

View File

@ -4,8 +4,9 @@ import { useTranslation } from 'react-i18next';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import { Modal as AnswerModal } from '@/components'; // import { Modal as AnswerModal } from '@/components';
import { changeUserStatus } from '@/services'; import { getUserRoles, changeUserRole } from '@/services';
import { UserRoleItem } from '@/common/interface';
const div = document.createElement('div'); const div = document.createElement('div');
const root = ReactDOM.createRoot(div); const root = ReactDOM.createRoot(div);
@ -19,108 +20,57 @@ const useChangeUserRoleModal = ({ callback }: Props) => {
keyPrefix: 'admin.user_role_modal', keyPrefix: 'admin.user_role_modal',
}); });
const [id, setId] = useState(''); const [id, setId] = useState('');
const [defaultType, setDefaultType] = useState(''); const [defaultId, setDefaultId] = useState(-1);
const [isInvalid, setInvalidState] = useState(false); const [isInvalid, setInvalidState] = useState(false);
const [changeType, setChangeType] = useState({ const [changedId, setChangeId] = useState(-1);
type: '',
haveContent: false,
});
const [content, setContent] = useState({
value: '',
isInvalid: false,
errorMsg: '',
});
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const [list] = useState<any[]>([ const [list, setList] = useState<UserRoleItem[]>([]);
{
type: 'user', const getRolesData = async () => {
name: t('user.name'), const res = await getUserRoles();
description: t('user.description'), setList(res);
}, };
{
type: 'admin',
name: t('admin.name'),
description: t('admin.description'),
},
{
type: 'moderator',
name: t('moderator.name'),
description: t('moderator.description'),
},
]);
const handleRadio = (val) => { const handleRadio = (val) => {
setInvalidState(false); setInvalidState(false);
setContent({ setChangeId(val.id);
value: '',
isInvalid: false,
errorMsg: '',
});
setChangeType({
type: val.type,
haveContent: val.have_content,
});
}; };
const onClose = () => { const onClose = () => {
setChangeType({ setChangeId(-1);
type: '', setDefaultId(-1);
haveContent: false,
});
setContent({
value: '',
isInvalid: false,
errorMsg: '',
});
setContent({
value: '',
isInvalid: false,
errorMsg: '',
});
setShow(false); setShow(false);
}; };
const handleSubmit = () => { const handleSubmit = () => {
if (changeType.type === '') { if (defaultId === changedId) {
setInvalidState(true);
return;
}
if (changeType.haveContent && !content.value) {
setContent({
value: content.value,
isInvalid: true,
errorMsg: t('remark.empty'),
});
return;
}
if (defaultType === changeType.type) {
onClose(); onClose();
return; return;
} }
if (changeType.type === 'deleted') { // if (changeType.type === 'deleted') {
onClose(); // onClose();
AnswerModal.confirm({ // AnswerModal.confirm({
title: t('confirm_title'), // title: t('confirm_title'),
content: t('confirm_content'), // content: t('confirm_content'),
confirmText: t('confirm_btn'), // confirmText: t('confirm_btn'),
confirmBtnVariant: 'danger', // confirmBtnVariant: 'danger',
onConfirm: () => { // onConfirm: () => {
changeUserStatus({ // changeUserStatus({
user_id: id, // user_id: id,
status: changeType.type, // status: changeType.type,
}).then(() => { // }).then(() => {
callback?.(); // callback?.();
onClose(); // onClose();
}); // });
}, // },
}); // });
return; // return;
} // }
changeUserStatus({ changeUserRole({
user_id: id, user_id: id,
status: changeType.type, role_id: changedId,
}).then(() => { }).then(() => {
callback?.(); callback?.();
onClose(); onClose();
@ -128,12 +78,10 @@ const useChangeUserRoleModal = ({ callback }: Props) => {
}; };
const onShow = (params) => { const onShow = (params) => {
getRolesData();
setId(params.id); setId(params.id);
setChangeType({ setChangeId(params.role_id);
...changeType, setDefaultId(params.role_id);
type: params.type,
});
setDefaultType(params.type);
setShow(true); setShow(true);
}; };
useLayoutEffect(() => { useLayoutEffect(() => {
@ -146,17 +94,17 @@ const useChangeUserRoleModal = ({ callback }: Props) => {
<Form> <Form>
{list.map((item) => { {list.map((item) => {
return ( return (
<div key={item?.type}> <div key={item?.id}>
<Form.Group controlId={item.type} className="mb-3"> <Form.Group controlId={item.name} className="mb-3">
<FormCheck> <FormCheck>
<FormCheck.Input <FormCheck.Input
id={item.type} id={item.name}
type="radio" type="radio"
checked={changeType.type === item.type} checked={changedId === item.id}
onChange={() => handleRadio(item)} onChange={() => handleRadio(item)}
isInvalid={isInvalid} isInvalid={isInvalid}
/> />
<FormCheck.Label htmlFor={item.type}> <FormCheck.Label htmlFor={item.name}>
<span className="fw-bold">{item.name}</span> <span className="fw-bold">{item.name}</span>
<br /> <br />
<span className="text-secondary"> <span className="text-secondary">

View File

@ -14,8 +14,9 @@ import {
Icon, Icon,
} from '@/components'; } from '@/components';
import * as Type from '@/common/interface'; import * as Type from '@/common/interface';
import { useChangeModal, useChangeUserRoleModal } from '@/hooks'; import { useChangeModal, useChangeUserRoleModal, useToast } from '@/hooks';
import { useQueryUsers } from '@/services'; import { useQueryUsers } from '@/services';
import { loggedUserInfoStore } from '@/stores';
import '../index.scss'; import '../index.scss';
@ -42,6 +43,8 @@ const Users: FC = () => {
const curFilter = urlSearchParams.get('filter') || UserFilterKeys[0]; const curFilter = urlSearchParams.get('filter') || UserFilterKeys[0];
const curPage = Number(urlSearchParams.get('page') || '1'); const curPage = Number(urlSearchParams.get('page') || '1');
const curQuery = urlSearchParams.get('query') || ''; const curQuery = urlSearchParams.get('query') || '';
const currentUser = loggedUserInfoStore((state) => state.user);
const Toast = useToast();
const { const {
data, data,
isLoading, isLoading,
@ -50,7 +53,11 @@ const Users: FC = () => {
page: curPage, page: curPage,
page_size: PAGE_SIZE, page_size: PAGE_SIZE,
query: curQuery, query: curQuery,
...(curFilter === 'all' ? {} : { status: curFilter }), ...(curFilter === 'all'
? {}
: curFilter === 'staff'
? { staff: true }
: { status: curFilter }),
}); });
const changeModal = useChangeModal({ const changeModal = useChangeModal({
callback: refreshUsers, callback: refreshUsers,
@ -60,18 +67,28 @@ const Users: FC = () => {
callback: refreshUsers, callback: refreshUsers,
}); });
const handleClick = ({ user_id, status }) => { const handleAction = (type, user) => {
changeModal.onShow({ const { user_id, status, role_id, username } = user;
id: user_id, if (username === currentUser.username) {
type: status, Toast.onShow({
}); msg: t('fobidden_operate_self', { keyPrefix: 'toast' }),
}; variant: 'warning',
});
return;
}
if (type === 'status') {
changeModal.onShow({
id: user_id,
type: status,
});
}
const handleClickRole = ({ user_id, role }) => { if (type === 'role') {
changeUserRoleModal.onShow({ changeUserRoleModal.onShow({
id: user_id, id: user_id,
role, role_id,
}); });
}
}; };
const handleFilter = (e) => { const handleFilter = (e) => {
@ -157,7 +174,9 @@ const Users: FC = () => {
</span> </span>
</td> </td>
<td> <td>
<span className="text-bg-light">Admin</span> <span className="badge text-bg-light">
{t(user.role_name)}
</span>
</td> </td>
{curFilter !== 'deleted' ? ( {curFilter !== 'deleted' ? (
<td className="text-end"> <td className="text-end">
@ -166,15 +185,17 @@ const Users: FC = () => {
<Icon name="three-dots-vertical" /> <Icon name="three-dots-vertical" />
</Dropdown.Toggle> </Dropdown.Toggle>
<Dropdown.Menu> <Dropdown.Menu>
<Dropdown.Item>{t('set_new_password')}</Dropdown.Item> {/* <Dropdown.Item>{t('set_new_password')}</Dropdown.Item> */}
<Dropdown.Item onClick={() => handleClick(user)}> <Dropdown.Item
onClick={() => handleAction('status', user)}>
{t('change_status')} {t('change_status')}
</Dropdown.Item> </Dropdown.Item>
<Dropdown.Item onClick={() => handleClickRole(user)}> <Dropdown.Item
onClick={() => handleAction('role', user)}>
{t('change_role')} {t('change_role')}
</Dropdown.Item> </Dropdown.Item>
<Dropdown.Divider /> {/* <Dropdown.Divider />
<Dropdown.Item>{t('show_logs')}</Dropdown.Item> <Dropdown.Item>{t('show_logs')}</Dropdown.Item> */}
</Dropdown.Menu> </Dropdown.Menu>
</Dropdown> </Dropdown>

View File

@ -21,3 +21,11 @@ export const useQueryUsers = (params) => {
mutate, mutate,
}; };
}; };
export const getUserRoles = () => {
return request.get('/answer/admin/api/roles');
};
export const changeUserRole = (params) => {
return request.put('/answer/admin/api/user/role', params);
};