Fetch roles in roles settings page (#10001)
## Context Following the addition of the new Roles page, we are now fetching roles from the DB thanks to this PR #9955 ## Test <img width="1136" alt="Screenshot 2025-02-04 at 14 46 21" src="https://github.com/user-attachments/assets/2c55c4d0-ee51-47bb-8113-efce172a9365" /> --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -1,20 +1,86 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { Button, H2Title, IconPlus, Section } from 'twenty-ui';
|
||||
import {
|
||||
AppTooltip,
|
||||
Avatar,
|
||||
Button,
|
||||
H2Title,
|
||||
IconChevronRight,
|
||||
IconLock,
|
||||
IconPlus,
|
||||
IconUser,
|
||||
Section,
|
||||
TooltipDelay,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||
import { Table } from '@/ui/layout/table/components/Table';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { FeatureFlagKey, useGetRolesQuery } from '~/generated/graphql';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
|
||||
const StyledRoleTableRow = styled.div`
|
||||
const StyledTable = styled(Table)`
|
||||
margin-top: ${({ theme }) => theme.spacing(0.5)};
|
||||
`;
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.background.transparent.light};
|
||||
cursor: pointer;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledNameCell = styled.div`
|
||||
align-items: center;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const StyledAssignedCell = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
const StyledAvatarGroup = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-right: ${({ theme }) => theme.spacing(1)};
|
||||
|
||||
> * {
|
||||
border: 2px solid ${({ theme }) => theme.background.primary};
|
||||
margin-left: -8px;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledTableHeaderRow = styled(Table)`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1.5)};
|
||||
`;
|
||||
|
||||
const StyledBottomSection = styled(Section)`
|
||||
border-top: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
margin-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding-top: ${({ theme }) => theme.spacing(4)};
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
`;
|
||||
|
||||
const StyledIconChevronRight = styled(IconChevronRight)`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
`;
|
||||
|
||||
const StyledAvatarContainer = styled.div`
|
||||
border: 0px;
|
||||
`;
|
||||
|
||||
export const SettingsRoles = () => {
|
||||
@ -22,22 +88,9 @@ export const SettingsRoles = () => {
|
||||
const isPermissionsEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IsPermissionsEnabled,
|
||||
);
|
||||
const theme = useTheme();
|
||||
|
||||
const GET_SETTINGS_ROLE_TABLE_METADATA = {
|
||||
tableId: 'settingsRole',
|
||||
fields: [
|
||||
{
|
||||
fieldName: 'name',
|
||||
fieldLabel: t`Name`,
|
||||
align: 'left' as const,
|
||||
},
|
||||
{
|
||||
fieldName: 'assignedTo',
|
||||
fieldLabel: t`Assigned to`,
|
||||
align: 'left' as const,
|
||||
},
|
||||
],
|
||||
};
|
||||
const { data: rolesData, loading: isRolesLoading } = useGetRolesQuery();
|
||||
|
||||
if (!isPermissionsEnabled) {
|
||||
return null;
|
||||
@ -46,14 +99,6 @@ export const SettingsRoles = () => {
|
||||
return (
|
||||
<SubMenuTopBarContainer
|
||||
title={t`Roles`}
|
||||
actionButton={
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title={t`New Role`}
|
||||
accent="blue"
|
||||
size="small"
|
||||
/>
|
||||
}
|
||||
links={[
|
||||
{
|
||||
children: <Trans>Workspace</Trans>,
|
||||
@ -68,21 +113,80 @@ export const SettingsRoles = () => {
|
||||
title={t`All roles`}
|
||||
description={t`Assign roles to specify each member's access permissions`}
|
||||
/>
|
||||
|
||||
<Table>
|
||||
<StyledRoleTableRow>
|
||||
{GET_SETTINGS_ROLE_TABLE_METADATA.fields.map(
|
||||
(settingsRoleTableMetadataField) => (
|
||||
<TableHeader
|
||||
key={settingsRoleTableMetadataField.fieldName}
|
||||
align={settingsRoleTableMetadataField.align}
|
||||
>
|
||||
{settingsRoleTableMetadataField.fieldLabel}
|
||||
</TableHeader>
|
||||
),
|
||||
)}
|
||||
</StyledRoleTableRow>
|
||||
</Table>
|
||||
<StyledTable>
|
||||
<StyledTableHeaderRow>
|
||||
<TableRow>
|
||||
<TableHeader>
|
||||
<Trans>Name</Trans>
|
||||
</TableHeader>
|
||||
<TableHeader align={'right'}>
|
||||
<Trans>Assigned to</Trans>
|
||||
</TableHeader>
|
||||
<TableHeader align={'right'}></TableHeader>
|
||||
</TableRow>
|
||||
</StyledTableHeaderRow>
|
||||
{!isRolesLoading &&
|
||||
rolesData?.getRoles.map((role) => (
|
||||
<StyledTableRow key={role.id}>
|
||||
<TableCell>
|
||||
<StyledNameCell>
|
||||
<IconUser size={theme.icon.size.md} />
|
||||
{role.label}
|
||||
{!role.isEditable && (
|
||||
<IconLock size={theme.icon.size.sm} />
|
||||
)}
|
||||
</StyledNameCell>
|
||||
</TableCell>
|
||||
<TableCell align={'right'}>
|
||||
<StyledAssignedCell>
|
||||
<StyledAvatarGroup>
|
||||
{role.workspaceMembers
|
||||
.slice(0, 5)
|
||||
.map((workspaceMember) => (
|
||||
<>
|
||||
<StyledAvatarContainer
|
||||
key={workspaceMember.id}
|
||||
id={`avatar-${workspaceMember.id}`}
|
||||
>
|
||||
<Avatar
|
||||
avatarUrl={workspaceMember.avatarUrl}
|
||||
placeholderColorSeed={workspaceMember.id}
|
||||
placeholder={
|
||||
workspaceMember.name.firstName ?? ''
|
||||
}
|
||||
type="rounded"
|
||||
size="sm"
|
||||
/>
|
||||
</StyledAvatarContainer>
|
||||
<AppTooltip
|
||||
anchorSelect={`#avatar-${workspaceMember.id}`}
|
||||
content={`${workspaceMember.name.firstName} ${workspaceMember.name.lastName}`}
|
||||
noArrow
|
||||
place="top"
|
||||
positionStrategy="fixed"
|
||||
delay={TooltipDelay.shortDelay}
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
</StyledAvatarGroup>
|
||||
{role.workspaceMembers.length}
|
||||
</StyledAssignedCell>
|
||||
</TableCell>
|
||||
<TableCell align={'right'}>
|
||||
<StyledIconChevronRight size={theme.icon.size.md} />
|
||||
</TableCell>
|
||||
</StyledTableRow>
|
||||
))}
|
||||
</StyledTable>
|
||||
<StyledBottomSection>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title={t`Create Role`}
|
||||
variant="secondary"
|
||||
size="small"
|
||||
soon
|
||||
/>
|
||||
</StyledBottomSection>
|
||||
</Section>
|
||||
</SettingsPageContainer>
|
||||
</SubMenuTopBarContainer>
|
||||
|
||||
Reference in New Issue
Block a user