mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
feat: use new role components in project access (#4018)
https://linear.app/unleash/issue/2-1143/adapt-project-roles-to-use-the-new-role-selector-and-role-description This PR further unifies roles, by having a single `IRole` interface to cover both types, and re-using the same components for project roles.
This commit is contained in:
parent
a5ee50cfc9
commit
a9e9ae8c3e
@ -10,7 +10,7 @@ import { ItemList } from 'component/common/ItemList/ItemList';
|
||||
import useAuthSettings from 'hooks/api/getters/useAuthSettings/useAuthSettings';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { useUsers } from 'hooks/api/getters/useUsers/useUsers';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { RoleSelect } from 'component/common/RoleSelect/RoleSelect';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { IPermission, ICheckedPermissions } from 'interfaces/permissions';
|
||||
import IRole, { PredefinedRoleType } from 'interfaces/role';
|
||||
import { IRole, PredefinedRoleType } from 'interfaces/role';
|
||||
import { useRoles } from 'hooks/api/getters/useRoles/useRoles';
|
||||
import { permissionsToCheckedPermissions } from 'utils/permissions';
|
||||
import { ROOT_ROLE_TYPE } from '@server/util/constants';
|
||||
|
@ -17,7 +17,7 @@ import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { UPDATE_ROLE } from '@server/types/permissions';
|
||||
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
|
||||
const StyledPageContent = styled(PageContent)(({ theme }) => ({
|
||||
'& .page-header': {
|
||||
|
@ -3,7 +3,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
|
||||
import { Dialogue } from 'component/common/Dialogue/Dialogue';
|
||||
import { useServiceAccounts } from 'hooks/api/getters/useServiceAccounts/useServiceAccounts';
|
||||
import { useUsers } from 'hooks/api/getters/useUsers/useUsers';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { RoleDeleteDialogUsers } from './RoleDeleteDialogUsers/RoleDeleteDialogUsers';
|
||||
import { RoleDeleteDialogServiceAccounts } from './RoleDeleteDialogServiceAccounts/RoleDeleteDialogServiceAccounts';
|
||||
import { useGroups } from 'hooks/api/getters/useGroups/useGroups';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { VFC } from 'react';
|
||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { useRole } from 'hooks/api/getters/useRole/useRole';
|
||||
import { RoleDescription } from 'component/common/RoleDescription/RoleDescription';
|
||||
import { PREDEFINED_ROLE_TYPES } from '@server/util/constants';
|
||||
|
@ -3,7 +3,7 @@ import { Box, styled } from '@mui/material';
|
||||
import { PREDEFINED_ROLE_TYPES } from '@server/util/constants';
|
||||
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
|
||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { VFC } from 'react';
|
||||
|
||||
const StyledBox = styled(Box)(() => ({
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { Badge } from 'component/common/Badge/Badge';
|
||||
import { styled } from '@mui/material';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell';
|
||||
import { PREDEFINED_ROLE_TYPES } from '@server/util/constants';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { TablePlaceholder, VirtualizedTable } from 'component/common/Table';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import IRole, { PredefinedRoleType } from 'interfaces/role';
|
||||
import { IRole, PredefinedRoleType } from 'interfaces/role';
|
||||
import useToast from 'hooks/useToast';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||
|
@ -33,7 +33,7 @@ import { INewPersonalAPIToken } from 'interfaces/personalAPIToken';
|
||||
import { ServiceAccountTokens } from './ServiceAccountTokens/ServiceAccountTokens';
|
||||
import { IServiceAccount } from 'interfaces/service-account';
|
||||
import { RoleSelect } from 'component/common/RoleSelect/RoleSelect';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
|
||||
const StyledForm = styled('form')(() => ({
|
||||
display: 'flex',
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { TablePlaceholder, VirtualizedTable } from 'component/common/Table';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import useToast from 'hooks/useToast';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||
|
@ -5,7 +5,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
|
||||
import { EDIT } from 'constants/misc';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { RoleSelect } from 'component/common/RoleSelect/RoleSelect';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
|
||||
const StyledForm = styled('form')(() => ({
|
||||
display: 'flex',
|
||||
|
@ -7,7 +7,7 @@ import ConfirmUserAdded from '../ConfirmUserAdded/ConfirmUserAdded';
|
||||
import { useUsers } from 'hooks/api/getters/useUsers/useUsers';
|
||||
import useAdminUsersApi from 'hooks/api/actions/useAdminUsersApi/useAdminUsersApi';
|
||||
import { IUser } from 'interfaces/user';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import useToast from 'hooks/useToast';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { useUsersPlan } from 'hooks/useUsersPlan';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useUsers } from 'hooks/api/getters/useUsers/useUsers';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { useRoles } from 'hooks/api/getters/useRoles/useRoles';
|
||||
|
||||
const useCreateUserForm = (
|
||||
|
@ -5,9 +5,10 @@ import {
|
||||
styled,
|
||||
} from '@mui/material';
|
||||
import { useRoles } from 'hooks/api/getters/useRoles/useRoles';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole, PredefinedRoleType } from 'interfaces/role';
|
||||
import { RoleDescription } from '../RoleDescription/RoleDescription';
|
||||
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
|
||||
import { ROOT_ROLE_TYPE } from '@server/util/constants';
|
||||
|
||||
const StyledRoleOption = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
@ -20,18 +21,22 @@ const StyledRoleOption = styled('div')(({ theme }) => ({
|
||||
|
||||
interface IRoleSelectProps
|
||||
extends Partial<AutocompleteProps<IRole, false, false, false>> {
|
||||
type?: PredefinedRoleType;
|
||||
value: IRole | null;
|
||||
setValue: (role: IRole | null) => void;
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export const RoleSelect = ({
|
||||
type = ROOT_ROLE_TYPE,
|
||||
value,
|
||||
setValue,
|
||||
required,
|
||||
...rest
|
||||
}: IRoleSelectProps) => {
|
||||
const { roles } = useRoles();
|
||||
const { roles: rootRoles, projectRoles } = useRoles();
|
||||
|
||||
const roles = type === ROOT_ROLE_TYPE ? rootRoles : projectRoles;
|
||||
|
||||
const renderRoleOption = (
|
||||
props: React.HTMLAttributes<HTMLLIElement>,
|
||||
|
@ -16,7 +16,7 @@ import useProjectAccess, {
|
||||
ENTITY_TYPE,
|
||||
IProjectAccess,
|
||||
} from 'hooks/api/getters/useProjectAccess/useProjectAccess';
|
||||
import { IProjectRole } from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
@ -25,7 +25,6 @@ import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { IUser } from 'interfaces/user';
|
||||
import { IGroup } from 'interfaces/group';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { ProjectRoleDescription } from './ProjectRoleDescription/ProjectRoleDescription';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { GO_BACK } from 'constants/navigate';
|
||||
import {
|
||||
@ -36,6 +35,8 @@ import {
|
||||
} from 'utils/testIds';
|
||||
import { caseInsensitiveSearch } from 'utils/search';
|
||||
import { IServiceAccount } from 'interfaces/service-account';
|
||||
import { RoleSelect } from 'component/common/RoleSelect/RoleSelect';
|
||||
import { PROJECT_ROLE_TYPE } from '@server/util/constants';
|
||||
|
||||
const StyledForm = styled('form')(() => ({
|
||||
display: 'flex',
|
||||
@ -82,15 +83,6 @@ const StyledUserOption = styled('div')(({ theme }) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledRoleOption = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
'& > span:last-of-type': {
|
||||
fontSize: theme.fontSizes.smallerBody,
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
}));
|
||||
|
||||
interface IAccessOption {
|
||||
id: number;
|
||||
entity: IUser | IGroup;
|
||||
@ -103,7 +95,7 @@ interface IProjectAccessAssignProps {
|
||||
users: IUser[];
|
||||
serviceAccounts: IServiceAccount[];
|
||||
groups: IGroup[];
|
||||
roles: IProjectRole[];
|
||||
roles: IRole[];
|
||||
}
|
||||
|
||||
export const ProjectAccessAssign = ({
|
||||
@ -190,7 +182,7 @@ export const ProjectAccessAssign = ({
|
||||
id === selected?.entity.id && type === selected?.type
|
||||
)
|
||||
);
|
||||
const [role, setRole] = useState<IProjectRole | null>(
|
||||
const [role, setRole] = useState<IRole | null>(
|
||||
roles.find(({ id }) => id === selected?.entity.roleId) ?? null
|
||||
);
|
||||
|
||||
@ -317,18 +309,6 @@ export const ProjectAccessAssign = ({
|
||||
);
|
||||
};
|
||||
|
||||
const renderRoleOption = (
|
||||
props: React.HTMLAttributes<HTMLLIElement>,
|
||||
option: IProjectRole
|
||||
) => (
|
||||
<li {...props}>
|
||||
<StyledRoleOption>
|
||||
<span>{option.name}</span>
|
||||
<span>{option.description}</span>
|
||||
</StyledRoleOption>
|
||||
</li>
|
||||
);
|
||||
|
||||
const isValid = selectedOptions.length > 0 && role;
|
||||
|
||||
return (
|
||||
@ -451,29 +431,13 @@ export const ProjectAccessAssign = ({
|
||||
Select the role to assign for this project
|
||||
</StyledInputDescription>
|
||||
<StyledAutocompleteWrapper>
|
||||
<Autocomplete
|
||||
<RoleSelect
|
||||
data-testid={PA_ROLE_ID}
|
||||
size="small"
|
||||
openOnFocus
|
||||
type={PROJECT_ROLE_TYPE}
|
||||
value={role}
|
||||
onChange={(_, newValue) => setRole(newValue)}
|
||||
options={roles}
|
||||
renderOption={renderRoleOption}
|
||||
getOptionLabel={option => option.name}
|
||||
renderInput={params => (
|
||||
<TextField {...params} label="Role" />
|
||||
)}
|
||||
setValue={role => setRole(role || null)}
|
||||
/>
|
||||
</StyledAutocompleteWrapper>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(role?.id)}
|
||||
show={
|
||||
<ProjectRoleDescription
|
||||
roleId={role?.id!}
|
||||
projectId={projectId}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<StyledButtonContainer>
|
||||
|
@ -1,163 +0,0 @@
|
||||
import { styled, SxProps, Theme } from '@mui/material';
|
||||
import { ForwardedRef, forwardRef, useMemo, VFC } from 'react';
|
||||
import { useRole } from 'hooks/api/getters/useRole/useRole';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import useProjectAccess from 'hooks/api/getters/useProjectAccess/useProjectAccess';
|
||||
import { ProjectRoleDescriptionProjectPermissions } from './ProjectRoleDescriptionProjectPermissions/ProjectRoleDescriptionProjectPermissions';
|
||||
import { ProjectRoleDescriptionEnvironmentPermissions } from './ProjectRoleDescriptionEnvironmentPermissions/ProjectRoleDescriptionEnvironmentPermissions';
|
||||
|
||||
const StyledDescription = styled('div', {
|
||||
shouldForwardProp: prop =>
|
||||
prop !== 'roleId' && prop !== 'popover' && prop !== 'sx',
|
||||
})<IProjectRoleDescriptionStyleProps>(({ theme, popover }) => ({
|
||||
width: '100%',
|
||||
maxWidth: theme.spacing(50),
|
||||
padding: theme.spacing(3),
|
||||
backgroundColor: popover
|
||||
? theme.palette.background.paper
|
||||
: theme.palette.neutral.light,
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
borderRadius: theme.shape.borderRadiusMedium,
|
||||
}));
|
||||
|
||||
const StyledDescriptionBlock = styled('div')(({ theme }) => ({
|
||||
'& p:last-child': {
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledDescriptionHeader = styled('p')(({ theme }) => ({
|
||||
color: theme.palette.text.primary,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
fontWeight: theme.fontWeight.bold,
|
||||
marginBottom: theme.spacing(2),
|
||||
}));
|
||||
|
||||
const StyledDescriptionSubHeader = styled('p')(({ theme }) => ({
|
||||
color: theme.palette.text.primary,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
marginBottom: theme.spacing(1),
|
||||
}));
|
||||
|
||||
interface IProjectRoleDescriptionStyleProps {
|
||||
popover?: boolean;
|
||||
className?: string;
|
||||
sx?: SxProps<Theme>;
|
||||
}
|
||||
|
||||
interface IProjectRoleDescriptionProps
|
||||
extends IProjectRoleDescriptionStyleProps {
|
||||
roleId: number;
|
||||
projectId: string;
|
||||
}
|
||||
|
||||
export const ProjectRoleDescription: VFC<IProjectRoleDescriptionProps> =
|
||||
forwardRef(
|
||||
(
|
||||
{
|
||||
roleId,
|
||||
projectId,
|
||||
className,
|
||||
sx,
|
||||
...props
|
||||
}: IProjectRoleDescriptionProps,
|
||||
ref: ForwardedRef<HTMLDivElement>
|
||||
) => {
|
||||
const { role } = useRole(roleId.toString());
|
||||
const { access } = useProjectAccess(projectId);
|
||||
const accessRole = access?.roles.find(role => role.id === roleId);
|
||||
|
||||
const environments = useMemo(() => {
|
||||
const environments = new Set<string>();
|
||||
role?.permissions
|
||||
?.filter((permission: any) => permission.environment)
|
||||
.forEach((permission: any) => {
|
||||
environments.add(permission.environment);
|
||||
});
|
||||
return [...environments].sort();
|
||||
}, [role]);
|
||||
|
||||
const projectPermissions = useMemo(() => {
|
||||
return role?.permissions?.filter(
|
||||
(permission: any) => !permission.environment
|
||||
);
|
||||
}, [role]);
|
||||
|
||||
return (
|
||||
<StyledDescription
|
||||
className={className}
|
||||
sx={sx}
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(
|
||||
role?.permissions && role?.permissions?.length > 0
|
||||
)}
|
||||
show={
|
||||
<>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(
|
||||
projectPermissions?.length
|
||||
)}
|
||||
show={
|
||||
<>
|
||||
<StyledDescriptionHeader>
|
||||
Project permissions
|
||||
</StyledDescriptionHeader>
|
||||
<StyledDescriptionBlock>
|
||||
<ProjectRoleDescriptionProjectPermissions
|
||||
permissions={
|
||||
role?.permissions || []
|
||||
}
|
||||
/>
|
||||
</StyledDescriptionBlock>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(environments.length)}
|
||||
show={
|
||||
<>
|
||||
<StyledDescriptionHeader>
|
||||
Environment permissions
|
||||
</StyledDescriptionHeader>
|
||||
{environments.map(environment => (
|
||||
<div key={environment}>
|
||||
<StyledDescriptionSubHeader>
|
||||
{environment}
|
||||
</StyledDescriptionSubHeader>
|
||||
<StyledDescriptionBlock>
|
||||
<ProjectRoleDescriptionEnvironmentPermissions
|
||||
environment={
|
||||
environment
|
||||
}
|
||||
permissions={
|
||||
role?.permissions ||
|
||||
[]
|
||||
}
|
||||
/>
|
||||
</StyledDescriptionBlock>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
elseShow={
|
||||
<>
|
||||
<StyledDescriptionSubHeader>
|
||||
{accessRole?.name}
|
||||
</StyledDescriptionSubHeader>
|
||||
<StyledDescriptionBlock>
|
||||
{accessRole?.description}
|
||||
</StyledDescriptionBlock>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</StyledDescription>
|
||||
);
|
||||
}
|
||||
);
|
@ -1,26 +0,0 @@
|
||||
interface IProjectRoleDescriptionEnvironmentPermissionsProps {
|
||||
environment: string;
|
||||
permissions: any[];
|
||||
}
|
||||
|
||||
export const ProjectRoleDescriptionEnvironmentPermissions = ({
|
||||
environment,
|
||||
permissions,
|
||||
}: IProjectRoleDescriptionEnvironmentPermissionsProps) => (
|
||||
<>
|
||||
{[
|
||||
...new Set(
|
||||
permissions
|
||||
.filter(
|
||||
(permission: any) =>
|
||||
permission.environment === environment
|
||||
)
|
||||
.map((permission: any) => permission.displayName)
|
||||
),
|
||||
]
|
||||
.sort()
|
||||
.map((permission: any) => (
|
||||
<p key={`${environment}-${permission}`}>{permission}</p>
|
||||
))}
|
||||
</>
|
||||
);
|
@ -1,17 +0,0 @@
|
||||
interface IProjectRoleDescriptionProjectPermissionsProps {
|
||||
permissions: any[];
|
||||
}
|
||||
|
||||
export const ProjectRoleDescriptionProjectPermissions = ({
|
||||
permissions,
|
||||
}: IProjectRoleDescriptionProjectPermissionsProps) => (
|
||||
<>
|
||||
{permissions
|
||||
?.filter((permission: any) => !permission.environment)
|
||||
.map((permission: any) => permission.displayName)
|
||||
.sort()
|
||||
.map((permission: any) => (
|
||||
<p key={permission}>{permission}</p>
|
||||
))}
|
||||
</>
|
||||
);
|
@ -1,40 +0,0 @@
|
||||
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
|
||||
import { VFC } from 'react';
|
||||
import { ProjectRoleDescription } from 'component/project/ProjectAccess/ProjectAccessAssign/ProjectRoleDescription/ProjectRoleDescription';
|
||||
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||
|
||||
interface IProjectAccessRoleCellProps {
|
||||
roleId: number;
|
||||
projectId: string;
|
||||
value?: string;
|
||||
emptyText?: string;
|
||||
}
|
||||
|
||||
export const ProjectAccessRoleCell: VFC<IProjectAccessRoleCellProps> = ({
|
||||
roleId,
|
||||
projectId,
|
||||
value,
|
||||
emptyText,
|
||||
}) => {
|
||||
if (!value) return <TextCell>{emptyText}</TextCell>;
|
||||
|
||||
return (
|
||||
<TextCell>
|
||||
<TooltipLink
|
||||
tooltip={
|
||||
<ProjectRoleDescription
|
||||
roleId={roleId}
|
||||
projectId={projectId}
|
||||
popover
|
||||
/>
|
||||
}
|
||||
tooltipProps={{
|
||||
maxWidth: 500,
|
||||
maxHeight: 600,
|
||||
}}
|
||||
>
|
||||
{value}
|
||||
</TooltipLink>
|
||||
</TextCell>
|
||||
);
|
||||
};
|
@ -43,7 +43,7 @@ import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton
|
||||
import { ProjectAccessCreate } from 'component/project/ProjectAccess/ProjectAccessCreate/ProjectAccessCreate';
|
||||
import { ProjectAccessEditUser } from 'component/project/ProjectAccess/ProjectAccessEditUser/ProjectAccessEditUser';
|
||||
import { ProjectAccessEditGroup } from 'component/project/ProjectAccess/ProjectAccessEditGroup/ProjectAccessEditGroup';
|
||||
import { ProjectAccessRoleCell } from './ProjectAccessRoleCell/ProjectAccessRoleCell';
|
||||
import { RoleCell } from 'component/common/Table/cells/RoleCell/RoleCell';
|
||||
import {
|
||||
PA_ASSIGN_BUTTON_ID,
|
||||
PA_EDIT_BUTTON_ID,
|
||||
@ -168,11 +168,7 @@ export const ProjectAccessTable: VFC = () => {
|
||||
access?.roles.find(({ id }) => id === row.entity.roleId)
|
||||
?.name,
|
||||
Cell: ({ value, row: { original: row } }: any) => (
|
||||
<ProjectAccessRoleCell
|
||||
roleId={row.entity.roleId}
|
||||
projectId={projectId}
|
||||
value={value}
|
||||
/>
|
||||
<RoleCell roleId={row.entity.roleId} value={value} />
|
||||
),
|
||||
maxWidth: 125,
|
||||
filterName: 'role',
|
||||
|
@ -2,7 +2,7 @@ import useSWR, { mutate, SWRConfiguration } from 'swr';
|
||||
import { useState, useEffect, useMemo } from 'react';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||
import { IProjectRole } from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { IGroup } from 'interfaces/group';
|
||||
import { IUser } from 'interfaces/user';
|
||||
import { mapGroupUsers } from '../useGroup/useGroup';
|
||||
@ -30,7 +30,7 @@ export interface IProjectAccessGroup extends IGroup {
|
||||
export interface IProjectAccessOutput {
|
||||
users: IProjectAccessUser[];
|
||||
groups: IProjectAccessGroup[];
|
||||
roles: IProjectRole[];
|
||||
roles: IRole[];
|
||||
rows: IProjectAccess[];
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { SWRConfiguration } from 'swr';
|
||||
import { useMemo } from 'react';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||
import IRole, { IRoleWithPermissions } from 'interfaces/role';
|
||||
import { IRole, IRoleWithPermissions } from 'interfaces/role';
|
||||
import useUiConfig from '../useUiConfig/useUiConfig';
|
||||
import { useConditionalSWR } from '../useConditionalSWR/useConditionalSWR';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import IRole, { IProjectRole } from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { useMemo } from 'react';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||
@ -11,7 +11,15 @@ import {
|
||||
PREDEFINED_ROLE_TYPES,
|
||||
} from '@server/util/constants';
|
||||
|
||||
export const useRoles = () => {
|
||||
interface IUseRolesOutput {
|
||||
roles: IRole[];
|
||||
projectRoles: IRole[];
|
||||
loading: boolean;
|
||||
refetch: () => void;
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
export const useRoles = (): IUseRolesOutput => {
|
||||
const { isEnterprise, uiConfig } = useUiConfig();
|
||||
|
||||
const { data, error, mutate } = useConditionalSWR(
|
||||
@ -56,7 +64,7 @@ export const useRoles = () => {
|
||||
.filter(({ type }: IRole) =>
|
||||
PROJECT_ROLE_TYPES.includes(type)
|
||||
)
|
||||
.sort(sortRoles) ?? []) as IProjectRole[],
|
||||
.sort(sortRoles) ?? []) as IRole[],
|
||||
loading: !error && !data,
|
||||
refetch: () => mutate(),
|
||||
error,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
import { IServiceAccount } from 'interfaces/service-account';
|
||||
import { useMemo } from 'react';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
|
@ -3,7 +3,7 @@ import { useMemo } from 'react';
|
||||
import { formatApiPath } from 'utils/formatPath';
|
||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||
import { IUser } from 'interfaces/user';
|
||||
import IRole from 'interfaces/role';
|
||||
import { IRole } from 'interfaces/role';
|
||||
|
||||
interface IUseUsersOutput {
|
||||
users: IUser[];
|
||||
|
@ -1,4 +1,4 @@
|
||||
import IRole from './role';
|
||||
import { IRole } from './role';
|
||||
|
||||
export interface IProfile {
|
||||
rootRole: IRole;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import IRole from './role';
|
||||
import { IRole } from './role';
|
||||
import { IUser } from './user';
|
||||
|
||||
export interface ICreateInvitedUser {
|
||||
|
@ -5,7 +5,7 @@ export type PredefinedRoleType =
|
||||
| typeof ROOT_ROLE_TYPE
|
||||
| typeof PROJECT_ROLE_TYPE;
|
||||
|
||||
interface IRole {
|
||||
export interface IRole {
|
||||
id: number;
|
||||
name: string;
|
||||
project: string | null;
|
||||
@ -16,12 +16,3 @@ interface IRole {
|
||||
export interface IRoleWithPermissions extends IRole {
|
||||
permissions: IPermission[];
|
||||
}
|
||||
|
||||
export interface IProjectRole {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export default IRole;
|
||||
|
Loading…
Reference in New Issue
Block a user