Compare commits

...

1 Commits

Author SHA1 Message Date
Weiko a051150bd9 Improve Relation picker for RLS 2026-02-23 22:22:18 +01:00
5 changed files with 53 additions and 32 deletions
@@ -3,7 +3,6 @@
import { useLingui } from '@lingui/react/macro';
import { getFilterTypeFromFieldType } from 'twenty-shared/utils';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { AdvancedFilterFieldSelectSearchInput } from '@/object-record/advanced-filter/components/AdvancedFilterFieldSelectSearchInput';
import { useAdvancedFilterFieldSelectDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown';
@@ -27,7 +26,6 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useContext } from 'react';
import { FieldMetadataType } from 'twenty-shared/types';
type SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectFieldMenuProps =
{
@@ -61,12 +59,9 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionFieldSelectF
fieldMetadataItem.label
.toLocaleLowerCase()
.includes(objectFilterDropdownSearchInput.toLocaleLowerCase()) &&
(RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
fieldMetadataItem.type,
) ||
(fieldMetadataItem.type === FieldMetadataType.RELATION &&
fieldMetadataItem.relation?.targetObjectMetadata.nameSingular ===
CoreObjectNameSingular.WorkspaceMember)),
),
)
.sort((a, b) => a.label.localeCompare(b.label));
@@ -133,6 +133,17 @@ export const SettingsRolePermissionsObjectLevelRecordLevelPermissionMeValueSelec
}
if (field.type === targetFieldType) {
if (
targetFieldType === FieldMetadataType.RELATION &&
isDefined(selectedFieldMetadataItem)
) {
return (
field.relation?.targetObjectMetadata.nameSingular ===
selectedFieldMetadataItem.relation?.targetObjectMetadata
.nameSingular
);
}
return true;
}
@@ -14,4 +14,5 @@ export const RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES = [
FieldMetadataType.EMAILS,
FieldMetadataType.FULL_NAME,
FieldMetadataType.ADDRESS,
FieldMetadataType.RELATION,
];
@@ -1,14 +1,10 @@
/* @license Enterprise */
import {
FieldMetadataType,
RecordFilterGroupLogicalOperator,
} from 'twenty-shared/types';
import { RecordFilterGroupLogicalOperator } from 'twenty-shared/types';
import { getFilterTypeFromFieldType, isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
import { useGetDefaultFieldMetadataItemForFilter } from '@/object-record/advanced-filter/hooks/useGetDefaultFieldMetadataItemForFilter';
@@ -60,13 +56,8 @@ export const useRecordLevelPermissionFilterActions = ({
const getDefaultFieldMetadataItemForRLS = () => {
const availableFieldMetadataItemsForRls =
availableFieldMetadataItemsForFilter.filter((fieldMetadataItem) => {
return (
RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
fieldMetadataItem.type,
) ||
(fieldMetadataItem.type === FieldMetadataType.RELATION &&
fieldMetadataItem.relation?.targetObjectMetadata.nameSingular ===
CoreObjectNameSingular.WorkspaceMember)
return RECORD_LEVEL_PERMISSION_PREDICATE_FIELD_TYPES.includes(
fieldMetadataItem.type,
);
});
@@ -107,22 +107,45 @@ export const buildRowLevelPermissionRecordFilter = ({
return null;
}
const rawWorkspaceMemberValue = Object.entries(workspaceMember).find(
([key]) => key === workspaceMemberFieldMetadata.name,
)?.[1];
if (workspaceMemberFieldMetadata.type === FieldMetadataType.RELATION) {
const joinColumnName = (
workspaceMemberFieldMetadata.settings as {
joinColumnName?: string;
} | null
)?.joinColumnName;
const workspaceMemberSubFieldName =
predicate.workspaceMemberSubFieldName;
if (!isDefined(joinColumnName)) {
return null;
}
if (
isDefined(workspaceMemberSubFieldName) &&
isDefined(rawWorkspaceMemberValue) &&
isCompositeFieldMetadataType(workspaceMemberFieldMetadata.type) &&
typeof rawWorkspaceMemberValue === 'object'
) {
predicateValue = rawWorkspaceMemberValue[workspaceMemberSubFieldName];
const fkValue = Object.entries(workspaceMember).find(
([key]) => key === joinColumnName,
)?.[1];
if (!isDefined(fkValue) || typeof fkValue !== 'string') {
return null;
}
predicateValue = { selectedRecordIds: [fkValue] };
} else {
predicateValue = rawWorkspaceMemberValue;
const rawWorkspaceMemberValue = Object.entries(workspaceMember).find(
([key]) => key === workspaceMemberFieldMetadata.name,
)?.[1];
const workspaceMemberSubFieldName =
predicate.workspaceMemberSubFieldName;
if (
isDefined(workspaceMemberSubFieldName) &&
isDefined(rawWorkspaceMemberValue) &&
isCompositeFieldMetadataType(workspaceMemberFieldMetadata.type) &&
typeof rawWorkspaceMemberValue === 'object'
) {
predicateValue =
rawWorkspaceMemberValue[workspaceMemberSubFieldName];
} else {
predicateValue = rawWorkspaceMemberValue;
}
}
if (!isDefined(predicateValue)) {