1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-10 17:53:36 +02:00
unleash.unleash/frontend/src/component/common/MultipleRoleSelect/MultipleRoleSelect.tsx
Christopher Kolstad 21b4ada577
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>
2023-08-25 09:31:37 +01:00

90 lines
2.6 KiB
TypeScript

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}
/>
))
}
/>
</>
);
};