diff --git a/src/buttons/RolesEditionButton/RolesEditionButton.js b/src/buttons/RolesEditionButton/RolesEditionButton.js index 65964bab..0aa59e6e 100644 --- a/src/buttons/RolesEditionButton/RolesEditionButton.js +++ b/src/buttons/RolesEditionButton/RolesEditionButton.js @@ -18,9 +18,11 @@ export const RolesEditionButton = ({ labels: tmpLabels, isIconButton = false, agents, + hasWriteSecurityPermission, + specificSharingRestriction, + canBeSharedWithAgent, resourceRolesPermissionsMapping, preventNoneRoleForAgents = false, - isReadOnly = false, disabled = false, onConfirmChanges, specificAccessByAgent, @@ -69,8 +71,10 @@ export const RolesEditionButton = ({ accessControlList={specificAccessByAgent} defaultRole={defaultRole} agents={agents} + canBeSharedWithAgent={canBeSharedWithAgent} labels={labels.dialog} - isReadOnly={isReadOnly} + hasWriteSecurityPermission={hasWriteSecurityPermission} + specificSharingRestriction={specificSharingRestriction} onConfirmChanges={onConfirmChanges} closeDialog={closeDialog} allRoles={allRoles} @@ -88,9 +92,15 @@ RolesEditionButton.propTypes = { */ isIconButton: PropTypes.bool, /** - * Defines whether user can edit or only see the resource's permissions; false by default + * Defines if current user has write security permission on the resource + * - true : selectors are enabled and share button is visible + * - false : selectors and share button are hidden */ - isReadOnly: PropTypes.bool, + hasWriteSecurityPermission: PropTypes.bool, + /** + * * Defines restriction for sharing the resource + */ + specificSharingRestriction: PropTypes.string, /** * Defines the RolesEditionButton's state: * - true : the button is disabled (the tooltip will guide users on how to enable the button) @@ -100,8 +110,13 @@ RolesEditionButton.propTypes = { /** * List of all users or users groups in the workspace */ - agents: PropTypes.array.isRequired, + /** + * Function that checks if the resource can be shared with the user + * - returns null if the resource can be shared with the user + * - returns a string (reason) if the resource cannot be shared with the user + */ + canBeSharedWithAgent: PropTypes.func, /** * List of users or users groups having specific access to the resource */ @@ -161,6 +176,7 @@ RolesEditionButton.propTypes = { noAdminError: 'string', userSelected: 'string', usersAccess: 'string', + disabledUserTooltip: 'function', generalAccess: 'string', removeAccess: 'string', add: 'object', diff --git a/src/buttons/RolesEditionButton/RolesEditionButton.spec.js b/src/buttons/RolesEditionButton/RolesEditionButton.spec.js index e9671810..c366448e 100644 --- a/src/buttons/RolesEditionButton/RolesEditionButton.spec.js +++ b/src/buttons/RolesEditionButton/RolesEditionButton.spec.js @@ -28,7 +28,6 @@ const defaultProps = { specificAccessByAgent: SAMPLE_AGENTS.specificAccessByAgent, resourceRolesPermissionsMapping: RESOURCE_ROLES_PERMISSIONS_MAPPING, preventNoneRoleForAgents: true, - isReadOnly: false, defaultRole: 'viewer', allRoles: ALL_ROLES, allPermissions: ALL_PERMISSIONS, @@ -73,7 +72,9 @@ describe('RoleEditionButton', () => { defaultRole: defaultProps.defaultRole, agents: defaultProps.agents, labels: defaultProps.labels.dialog, - isReadOnly: defaultProps.isReadOnly, + hasWriteSecurityPermission: defaultProps.hasWriteSecurityPermission, + specificSharingRestriction: defaultProps.specificSharingRestriction, + canBeSharedWithAgent: defaultProps.canBeSharedWithAgent, allRoles: defaultProps.allRoles, allPermissions: defaultProps.allPermissions, defaultAccessScope: defaultProps.defaultAccessScope, diff --git a/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.js b/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.js index fcad50a1..9c208c7f 100644 --- a/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.js +++ b/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.js @@ -16,9 +16,11 @@ import { IconButton, Typography, Autocomplete, + Box, } from '@mui/material'; import { styled } from '@mui/material/styles'; import { RoleEditor } from '../../../../inputs'; +import { FadingTooltip } from '../../../../misc'; import { getIdentifierFromUserEmail } from '../../../../utils'; import { RolesAddingDialog } from './components'; @@ -54,7 +56,9 @@ const sortById = (agentA, agentB) => (agentA.id < agentB.id ? -1 : 1); export const RolesEditionDialog = ({ labels: tmpLabels, - isReadOnly = false, + hasWriteSecurityPermission = true, + specificSharingRestriction, + canBeSharedWithAgent = () => null, resourceRolesPermissionsMapping, preventNoneRoleForAgents = false, onConfirmChanges, @@ -71,7 +75,6 @@ export const RolesEditionDialog = ({ const [selectedAgentForRoleAddition, setSelectedAgentForRoleAddition] = useState(null); const [newAccessControlList, setNewAccessControlList] = useState([...accessControlList].sort(sortById)); const [newDefaultRole, setNewDefaultRole] = useState(defaultRole || ''); - const labels = { ...DEFAULT_LABELS, ...tmpLabels }; useEffect(() => { @@ -135,12 +138,14 @@ export const RolesEditionDialog = ({ <> - {!isReadOnly && ( + {hasWriteSecurityPermission && ( canBeSharedWithAgent(option) != null} autoComplete + disabled={specificSharingRestriction != null} disableClearable={true} options={agentsWithoutSpecificAccess} value={selectedAgentForRoleAddition?.id} @@ -151,12 +156,24 @@ export const RolesEditionDialog = ({ )} renderOption={(props, option) => { + const tooltip = canBeSharedWithAgent(option); return ( -
  • - - {option.id} - -
  • + + + + + {option.id} + + + + ); }} /> @@ -173,7 +190,7 @@ export const RolesEditionDialog = ({ agentAccess={agent.role} allRoles={preventNoneRoleForAgents ? allRolesWithoutNone : allRoles} onOptionSelected={(event) => editSpecificAccess(event, agent)} - isReadOnly={isReadOnly} + isReadOnly={!hasWriteSecurityPermission || specificSharingRestriction != null} actions={[ { id: 'remove_specific_access', @@ -201,7 +218,7 @@ export const RolesEditionDialog = ({ helperText={labels.editor.helperText} allRoles={allRoles} icon={workspaceIcon} - isReadOnly={isReadOnly} + isReadOnly={!hasWriteSecurityPermission || specificSharingRestriction != null} onOptionSelected={(event) => setNewDefaultRole(event.target.value)} />
    @@ -209,18 +226,20 @@ export const RolesEditionDialog = ({
    - {!isReadOnly && ( - + {hasWriteSecurityPermission && ( + + + )} @@ -258,7 +277,7 @@ export const RolesEditionDialog = ({ )} - {isReadOnly ? labels.readOnlyTitle : labels.title} + {hasWriteSecurityPermission ? labels.readOnlyTitle : labels.title} {dialogContent} @@ -283,12 +302,14 @@ RolesEditionDialog.propTypes = { helperText: PropTypes.object, }), }), - isReadOnly: PropTypes.bool, + hasWriteSecurityPermission: PropTypes.bool, + specificSharingRestriction: PropTypes.string, resourceRolesPermissionsMapping: PropTypes.object.isRequired, preventNoneRoleForAgents: PropTypes.bool, onConfirmChanges: PropTypes.func.isRequired, accessControlList: PropTypes.array.isRequired, agents: PropTypes.array.isRequired, + canBeSharedWithAgent: PropTypes.func, defaultRole: PropTypes.string, open: PropTypes.bool.isRequired, closeDialog: PropTypes.func.isRequired, diff --git a/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.spec.js b/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.spec.js index 50564a74..fe49c897 100644 --- a/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.spec.js +++ b/src/buttons/RolesEditionButton/components/RolesEditionDialog/RolesEditionDialog.spec.js @@ -53,7 +53,6 @@ const selectRoleForAgent = (agentId, newRole) => { const propsWithoutUsers = { labels: LABELS.dialog, - isReadOnly: false, resourceRolesPermissionsMapping: RESOURCE_ROLES_PERMISSIONS_MAPPING, allRoles: ALL_ROLES, allPermissions: ALL_PERMISSIONS, @@ -78,9 +77,9 @@ const propsWithPreventNoneRole = { preventNoneRoleForAgents: true, }; -const propsWithReadOnly = { +const propsWithWriteSecurityPermissionToFalse = { ...propsWithUsers, - isReadOnly: true, + hasWriteSecurityPermission: false, }; const allRolesWithoutNone = ALL_ROLES.filter((role) => role.value.toLowerCase() !== 'none'); @@ -384,9 +383,9 @@ describe('RolesEditionDialog', () => { }); }); - describe('Read-only', () => { + describe('Write security to false', () => { beforeEach(() => { - setUp(propsWithReadOnly); + setUp(propsWithWriteSecurityPermissionToFalse); }); test('New user cannot be added', () => {