UpdateRoleDialog.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { makeStyles, Theme, Typography } from '@material-ui/core';
  2. import { FC, useMemo, useState, useEffect } from 'react';
  3. import { useTranslation } from 'react-i18next';
  4. import DialogTemplate from '@/components/customDialog/DialogTemplate';
  5. import CustomInput from '@/components/customInput/CustomInput';
  6. import { ITextfieldConfig } from '@/components/customInput/Types';
  7. import { useFormValidation } from '@/hooks/Form';
  8. import { formatForm } from '@/utils/Form';
  9. import { UserHttp } from '@/http/User';
  10. import {
  11. CreateRoleProps,
  12. CreateRoleParams,
  13. PrivilegeOptionsProps,
  14. } from './Types';
  15. import PrivilegeOptions from './PrivilegeOptions';
  16. const useStyles = makeStyles((theme: Theme) => ({
  17. input: {
  18. margin: theme.spacing(1, 0, 0.5),
  19. },
  20. dialogWrapper: {
  21. maxWidth: theme.spacing(88),
  22. },
  23. checkBox: {
  24. width: theme.spacing(24),
  25. },
  26. formGrp: {
  27. marginBottom: theme.spacing(2),
  28. },
  29. subTitle: {
  30. marginBottom: theme.spacing(0.5),
  31. },
  32. }));
  33. const UpdateRoleDialog: FC<CreateRoleProps> = ({
  34. onUpdate,
  35. handleClose,
  36. role = { name: '', privileges: [] },
  37. }) => {
  38. const { t: userTrans } = useTranslation('user');
  39. const { t: btnTrans } = useTranslation('btn');
  40. const { t: warningTrans } = useTranslation('warning');
  41. const [rbacOptions, setRbacOptions] = useState({
  42. GlobalPrivileges: {},
  43. CollectionPrivileges: {},
  44. RbacObjects: {},
  45. UserPrivileges: {},
  46. Privileges: {},
  47. });
  48. const fetchRBAC = async () => {
  49. const rbacOptions = await UserHttp.getRBAC();
  50. setRbacOptions(rbacOptions);
  51. };
  52. const isEditing = role.name !== '';
  53. useEffect(() => {
  54. fetchRBAC();
  55. }, []);
  56. const [form, setForm] = useState<CreateRoleParams>({
  57. roleName: role.name,
  58. privileges: JSON.parse(JSON.stringify(role.privileges)),
  59. });
  60. const checkedForm = useMemo(() => {
  61. return formatForm(form);
  62. }, [form]);
  63. const { validation, checkIsValid, disabled } = useFormValidation(checkedForm);
  64. const classes = useStyles();
  65. const handleInputChange = (key: 'roleName', value: string) => {
  66. setForm(v => {
  67. const newFrom = { ...v, [key]: value };
  68. // update roleName
  69. newFrom.privileges.forEach(p => (p.roleName = value));
  70. return newFrom;
  71. });
  72. };
  73. const createConfigs: ITextfieldConfig[] = [
  74. {
  75. label: userTrans('role'),
  76. key: 'roleName',
  77. onChange: (value: string) => handleInputChange('roleName', value),
  78. variant: 'filled',
  79. className: classes.input,
  80. placeholder: userTrans('role'),
  81. fullWidth: true,
  82. validations: [
  83. {
  84. rule: 'require',
  85. errorText: warningTrans('required', {
  86. name: userTrans('role'),
  87. }),
  88. },
  89. ],
  90. defaultValue: form.roleName,
  91. disabled: isEditing,
  92. },
  93. ];
  94. const handleCreateRole = async () => {
  95. if (!isEditing) {
  96. await UserHttp.createRole(form);
  97. }
  98. await UserHttp.updateRolePrivileges(form);
  99. onUpdate({ data: form, isEditing: isEditing });
  100. };
  101. const onChange = (newSelection: any) => {
  102. setForm(v => ({ ...v, privileges: [...newSelection] }));
  103. };
  104. const optionGroups: PrivilegeOptionsProps[] = [
  105. {
  106. options: Object.values(rbacOptions.GlobalPrivileges) as string[],
  107. object: 'Global',
  108. title: userTrans('objectGlobal'),
  109. selection: form.privileges,
  110. roleName: form.roleName,
  111. onChange: onChange,
  112. },
  113. {
  114. options: Object.values(rbacOptions.CollectionPrivileges) as string[],
  115. title: userTrans('objectCollection'),
  116. object: 'Collection',
  117. selection: form.privileges,
  118. roleName: form.roleName,
  119. onChange: onChange,
  120. },
  121. {
  122. options: Object.values(rbacOptions.UserPrivileges) as string[],
  123. title: userTrans('objectUser'),
  124. object: 'User',
  125. selection: form.privileges,
  126. roleName: form.roleName,
  127. onChange: onChange,
  128. },
  129. ];
  130. return (
  131. <DialogTemplate
  132. title={userTrans(
  133. isEditing ? 'updateRolePrivilegeTitle' : 'createRoleTitle'
  134. )}
  135. handleClose={handleClose}
  136. confirmLabel={btnTrans(isEditing ? 'update' : 'create')}
  137. handleConfirm={handleCreateRole}
  138. confirmDisabled={disabled}
  139. dialogClass={classes.dialogWrapper}
  140. >
  141. <>
  142. {createConfigs.map(v => (
  143. <CustomInput
  144. type="text"
  145. textConfig={v}
  146. checkValid={checkIsValid}
  147. validInfo={validation}
  148. key={v.label}
  149. />
  150. ))}
  151. <Typography variant="h5" component="h5" className={classes.subTitle}>
  152. {userTrans('privileges')}
  153. </Typography>
  154. {optionGroups.map(o => (
  155. <PrivilegeOptions
  156. key={o.object}
  157. title={o.title}
  158. object={o.object}
  159. options={o.options}
  160. selection={o.selection}
  161. roleName={o.roleName}
  162. onChange={o.onChange}
  163. />
  164. ))}
  165. </>
  166. </DialogTemplate>
  167. );
  168. };
  169. export default UpdateRoleDialog;