Update 'Settings Permissions' Layout (#10997)

Fixes https://github.com/twentyhq/core-team-issues/issues/566

## Before
<img width="712" alt="Screenshot 2025-03-18 at 17 17 38"
src="https://github.com/user-attachments/assets/5c2dd8c6-e0cc-4610-b858-071d50de692c"
/>
<img width="775" alt="Screenshot 2025-03-18 at 17 17 30"
src="https://github.com/user-attachments/assets/52bdde22-f26d-4698-8138-5f2af28ddd50"
/>


## After
<img width="949" alt="Screenshot 2025-03-18 at 16 58 31"
src="https://github.com/user-attachments/assets/71b77032-0f5d-452b-b088-7af7e306d0a6"
/>
<img width="946" alt="Screenshot 2025-03-18 at 16 58 38"
src="https://github.com/user-attachments/assets/dc2ddf95-1622-419a-a35b-3037da7bdd4d"
/>
This commit is contained in:
Weiko
2025-03-18 17:48:35 +01:00
committed by GitHub
parent 6acb70d6a9
commit c3a9c85265
6 changed files with 53 additions and 56 deletions

View File

@ -11,12 +11,12 @@ import {
IconEye, IconEye,
IconHierarchy, IconHierarchy,
IconKey, IconKey,
IconLock, IconLockOpen,
IconPencil, IconPencil,
IconServer,
IconSettings, IconSettings,
IconTrash, IconTrash,
IconTrashX, IconTrashX,
IconUserCog,
IconUsers, IconUsers,
Section, Section,
} from 'twenty-ui'; } from 'twenty-ui';
@ -82,50 +82,50 @@ export const RolePermissions = ({ role }: RolePermissionsProps) => {
const settingsPermissionsConfig: RolePermissionsSettingPermission[] = [ const settingsPermissionsConfig: RolePermissionsSettingPermission[] = [
{ {
key: SettingsPermissions.API_KEYS_AND_WEBHOOKS, key: SettingsPermissions.API_KEYS_AND_WEBHOOKS,
label: 'Manage API Keys & Webhooks', name: 'API Keys & Webhooks',
type: 'Developer', description: 'Manage API keys and webhooks',
value: role.canUpdateAllSettings, value: role.canUpdateAllSettings,
Icon: IconCode, Icon: IconCode,
}, },
{ {
key: SettingsPermissions.WORKSPACE, key: SettingsPermissions.WORKSPACE,
label: 'Manage Workspace Settings', name: 'Workspace',
type: 'General', description: 'Set global workspace preferences',
value: role.canUpdateAllSettings, value: role.canUpdateAllSettings,
Icon: IconSettings, Icon: IconSettings,
}, },
{ {
key: SettingsPermissions.WORKSPACE_MEMBERS, key: SettingsPermissions.WORKSPACE_MEMBERS,
label: 'Manage Members', name: 'Users',
type: 'Members', description: 'Add or remove users',
value: role.canUpdateAllSettings, value: role.canUpdateAllSettings,
Icon: IconUsers, Icon: IconUsers,
}, },
{ {
key: SettingsPermissions.ROLES, key: SettingsPermissions.ROLES,
label: 'Manage Roles', name: 'Roles',
type: 'Members', description: 'Define user roles and access levels',
value: role.canUpdateAllSettings, value: role.canUpdateAllSettings,
Icon: IconLock, Icon: IconLockOpen,
}, },
{ {
key: SettingsPermissions.DATA_MODEL, key: SettingsPermissions.DATA_MODEL,
label: 'Manage Data Model', name: 'Data Model',
type: 'Data Model', description: 'Edit CRM data structure and fields',
value: role.canUpdateAllSettings, value: role.canUpdateAllSettings,
Icon: IconHierarchy, Icon: IconHierarchy,
}, },
{ {
key: SettingsPermissions.ADMIN_PANEL, key: SettingsPermissions.ADMIN_PANEL,
label: 'Manage Admin Panel', name: 'Admin Panel',
type: 'Admin Panel', description: 'Admin settings and system tools',
value: role.canUpdateAllSettings, value: role.canUpdateAllSettings,
Icon: IconUserCog, Icon: IconServer,
}, },
{ {
key: SettingsPermissions.SECURITY, key: SettingsPermissions.SECURITY,
label: 'Manage Security Settings', name: 'Security',
type: 'Security', description: 'Manage security policies',
value: role.canUpdateAllSettings, value: role.canUpdateAllSettings,
Icon: IconKey, Icon: IconKey,
}, },
@ -139,7 +139,11 @@ export const RolePermissions = ({ role }: RolePermissionsProps) => {
description={t`Ability to interact with each object`} description={t`Ability to interact with each object`}
/> />
<StyledTable> <StyledTable>
<RolePermissionsObjectsTableHeader allPermissions={true} /> <RolePermissionsObjectsTableHeader
allPermissions={objectPermissionsConfig.every(
(permission) => permission.value,
)}
/>
<StyledTableRows> <StyledTableRows>
{objectPermissionsConfig.map((permission) => ( {objectPermissionsConfig.map((permission) => (
<RolePermissionsObjectsTableRow <RolePermissionsObjectsTableRow

View File

@ -4,10 +4,6 @@ import styled from '@emotion/styled';
import { t } from '@lingui/core/macro'; import { t } from '@lingui/core/macro';
import { Checkbox } from 'twenty-ui'; import { Checkbox } from 'twenty-ui';
const StyledTableHeaderRow = styled(TableRow)`
display: flex;
`;
const StyledNameHeader = styled(TableHeader)` const StyledNameHeader = styled(TableHeader)`
flex: 1; flex: 1;
`; `;
@ -26,10 +22,14 @@ type RolePermissionsObjectsTableHeaderProps = {
export const RolePermissionsObjectsTableHeader = ({ export const RolePermissionsObjectsTableHeader = ({
allPermissions, allPermissions,
}: RolePermissionsObjectsTableHeaderProps) => ( }: RolePermissionsObjectsTableHeaderProps) => (
<StyledTableHeaderRow> <TableRow>
<StyledNameHeader>{t`Name`}</StyledNameHeader> <StyledNameHeader>{t`Name`}</StyledNameHeader>
<StyledActionsHeader aria-label={t`Actions`}> <StyledActionsHeader aria-label={t`Actions`}>
<Checkbox checked={allPermissions} disabled /> <Checkbox
checked={allPermissions}
indeterminate={!allPermissions}
disabled
/>
</StyledActionsHeader> </StyledActionsHeader>
</StyledTableHeaderRow> </TableRow>
); );

View File

@ -4,12 +4,6 @@ import styled from '@emotion/styled';
import { t } from '@lingui/core/macro'; import { t } from '@lingui/core/macro';
import { Checkbox } from 'twenty-ui'; import { Checkbox } from 'twenty-ui';
const StyledTableHeaderRow = styled(TableRow)`
align-items: center;
display: flex;
height: ${({ theme }) => theme.spacing(8)};
`;
const StyledNameHeader = styled(TableHeader)` const StyledNameHeader = styled(TableHeader)`
flex: 1; flex: 1;
padding-left: ${({ theme }) => theme.spacing(2)}; padding-left: ${({ theme }) => theme.spacing(2)};
@ -33,11 +27,11 @@ type RolePermissionsSettingsTableHeaderProps = {
export const RolePermissionsSettingsTableHeader = ({ export const RolePermissionsSettingsTableHeader = ({
allPermissions, allPermissions,
}: RolePermissionsSettingsTableHeaderProps) => ( }: RolePermissionsSettingsTableHeaderProps) => (
<StyledTableHeaderRow> <TableRow gridAutoColumns="3fr 4fr 24px">
<StyledNameHeader>{t`Name`}</StyledNameHeader> <StyledNameHeader>{t`Name`}</StyledNameHeader>
<StyledTypeHeader>{t`Type`}</StyledTypeHeader> <StyledTypeHeader>{t`Description`}</StyledTypeHeader>
<StyledActionsHeader aria-label={t`Actions`}> <StyledActionsHeader aria-label={t`Actions`}>
<Checkbox checked={allPermissions} disabled /> <Checkbox checked={allPermissions} disabled />
</StyledActionsHeader> </StyledActionsHeader>
</StyledTableHeaderRow> </TableRow>
); );

View File

@ -1,14 +1,15 @@
import { RolePermissionsSettingPermission } from '@/settings/roles/types/RolePermissionsSettingPermission'; import { RolePermissionsSettingPermission } from '@/settings/roles/types/RolePermissionsSettingPermission';
import { TableCell } from '@/ui/layout/table/components/TableCell'; import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow'; import { TableRow } from '@/ui/layout/table/components/TableRow';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Checkbox } from 'twenty-ui'; import { Checkbox } from 'twenty-ui';
const StyledLabel = styled.span` const StyledName = styled.span`
color: ${({ theme }) => theme.font.color.primary}; color: ${({ theme }) => theme.font.color.primary};
`; `;
const StyledType = styled(StyledLabel)` const StyledDescription = styled(StyledName)`
color: ${({ theme }) => theme.font.color.secondary}; color: ${({ theme }) => theme.font.color.secondary};
`; `;
@ -17,7 +18,6 @@ const StyledPermissionCell = styled(TableCell)`
display: flex; display: flex;
flex: 1; flex: 1;
gap: ${({ theme }) => theme.spacing(2)}; gap: ${({ theme }) => theme.spacing(2)};
padding-left: ${({ theme }) => theme.spacing(2)};
`; `;
const StyledCheckboxCell = styled(TableCell)` const StyledCheckboxCell = styled(TableCell)`
@ -27,11 +27,6 @@ const StyledCheckboxCell = styled(TableCell)`
padding-right: ${({ theme }) => theme.spacing(4)}; padding-right: ${({ theme }) => theme.spacing(4)};
`; `;
const StyledTableRow = styled(TableRow)`
align-items: center;
display: flex;
`;
const StyledIconContainer = styled.div` const StyledIconContainer = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
@ -45,20 +40,26 @@ type RolePermissionsSettingsTableRowProps = {
export const RolePermissionsSettingsTableRow = ({ export const RolePermissionsSettingsTableRow = ({
permission, permission,
}: RolePermissionsSettingsTableRowProps) => { }: RolePermissionsSettingsTableRowProps) => {
const theme = useTheme();
return ( return (
<StyledTableRow key={permission.key}> <TableRow key={permission.key} gridAutoColumns="3fr 4fr 24px">
<StyledPermissionCell>
<StyledLabel>{permission.label}</StyledLabel>
</StyledPermissionCell>
<StyledPermissionCell> <StyledPermissionCell>
<StyledIconContainer> <StyledIconContainer>
<permission.Icon size={14} /> <permission.Icon
size={16}
color={theme.font.color.primary}
stroke={theme.icon.stroke.sm}
/>
</StyledIconContainer> </StyledIconContainer>
<StyledType>{permission.type}</StyledType> <StyledName>{permission.name}</StyledName>
</StyledPermissionCell>
<StyledPermissionCell>
<StyledDescription>{permission.description}</StyledDescription>
</StyledPermissionCell> </StyledPermissionCell>
<StyledCheckboxCell> <StyledCheckboxCell>
<Checkbox checked={permission.value} disabled /> <Checkbox checked={permission.value} disabled />
</StyledCheckboxCell> </StyledCheckboxCell>
</StyledTableRow> </TableRow>
); );
}; };

View File

@ -2,8 +2,8 @@ import { IconComponent } from 'twenty-ui';
export type RolePermissionsSettingPermission = { export type RolePermissionsSettingPermission = {
key: string; key: string;
label: string; name: string;
type: string; description: string;
value: boolean; value: boolean;
Icon: IconComponent; Icon: IconComponent;
}; };

View File

@ -104,7 +104,7 @@ const StyledInput = styled.input<InputProps>`
disabled && isChecked disabled && isChecked
? theme.adaptiveColors.blue3 ? theme.adaptiveColors.blue3
: indeterminate || isChecked : indeterminate || isChecked
? theme.color.blue ? theme.adaptiveColors.blue3
: 'transparent'}; : 'transparent'};
border-color: ${({ border-color: ${({
theme, theme,
@ -114,12 +114,10 @@ const StyledInput = styled.input<InputProps>`
disabled, disabled,
}) => { }) => {
switch (true) { switch (true) {
case isChecked: case indeterminate || isChecked:
return disabled ? theme.adaptiveColors.blue3 : theme.color.blue; return disabled ? theme.adaptiveColors.blue3 : theme.color.blue;
case disabled: case disabled:
return theme.border.color.strong; return theme.border.color.strong;
case indeterminate || isChecked:
return theme.color.blue;
case variant === CheckboxVariant.Primary: case variant === CheckboxVariant.Primary:
return theme.border.color.inverted; return theme.border.color.inverted;
case variant === CheckboxVariant.Tertiary: case variant === CheckboxVariant.Tertiary: