Field permission CRUD front-end implementation (#13524)

This PR implements what's needed to edit field permissions on a role.

Field permissions that aren't useful are kept in the database to avoid
the overhead of adding cleaning logics both in front end and back end.
They just won't be taken into account if object permission doesn't allow
it.

In this PR we also handle the case were there's no object permission
override but where there are only field permission overrides, which can
happen if an object inherits from a "all object can read" but restricts
read only on some fields.

<img width="547" height="642" alt="image"
src="https://github.com/user-attachments/assets/77d81f89-4af9-42b6-97f3-fae3a6ba1eeb"
/>


<img width="590" height="912" alt="image"
src="https://github.com/user-attachments/assets/69fab8ee-7252-401a-bc6f-8a8b7c7f6bc4"
/>

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

This PR lowers unit test coverage because the essential unit tests for
this PR have been written and writing more tests would not be a great
tradeoff for this feature which has already taken a lot of efforts.
This commit is contained in:
Lucas Bordeau
2025-08-05 11:50:23 +02:00
committed by GitHub
parent 497fc2c0b2
commit 04ed843aaf
59 changed files with 2358 additions and 527 deletions
@@ -2,9 +2,9 @@ import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { Link } from 'react-router-dom';
import { SettingsFieldType } from '@/settings/data-model/types/SettingsFieldType';
import { getSettingsFieldTypeConfig } from '@/settings/data-model/utils/getSettingsFieldTypeConfig';
import { IconComponent, IconTwentyStar } from 'twenty-ui/display';
import { SettingsFieldType } from '@/settings/data-model/types/SettingsFieldType';
type SettingsObjectFieldDataTypeProps = {
to?: string;
@@ -10,6 +10,7 @@ import { SettingsObjectFieldActiveActionDropdown } from '@/settings/data-model/o
import { SettingsObjectFieldInactiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown';
import { settingsObjectFieldsFamilyState } from '@/settings/data-model/object-details/states/settingsObjectFieldsFamilyState';
import { isFieldTypeSupportedInSettings } from '@/settings/data-model/utils/isFieldTypeSupportedInSettings';
import { FIELD_LEVEL_PERMISSION_TABLE_GRID_TEMPLATE_COLUMNS } from '@/settings/roles/role-permissions/object-level-permissions/field-permissions/constants/FieldLevelPermissionTableGridTemplateColumns';
import { SettingsPath } from '@/types/SettingsPath';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
@@ -39,7 +40,7 @@ type SettingsObjectFieldItemTableRowProps = {
};
export const StyledObjectFieldTableRow = styled(TableRow)`
grid-template-columns: 180px 148px 148px 36px;
grid-template-columns: ${FIELD_LEVEL_PERMISSION_TABLE_GRID_TEMPLATE_COLUMNS};
`;
const StyledNameTableCell = styled(TableCell)`