User.tsx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { useContext, useEffect, useState } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { UserService } from '@/http';
  4. import AttuGrid from '@/components/grid/Grid';
  5. import { ColDefinitionsType, ToolBarConfig } from '@/components/grid/Types';
  6. import {
  7. CreateUserParams,
  8. DeleteUserParams,
  9. UpdateUserRoleParams,
  10. } from './Types';
  11. import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
  12. import Wrapper from '@/components/layout/Wrapper';
  13. import { rootContext } from '@/context';
  14. import { useNavigationHook, usePaginationHook } from '@/hooks';
  15. import CreateUser from './dialogs/CreateUserDialog';
  16. import UpdateUserRole from './dialogs/UpdateUserRole';
  17. import UpdateUser from './dialogs/UpdateUserPassDialog';
  18. import { ALL_ROUTER_TYPES } from '@/router/consts';
  19. import type { UserWithRoles } from '@server/types';
  20. import { getLabelDisplayedRows } from '@/pages/search/Utils';
  21. const Users = () => {
  22. useNavigationHook(ALL_ROUTER_TYPES.USER);
  23. // ui states
  24. const [users, setUsers] = useState<UserWithRoles[]>([]);
  25. const [selectedUser, setSelectedUser] = useState<UserWithRoles[]>([]);
  26. const [loading, setLoading] = useState(true);
  27. const [hasPermission, setHasPermission] = useState(true);
  28. // context
  29. const { setDialog, handleCloseDialog, openSnackBar } =
  30. useContext(rootContext);
  31. // i18n
  32. const { t: successTrans } = useTranslation('success');
  33. const { t: userTrans } = useTranslation('user');
  34. const { t: btnTrans } = useTranslation('btn');
  35. const { t: dialogTrans } = useTranslation('dialog');
  36. const { t: commonTrans } = useTranslation();
  37. const fetchUsers = async () => {
  38. setLoading(true);
  39. try {
  40. const res = await UserService.getUsers();
  41. setUsers(res);
  42. } catch (error) {
  43. setHasPermission(false);
  44. } finally {
  45. setLoading(false);
  46. }
  47. };
  48. const {
  49. pageSize,
  50. handlePageSize,
  51. currentPage,
  52. handleCurrentPage,
  53. total,
  54. data: result,
  55. order,
  56. orderBy,
  57. handleGridSort,
  58. } = usePaginationHook(users || []);
  59. const handleCreate = async (data: CreateUserParams) => {
  60. const s: any = await UserService.createUser(data);
  61. // assign user role if
  62. await UserService.updateUserRole({
  63. username: data.username,
  64. roles: data.roles,
  65. });
  66. fetchUsers();
  67. openSnackBar(successTrans('create', { name: userTrans('user') }));
  68. handleCloseDialog();
  69. };
  70. const onUpdate = async (data: UpdateUserRoleParams) => {
  71. fetchUsers();
  72. openSnackBar(
  73. successTrans('update', { name: userTrans('updateRoleSuccess') })
  74. );
  75. handleCloseDialog();
  76. };
  77. const onUpdateUserPass = async (res: any) => {
  78. openSnackBar(successTrans('passwordChanged'));
  79. fetchUsers();
  80. handleCloseDialog();
  81. };
  82. const handleDelete = async () => {
  83. for (const user of selectedUser) {
  84. const param: DeleteUserParams = {
  85. username: user.username,
  86. };
  87. await UserService.deleteUser(param);
  88. }
  89. openSnackBar(successTrans('delete', { name: userTrans('user') }));
  90. fetchUsers();
  91. handleCloseDialog();
  92. };
  93. const toolbarConfigs: ToolBarConfig[] = [
  94. {
  95. label: userTrans('user'),
  96. onClick: async () => {
  97. const roles = await UserService.getRoles();
  98. setDialog({
  99. open: true,
  100. type: 'custom',
  101. params: {
  102. component: (
  103. <CreateUser
  104. handleCreate={handleCreate}
  105. handleClose={handleCloseDialog}
  106. roleOptions={roles.map(r => {
  107. return { label: r.roleName, value: r.roleName };
  108. })}
  109. />
  110. ),
  111. },
  112. });
  113. },
  114. icon: 'add',
  115. },
  116. {
  117. type: 'button',
  118. btnVariant: 'text',
  119. btnColor: 'secondary',
  120. label: userTrans('editPassword'),
  121. onClick: async () => {
  122. setDialog({
  123. open: true,
  124. type: 'custom',
  125. params: {
  126. component: (
  127. <UpdateUser
  128. username={selectedUser[0]!.username}
  129. onUpdate={onUpdateUserPass}
  130. handleClose={handleCloseDialog}
  131. />
  132. ),
  133. },
  134. });
  135. },
  136. icon: 'edit',
  137. disabled: () => selectedUser.length === 0 || selectedUser.length > 1,
  138. disabledTooltip: userTrans('editPassDisabledTip'),
  139. },
  140. {
  141. type: 'button',
  142. btnVariant: 'text',
  143. btnColor: 'secondary',
  144. label: userTrans('editRole'),
  145. onClick: async () => {
  146. setDialog({
  147. open: true,
  148. type: 'custom',
  149. params: {
  150. component: (
  151. <UpdateUserRole
  152. username={selectedUser[0]!.username}
  153. onUpdate={onUpdate}
  154. handleClose={handleCloseDialog}
  155. roles={
  156. users.filter(u => u.username === selectedUser[0].username)[0]
  157. .roles
  158. }
  159. />
  160. ),
  161. },
  162. });
  163. },
  164. icon: 'edit',
  165. disabled: () =>
  166. selectedUser.length === 0 ||
  167. selectedUser.length > 1 ||
  168. selectedUser.findIndex(v => v.username === 'root') > -1,
  169. disabledTooltip: userTrans('deleteEditRoleTip'),
  170. },
  171. {
  172. type: 'button',
  173. btnVariant: 'text',
  174. btnColor: 'secondary',
  175. onClick: () => {
  176. setDialog({
  177. open: true,
  178. type: 'custom',
  179. params: {
  180. component: (
  181. <DeleteTemplate
  182. label={btnTrans('drop')}
  183. title={dialogTrans('deleteTitle', { type: userTrans('user') })}
  184. text={userTrans('deleteWarning')}
  185. handleDelete={handleDelete}
  186. />
  187. ),
  188. },
  189. });
  190. },
  191. label: btnTrans('drop'),
  192. disabled: () =>
  193. selectedUser.length === 0 ||
  194. selectedUser.findIndex(v => v.username === 'root') > -1,
  195. disabledTooltip: userTrans('deleteTip'),
  196. icon: 'cross',
  197. },
  198. ];
  199. const colDefinitions: ColDefinitionsType[] = [
  200. {
  201. id: 'username',
  202. align: 'left',
  203. sortType: 'string',
  204. disablePadding: false,
  205. label: userTrans('user'),
  206. },
  207. {
  208. id: 'roles',
  209. align: 'left',
  210. notSort: true,
  211. disablePadding: true,
  212. label: userTrans('role'),
  213. formatter(rowData, cellData) {
  214. return rowData.username === 'root' ? 'admin' : cellData.join(', ');
  215. },
  216. getStyle: () => {
  217. return { width: '80%' };
  218. },
  219. },
  220. ];
  221. const handleSelectChange = (value: UserWithRoles[]) => {
  222. setSelectedUser(value);
  223. };
  224. useEffect(() => {
  225. fetchUsers();
  226. }, []);
  227. const handlePageChange = (e: any, page: number) => {
  228. handleCurrentPage(page);
  229. };
  230. return (
  231. <Wrapper hasPermission={hasPermission}>
  232. <AttuGrid
  233. toolbarConfigs={toolbarConfigs}
  234. colDefinitions={colDefinitions}
  235. rows={result}
  236. rowCount={total}
  237. primaryKey="username"
  238. showPagination={true}
  239. selected={selectedUser}
  240. setSelected={handleSelectChange}
  241. page={currentPage}
  242. onPageChange={handlePageChange}
  243. rowsPerPage={pageSize}
  244. setRowsPerPage={handlePageSize}
  245. isLoading={loading}
  246. order={order}
  247. orderBy={orderBy}
  248. handleSort={handleGridSort}
  249. labelDisplayedRows={getLabelDisplayedRows(commonTrans('grid.users'))}
  250. />
  251. </Wrapper>
  252. );
  253. };
  254. export default Users;