diff --git a/packages/web/src/locales/en.json b/packages/web/src/locales/en.json index 8ad1bca7..78a0a077 100644 --- a/packages/web/src/locales/en.json +++ b/packages/web/src/locales/en.json @@ -257,6 +257,7 @@ "deleteRoleButton.successfullyDeleted": "The role has been deleted.", "deleteRoleButton.generalError": "Failed while deleting!", "editRolePage.title": "Edit role", + "editRolePage.permissionsError": "Permissions are invalid.", "createRolePage.title": "Create role", "roleForm.name": "Name", "roleForm.description": "Description", diff --git a/packages/web/src/pages/EditRole/index.ee.jsx b/packages/web/src/pages/EditRole/index.ee.jsx index 92573e1e..d503969b 100644 --- a/packages/web/src/pages/EditRole/index.ee.jsx +++ b/packages/web/src/pages/EditRole/index.ee.jsx @@ -5,6 +5,10 @@ import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar'; import * as React from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { merge } from 'lodash'; +import Alert from '@mui/material/Alert'; +import AlertTitle from '@mui/material/AlertTitle'; +import { yupResolver } from '@hookform/resolvers/yup'; +import * as yup from 'yup'; import Container from 'components/Container'; import Form from 'components/Form'; @@ -22,6 +26,40 @@ import useAdminUpdateRole from 'hooks/useAdminUpdateRole'; import useRole from 'hooks/useRole.ee'; import usePermissionCatalog from 'hooks/usePermissionCatalog.ee'; +const getValidationSchema = (formatMessage) => { + const getMandatoryFieldMessage = (fieldTranslationId) => + formatMessage('roleForm.mandatoryInput', { + inputName: formatMessage(fieldTranslationId), + }); + + return yup.object().shape({ + name: yup + .string() + .trim() + .required(getMandatoryFieldMessage('roleForm.name')), + description: yup.string().trim(), + }); +}; + +const getPermissionsErrorMessage = (error) => { + const errors = error?.response?.data?.errors; + + if (errors) { + const permissionsErrors = Object.keys(errors) + .filter((key) => key.startsWith('permissions')) + .reduce((obj, key) => { + obj[key] = errors[key]; + return obj; + }, {}); + + if (Object.keys(permissionsErrors).length > 0) { + return JSON.stringify(permissionsErrors, null, 2); + } + } + + return null; +}; + export default function EditRole() { const formatMessage = useFormatMessage(); const navigate = useNavigate(); @@ -34,9 +72,11 @@ export default function EditRole() { const role = roleData?.data; const permissionCatalog = permissionCatalogData?.data; const enqueueSnackbar = useEnqueueSnackbar(); + const [permissionError, setPermissionError] = React.useState(null); const handleRoleUpdate = async (roleData) => { try { + setPermissionError(null); const newPermissions = getPermissions(roleData.computedPermissions); await updateRole({ name: roleData.name, @@ -53,7 +93,13 @@ export default function EditRole() { navigate(URLS.ROLES); } catch (error) { - throw new Error('Failed while updating!'); + const permissionError = getPermissionsErrorMessage(error); + if (permissionError) { + setPermissionError(permissionError); + } + + const errors = error?.response?.data?.errors; + throw errors || error; } }; @@ -82,46 +128,72 @@ export default function EditRole() { -
- - - - - - {formatMessage('editRole.submit')} - - -
+
( + + + + + {permissionError && ( + + + {formatMessage('editRolePage.permissionsError')} + +
+                      {permissionError}
+                    
+
+ )} + {errors?.root?.general && !permissionError && ( + + {errors?.root?.general?.message} + + )} + + {formatMessage('editRole.submit')} + +
+ )} + />