Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: multiple project roles (#4512)
https://linear.app/unleash/issue/2-1128/change-the-api-to-support-adding-multiple-roles-to-a-usergroup-on-a https://linear.app/unleash/issue/2-1125/be-able-to-fetch-all-roles-for-a-user-in-a-project https://linear.app/unleash/issue/2-1127/adapt-the-ui-to-be-able-to-do-a-multi-select-on-role-permissions-for - Allows assigning project roles to groups with root roles - Implements new methods that support assigning, editing, removing and retrieving multiple project roles in project access, along with other auxiliary methods - Adds new events for updating and removing assigned roles - Adapts `useProjectApi` to new methods that use new endpoints that support multiple roles - Adds the `multipleRoles` feature flag that controls the possibility of selecting multiple roles on the UI - Adapts `ProjectAccessAssign` to support multiple role, using the new methods - Adds a new `MultipleRoleSelect` component that allows you to select multiple roles based on the `RoleSelect` component - Adapts the `RoleCell` component to support either a single role or multiple roles - Updates the `access.spec.ts` Cypress e2e test to reflect our new logic - Updates `access-service.e2e.test.ts` with tests covering the multiple roles logic and covering some corner cases - Updates `project-service.e2e.test.ts` to adapt to the new logic, adding a test that covers adding access with `[roles], [groups], [users]` - Misc refactors and boy scouting ![image](https://github.com/Unleash/unleash/assets/14320932/d1cc7626-9387-4ab8-9860-cd293a0d4f62) --------- Co-authored-by: David Leek <david@getunleash.io> Co-authored-by: Mateusz Kwasniewski <kwasniewski.mateusz@gmail.com> Co-authored-by: Nuno Góis <github@nunogois.com>
- Loading branch information
1 parent
1f96c16
commit 21b4ada
Showing
26 changed files
with
1,927 additions
and
430 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
frontend/src/component/common/MultipleRoleSelect/MultipleRoleSelect.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { | ||
Autocomplete, | ||
AutocompleteProps, | ||
AutocompleteRenderOptionState, | ||
Checkbox, | ||
TextField, | ||
styled, | ||
} from '@mui/material'; | ||
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; | ||
import CheckBoxIcon from '@mui/icons-material/CheckBox'; | ||
import { IRole } from 'interfaces/role'; | ||
import { RoleDescription } from '../RoleDescription/RoleDescription'; | ||
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; | ||
|
||
const StyledRoleOption = styled('div')(({ theme }) => ({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
'& > span:last-of-type': { | ||
fontSize: theme.fontSizes.smallerBody, | ||
color: theme.palette.text.secondary, | ||
}, | ||
})); | ||
|
||
interface IMultipleRoleSelectProps | ||
extends Partial<AutocompleteProps<IRole, true, false, false>> { | ||
roles: IRole[]; | ||
value: IRole[]; | ||
setValue: (role: IRole[]) => void; | ||
required?: boolean; | ||
} | ||
|
||
export const MultipleRoleSelect = ({ | ||
roles, | ||
value, | ||
setValue, | ||
required, | ||
...rest | ||
}: IMultipleRoleSelectProps) => { | ||
const renderRoleOption = ( | ||
props: React.HTMLAttributes<HTMLLIElement>, | ||
option: IRole, | ||
state: AutocompleteRenderOptionState | ||
) => ( | ||
<li {...props}> | ||
<Checkbox | ||
icon={<CheckBoxOutlineBlankIcon fontSize="small" />} | ||
checkedIcon={<CheckBoxIcon fontSize="small" />} | ||
style={{ marginRight: 8 }} | ||
checked={state.selected} | ||
/> | ||
<StyledRoleOption> | ||
<span>{option.name}</span> | ||
<span>{option.description}</span> | ||
</StyledRoleOption> | ||
</li> | ||
); | ||
|
||
return ( | ||
<> | ||
<Autocomplete | ||
multiple | ||
disableCloseOnSelect | ||
openOnFocus | ||
size="small" | ||
value={value} | ||
onChange={(_, roles) => setValue(roles)} | ||
options={roles} | ||
renderOption={renderRoleOption} | ||
getOptionLabel={option => option.name} | ||
renderInput={params => ( | ||
<TextField {...params} label="Role" required={required} /> | ||
)} | ||
{...rest} | ||
/> | ||
<ConditionallyRender | ||
condition={value.length > 0} | ||
show={() => | ||
value.map(({ id }) => ( | ||
<RoleDescription | ||
key={id} | ||
sx={{ marginTop: 1 }} | ||
roleId={id} | ||
/> | ||
)) | ||
} | ||
/> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.