From e2542f39e1bbd476c1b835cc2289ecbbcf4c4536 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Apr 2025 14:01:39 +0000 Subject: [PATCH] feat(Roles): adopt request form data for new form style --- .../PermissionCatalogField/ActionField.jsx | 51 ------- .../AllEntitiesPermissions.jsx | 63 +++++++++ .../OwnEntitiesPermission.jsx | 41 ++++++ .../PermissionCatalogField/index.ee.jsx | 132 +++++++++++------- .../web/src/helpers/computePermissions.ee.js | 37 ++--- packages/web/src/locales/en.json | 4 +- .../web/src/pages/CreateRole/index.ee.jsx | 3 - packages/web/src/pages/EditRole/index.ee.jsx | 1 + 8 files changed, 201 insertions(+), 131 deletions(-) delete mode 100644 packages/web/src/components/PermissionCatalogField/ActionField.jsx create mode 100644 packages/web/src/components/PermissionCatalogField/AllEntitiesPermissions.jsx create mode 100644 packages/web/src/components/PermissionCatalogField/OwnEntitiesPermission.jsx diff --git a/packages/web/src/components/PermissionCatalogField/ActionField.jsx b/packages/web/src/components/PermissionCatalogField/ActionField.jsx deleted file mode 100644 index 3bf2dde6..00000000 --- a/packages/web/src/components/PermissionCatalogField/ActionField.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { useFormContext } from 'react-hook-form'; -import PropTypes from 'prop-types'; -import ControlledCheckbox from 'components/ControlledCheckbox'; - -const ActionField = ({ action, subject, disabled, name, syncIsCreator }) => { - const { formState, resetField } = useFormContext(); - - const actionDefaultValue = - formState.defaultValues?.[name]?.[subject.key]?.[action.key].value; - const conditionFieldName = `${name}.${subject.key}.${action.key}.conditions.isCreator`; - const conditionFieldTouched = - formState.touchedFields?.[name]?.[subject.key]?.[action.key]?.conditions - ?.isCreator === true; - - const handleSyncIsCreator = (newValue) => { - if ( - syncIsCreator && - actionDefaultValue === false && - !conditionFieldTouched - ) { - resetField(conditionFieldName, { defaultValue: newValue }); - } - }; - - return ( - { - handleSyncIsCreator(value); - }} - /> - ); -}; - -ActionField.propTypes = { - action: PropTypes.shape({ - key: PropTypes.string.isRequired, - subjects: PropTypes.arrayOf(PropTypes.string).isRequired, - }), - subject: PropTypes.shape({ - key: PropTypes.string.isRequired, - }).isRequired, - disabled: PropTypes.bool, - name: PropTypes.string.isRequired, - syncIsCreator: PropTypes.bool, -}; - -export default ActionField; diff --git a/packages/web/src/components/PermissionCatalogField/AllEntitiesPermissions.jsx b/packages/web/src/components/PermissionCatalogField/AllEntitiesPermissions.jsx new file mode 100644 index 00000000..ade1408a --- /dev/null +++ b/packages/web/src/components/PermissionCatalogField/AllEntitiesPermissions.jsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { useFormContext } from 'react-hook-form'; +import PropTypes from 'prop-types'; +import ControlledCheckbox from 'components/ControlledCheckbox'; + +const AllEntitiesPermissions = ({ + action, + subject, + disabled, + name, + syncIsCreator, +}) => { + const { getValues, formState, resetField } = useFormContext(); + + const fieldName = `${name}.${subject.key}.${action.key}.allEntities`; + const defaultValue = + formState.defaultValues?.[name]?.[subject.key]?.[action.key].allEntities; + const ownEntitiesFieldName = `${name}.${subject.key}.${action.key}.ownEntities`; + const ownEntitiesFieldTouched = + formState.touchedFields?.[name]?.[subject.key]?.[action.key] + ?.ownEntities === true; + + const currentValue = getValues(fieldName); + + React.useEffect(() => { + if (currentValue === true) { + resetField(ownEntitiesFieldName, { defaultValue: true }); + } + }, [ownEntitiesFieldName, currentValue]); + + const handleSyncIsCreator = (newValue) => { + if (syncIsCreator && defaultValue === false && !ownEntitiesFieldTouched) { + resetField(ownEntitiesFieldName, { defaultValue: newValue }); + } + + if (newValue === true) { + resetField(ownEntitiesFieldName, { defaultValue: true }); + } + }; + + return ( + + ); +}; + +AllEntitiesPermissions.propTypes = { + action: PropTypes.shape({ + key: PropTypes.string.isRequired, + subjects: PropTypes.arrayOf(PropTypes.string).isRequired, + }), + subject: PropTypes.shape({ + key: PropTypes.string.isRequired, + }).isRequired, + disabled: PropTypes.bool, + name: PropTypes.string.isRequired, + syncIsCreator: PropTypes.bool, +}; + +export default AllEntitiesPermissions; diff --git a/packages/web/src/components/PermissionCatalogField/OwnEntitiesPermission.jsx b/packages/web/src/components/PermissionCatalogField/OwnEntitiesPermission.jsx new file mode 100644 index 00000000..ee4f91bb --- /dev/null +++ b/packages/web/src/components/PermissionCatalogField/OwnEntitiesPermission.jsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { useFormContext } from 'react-hook-form'; +import PropTypes from 'prop-types'; +import ControlledCheckbox from 'components/ControlledCheckbox'; + +const OwnEntitiesPermission = ({ action, subject, disabled, name }) => { + const { getValues, resetField } = useFormContext(); + + const fieldName = `${name}.${subject.key}.${action.key}.ownEntities`; + const allEntitiesFieldName = `${name}.${subject.key}.${action.key}.allEntities`; + + const currentValue = getValues(fieldName); + + React.useEffect(() => { + if (currentValue === false) { + resetField(allEntitiesFieldName, { defaultValue: false }); + } + }, [allEntitiesFieldName, currentValue]); + + return ( + + ); +}; + +OwnEntitiesPermission.propTypes = { + action: PropTypes.shape({ + key: PropTypes.string.isRequired, + subjects: PropTypes.arrayOf(PropTypes.string).isRequired, + }), + subject: PropTypes.shape({ + key: PropTypes.string.isRequired, + }).isRequired, + disabled: PropTypes.bool, + name: PropTypes.string.isRequired, +}; + +export default OwnEntitiesPermission; diff --git a/packages/web/src/components/PermissionCatalogField/index.ee.jsx b/packages/web/src/components/PermissionCatalogField/index.ee.jsx index 1c8d6902..0392d4cf 100644 --- a/packages/web/src/components/PermissionCatalogField/index.ee.jsx +++ b/packages/web/src/components/PermissionCatalogField/index.ee.jsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import SettingsIcon from '@mui/icons-material/Settings'; import IconButton from '@mui/material/IconButton'; import Paper from '@mui/material/Paper'; @@ -10,12 +9,16 @@ import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; +import PropTypes from 'prop-types'; import * as React from 'react'; +import ControlledCheckbox from 'components/ControlledCheckbox'; import usePermissionCatalog from 'hooks/usePermissionCatalog.ee'; -import PermissionSettings from './PermissionSettings.ee'; +import useFormatMessage from 'hooks/useFormatMessage'; +import AllEntitiesPermissions from './AllEntitiesPermissions'; +import ConditionField from './OwnEntitiesPermission'; import PermissionCatalogFieldLoader from './PermissionCatalogFieldLoader'; -import ActionField from './ActionField'; +import PermissionSettings from './PermissionSettings.ee'; const PermissionCatalogField = ({ name = 'permissions', @@ -23,6 +26,7 @@ const PermissionCatalogField = ({ syncIsCreator = false, loading = false, }) => { + const formatMessage = useFormatMessage(); const { data, isLoading: isPermissionCatalogLoading } = usePermissionCatalog(); const permissionCatalog = data?.data; @@ -39,24 +43,44 @@ const PermissionCatalogField = ({ {permissionCatalog?.actions.map((action) => ( - - - {action.label} - - - ))} + + + + {action.label}{' '} + {formatMessage('permissionCatalogField.ownEntitiesLabel')} + + - + + + {action.label}{' '} + {formatMessage('permissionCatalogField.allEntitiesLabel')} + + + + ))} + {permissionCatalog?.subjects.map((subject) => ( {permissionCatalog?.actions.map((action) => ( - - - {action.subjects.includes(subject.key) && ( - - )} - {!action.subjects.includes(subject.key) && '-'} - - - ))} - - - - setDialogName(subject.key)} - disabled={disabled} - data-test="permission-settings-button" + + - - + + {action.subjects.includes(subject.key) && ( + + )} + {!action.subjects.includes(subject.key) && '-'} + + - setDialogName('')} - fieldPrefix={`${name}.${subject.key}`} - subject={subject.key} - actions={permissionCatalog?.actions} - conditions={permissionCatalog?.conditions} - /> - - + + + {action.subjects.includes(subject.key) && ( + + )} + {!action.subjects.includes(subject.key) && '-'} + + + + ))} ))} @@ -116,6 +139,7 @@ const PermissionCatalogField = ({ ); }; + PermissionCatalogField.propTypes = { name: PropTypes.string, disabled: PropTypes.bool, diff --git a/packages/web/src/helpers/computePermissions.ee.js b/packages/web/src/helpers/computePermissions.ee.js index 3bcfa521..3956eedb 100644 --- a/packages/web/src/helpers/computePermissions.ee.js +++ b/packages/web/src/helpers/computePermissions.ee.js @@ -6,10 +6,8 @@ export function getRoleWithComputedPermissions(role) { [permission.subject]: { ...(computedPermissions[permission.subject] || {}), [permission.action]: { - conditions: Object.fromEntries( - permission.conditions.map((condition) => [condition, true]), - ), - value: true, + allEntities: permission.conditions.includes('isCreator') === false, + ownEntities: true, }, }, }), @@ -28,15 +26,19 @@ export function getPermissions(computedPermissions) { (permissions, computedPermissionEntry) => { const [subject, actionsWithConditions] = computedPermissionEntry; for (const action in actionsWithConditions) { - const { value: permitted, conditions = {} } = - actionsWithConditions[action]; - if (permitted) { + const { ownEntities, allEntities } = actionsWithConditions[action]; + + if (ownEntities && !allEntities) { permissions.push({ action, subject, - conditions: Object.entries(conditions) - .filter(([, enabled]) => enabled) - .map(([condition]) => condition), + conditions: ['isCreator'], + }); + } else if (ownEntities && allEntities) { + permissions.push({ + action, + subject, + conditions: [], }); } } @@ -46,18 +48,9 @@ export function getPermissions(computedPermissions) { ); } -export const getComputedPermissionsDefaultValues = ( - data, - conditionsInitialValues, -) => { +export const getComputedPermissionsDefaultValues = (data) => { if (!data) return {}; - const conditions = {}; - data.conditions.forEach((condition) => { - conditions[condition.key] = - conditionsInitialValues?.[condition.key] || false; - }); - const result = {}; data.subjects.forEach((subject) => { @@ -69,8 +62,8 @@ export const getComputedPermissionsDefaultValues = ( if (action.subjects.includes(subjectKey)) { result[subjectKey][actionKey] = { - value: false, - conditions: { ...conditions }, + ownEntities: false, + allEntities: false, }; } }); diff --git a/packages/web/src/locales/en.json b/packages/web/src/locales/en.json index 90504e13..e2ad9620 100644 --- a/packages/web/src/locales/en.json +++ b/packages/web/src/locales/en.json @@ -403,5 +403,7 @@ "executionFilters.statusFilterSuccessfulOption": "Successful", "executionFilters.statusFilterFailedOption": "Failed", "executionFilters.startDateLabel": "Start Date", - "executionFilters.endDateLabel": "End Date" + "executionFilters.endDateLabel": "End Date", + "permissionCatalogField.ownEntitiesLabel": "(own entities)", + "permissionCatalogField.allEntitiesLabel": "(all entities)" } diff --git a/packages/web/src/pages/CreateRole/index.ee.jsx b/packages/web/src/pages/CreateRole/index.ee.jsx index 88ac1d82..6fe50b41 100644 --- a/packages/web/src/pages/CreateRole/index.ee.jsx +++ b/packages/web/src/pages/CreateRole/index.ee.jsx @@ -73,9 +73,6 @@ export default function CreateRole() { description: '', computedPermissions: getComputedPermissionsDefaultValues( permissionCatalogData?.data, - { - isCreator: true, - }, ), }), [permissionCatalogData], diff --git a/packages/web/src/pages/EditRole/index.ee.jsx b/packages/web/src/pages/EditRole/index.ee.jsx index d503969b..326ac7ed 100644 --- a/packages/web/src/pages/EditRole/index.ee.jsx +++ b/packages/web/src/pages/EditRole/index.ee.jsx @@ -78,6 +78,7 @@ export default function EditRole() { try { setPermissionError(null); const newPermissions = getPermissions(roleData.computedPermissions); + await updateRole({ name: roleData.name, description: roleData.description,