User.tsx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import React, { useContext, useEffect, useState } from 'react';
  2. import { makeStyles, Theme } from '@material-ui/core';
  3. import { useTranslation } from 'react-i18next';
  4. import { UserHttp } from '@/http/User';
  5. import AttuGrid from '@/components/grid/Grid';
  6. import { ColDefinitionsType, ToolBarConfig } from '@/components/grid/Types';
  7. import {
  8. CreateUserParams,
  9. DeleteUserParams,
  10. UpdateUserParams,
  11. UserData,
  12. UpdateUserRoleParams,
  13. } from './Types';
  14. import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
  15. import { rootContext } from '@/context/Root';
  16. import { useNavigationHook } from '@/hooks/Navigation';
  17. import { ALL_ROUTER_TYPES } from '@/router/Types';
  18. import CreateUser from './CreateUser';
  19. import UpdateUserRole from './UpdateUserRole';
  20. import UpdateUser from './Update';
  21. const useStyles = makeStyles((theme: Theme) => ({
  22. wrapper: {
  23. height: `calc(100vh - 160px)`,
  24. },
  25. }));
  26. const Users = () => {
  27. useNavigationHook(ALL_ROUTER_TYPES.USER);
  28. const classes = useStyles();
  29. const [users, setUsers] = useState<UserData[]>([]);
  30. const [selectedUser, setSelectedUser] = useState<UserData[]>([]);
  31. const { setDialog, handleCloseDialog, openSnackBar } =
  32. useContext(rootContext);
  33. const { t: successTrans } = useTranslation('success');
  34. const { t: userTrans } = useTranslation('user');
  35. const { t: btnTrans } = useTranslation('btn');
  36. const { t: dialogTrans } = useTranslation('dialog');
  37. const fetchUsers = async () => {
  38. const res = await UserHttp.getUsers();
  39. const roles = await UserHttp.getRoles();
  40. setUsers(
  41. res.usernames.map((v: string) => {
  42. const name = v;
  43. const rolesByName = roles.results.filter((r: any) =>
  44. r.users.map((u: any) => u.name).includes(name)
  45. );
  46. const originRoles =
  47. v === 'root' ? ['root'] : rolesByName.map((r: any) => r.role.name);
  48. return {
  49. name: v,
  50. role: originRoles.join(' , '),
  51. roles: originRoles,
  52. };
  53. })
  54. );
  55. };
  56. const handleCreate = async (data: CreateUserParams) => {
  57. await UserHttp.createUser(data);
  58. // assign user role if
  59. await UserHttp.updateUserRole({
  60. username: data.username,
  61. roles: data.roles,
  62. });
  63. fetchUsers();
  64. openSnackBar(successTrans('create', { name: userTrans('user') }));
  65. handleCloseDialog();
  66. };
  67. const onUpdate = async (data: UpdateUserRoleParams) => {
  68. fetchUsers();
  69. openSnackBar(
  70. successTrans('update', { name: userTrans('updateRoleSuccess') })
  71. );
  72. handleCloseDialog();
  73. };
  74. const handleUpdate = async (data: UpdateUserParams) => {
  75. await UserHttp.updateUser(data);
  76. fetchUsers();
  77. openSnackBar(successTrans('update', { name: userTrans('user') }));
  78. handleCloseDialog();
  79. };
  80. const handleDelete = async () => {
  81. for (const user of selectedUser) {
  82. const param: DeleteUserParams = {
  83. username: user.name,
  84. };
  85. await UserHttp.deleteUser(param);
  86. }
  87. openSnackBar(successTrans('delete', { name: userTrans('user') }));
  88. fetchUsers();
  89. handleCloseDialog();
  90. };
  91. const toolbarConfigs: ToolBarConfig[] = [
  92. {
  93. label: userTrans('user'),
  94. onClick: async () => {
  95. const roles = await UserHttp.getRoles();
  96. setDialog({
  97. open: true,
  98. type: 'custom',
  99. params: {
  100. component: (
  101. <CreateUser
  102. handleCreate={handleCreate}
  103. handleClose={handleCloseDialog}
  104. roleOptions={roles.results.map((r: any) => {
  105. return { label: r.role.name, value: r.role.name };
  106. })}
  107. />
  108. ),
  109. },
  110. });
  111. },
  112. icon: 'add',
  113. },
  114. {
  115. type: 'iconBtn',
  116. label: userTrans('editRole'),
  117. onClick: async () => {
  118. setDialog({
  119. open: true,
  120. type: 'custom',
  121. params: {
  122. component: (
  123. <UpdateUserRole
  124. username={selectedUser[0]!.name}
  125. onUpdate={onUpdate}
  126. handleClose={handleCloseDialog}
  127. roles={
  128. users.filter(u => u.name === selectedUser[0].name)[0].roles
  129. }
  130. />
  131. ),
  132. },
  133. });
  134. },
  135. icon: 'edit',
  136. disabled: () =>
  137. selectedUser.length === 0 ||
  138. selectedUser.length > 1 ||
  139. selectedUser.findIndex(v => v.name === 'root') > -1,
  140. disabledTooltip: userTrans('deleteEditRoleTip'),
  141. },
  142. {
  143. type: 'iconBtn',
  144. onClick: () => {
  145. setDialog({
  146. open: true,
  147. type: 'custom',
  148. params: {
  149. component: (
  150. <DeleteTemplate
  151. label={btnTrans('drop')}
  152. title={dialogTrans('deleteTitle', { type: userTrans('user') })}
  153. text={userTrans('deleteWarning')}
  154. handleDelete={handleDelete}
  155. />
  156. ),
  157. },
  158. });
  159. },
  160. label: '',
  161. disabled: () =>
  162. selectedUser.length === 0 ||
  163. selectedUser.findIndex(v => v.name === 'root') > -1,
  164. disabledTooltip: userTrans('deleteTip'),
  165. icon: 'delete',
  166. },
  167. ];
  168. const colDefinitions: ColDefinitionsType[] = [
  169. {
  170. id: 'name',
  171. align: 'left',
  172. disablePadding: false,
  173. label: userTrans('user'),
  174. },
  175. {
  176. id: 'role',
  177. align: 'left',
  178. disablePadding: false,
  179. label: userTrans('role'),
  180. },
  181. {
  182. id: 'action',
  183. disablePadding: false,
  184. label: 'Action',
  185. showActionCell: true,
  186. sortBy: 'action',
  187. actionBarConfigs: [
  188. {
  189. onClick: (e: React.MouseEvent, row: UserData) => {
  190. setDialog({
  191. open: true,
  192. type: 'custom',
  193. params: {
  194. component: (
  195. <UpdateUser
  196. username={row.name}
  197. handleUpdate={handleUpdate}
  198. handleClose={handleCloseDialog}
  199. />
  200. ),
  201. },
  202. });
  203. },
  204. linkButton: true,
  205. text: 'Update password',
  206. },
  207. ],
  208. },
  209. ];
  210. const handleSelectChange = (value: UserData[]) => {
  211. setSelectedUser(value);
  212. };
  213. useEffect(() => {
  214. fetchUsers();
  215. }, []);
  216. return (
  217. <div className={classes.wrapper}>
  218. <AttuGrid
  219. toolbarConfigs={toolbarConfigs}
  220. colDefinitions={colDefinitions}
  221. rows={users}
  222. rowCount={users.length}
  223. primaryKey="name"
  224. showPagination={false}
  225. selected={selectedUser}
  226. setSelected={handleSelectChange}
  227. // page={currentPage}
  228. // onChangePage={handlePageChange}
  229. // rowsPerPage={pageSize}
  230. // setRowsPerPage={handlePageSize}
  231. // isLoading={loading}
  232. // order={order}
  233. // orderBy={orderBy}
  234. // handleSort={handleGridSort}
  235. />
  236. </div>
  237. );
  238. };
  239. export default Users;