Display "Not shared" indicator for RLS-restricted relation fields (#17713)
## Context Previously, if for example a Person had a companyId but the company relation was null due to RLS, the company column appeared empty. Now it displays ForbiddenFieldDisplay to indicate the relation exists but is inaccessible. When RLS restricts access to a related record, the frontend now shows a "Not shared" indicator (with lock icon) instead of an empty field. <img width="1275" height="399" alt="Screenshot 2026-02-04 at 15 37 53" src="https://github.com/user-attachments/assets/870306f8-f811-4dc0-b23b-a33e89043a37" />
This commit is contained in:
+11
-2
@@ -1,16 +1,25 @@
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { RecordChip } from '@/object-record/components/RecordChip';
|
||||
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
|
||||
import { ForbiddenFieldDisplay } from '@/object-record/record-field/ui/meta-types/display/components/ForbiddenFieldDisplay';
|
||||
import { useRelationToOneFieldDisplay } from '@/object-record/record-field/ui/meta-types/hooks/useRelationToOneFieldDisplay';
|
||||
import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const RelationToOneFieldDisplay = () => {
|
||||
const { fieldValue, fieldDefinition, generateRecordChipData } =
|
||||
useRelationToOneFieldDisplay();
|
||||
const {
|
||||
fieldValue,
|
||||
fieldDefinition,
|
||||
generateRecordChipData,
|
||||
foreignKeyFieldValue,
|
||||
} = useRelationToOneFieldDisplay();
|
||||
|
||||
const { disableChipClick, triggerEvent } = useContext(FieldContext);
|
||||
|
||||
if (!isDefined(fieldValue) && isDefined(foreignKeyFieldValue)) {
|
||||
return <ForbiddenFieldDisplay />;
|
||||
}
|
||||
|
||||
if (
|
||||
!isDefined(fieldValue) ||
|
||||
!isDefined(fieldDefinition?.metadata.relationObjectMetadataNameSingular)
|
||||
|
||||
+12
@@ -11,6 +11,7 @@ import { generateDefaultRecordChipData } from '@/object-metadata/utils/generateD
|
||||
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
|
||||
import { assertFieldMetadata } from '@/object-record/record-field/ui/types/guards/assertFieldMetadata';
|
||||
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
|
||||
import { getJoinColumnNameOrThrow } from '@/object-record/record-field/ui/utils/junction/getJoinColumnNameOrThrow';
|
||||
import { useRecordFieldValue } from '@/object-record/record-store/hooks/useRecordFieldValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
@@ -41,6 +42,16 @@ export const useRelationToOneFieldDisplay = () => {
|
||||
fieldDefinition,
|
||||
);
|
||||
|
||||
const joinColumnName = getJoinColumnNameOrThrow(
|
||||
fieldDefinition.metadata.settings,
|
||||
);
|
||||
|
||||
const foreignKeyFieldValue = useRecordFieldValue<string | null | undefined>(
|
||||
recordId,
|
||||
joinColumnName,
|
||||
{ type: FieldMetadataType.UUID, metadata: { fieldName: joinColumnName } },
|
||||
);
|
||||
|
||||
const maxWidthForField =
|
||||
isDefined(button) && isDefined(maxWidth)
|
||||
? maxWidth - FIELD_EDIT_BUTTON_WIDTH
|
||||
@@ -69,6 +80,7 @@ export const useRelationToOneFieldDisplay = () => {
|
||||
return {
|
||||
fieldDefinition,
|
||||
fieldValue,
|
||||
foreignKeyFieldValue,
|
||||
maxWidth: maxWidthForField,
|
||||
recordId,
|
||||
generateRecordChipData,
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { getJoinColumnName } from '@/object-record/record-field/ui/utils/junction/getJoinColumnName';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const getJoinColumnNameOrThrow = (
|
||||
settings: FieldMetadataItem['settings'],
|
||||
): string => {
|
||||
const joinColumnName = getJoinColumnName(settings);
|
||||
if (!isDefined(joinColumnName)) {
|
||||
throw new Error('Join column name is not defined');
|
||||
}
|
||||
return joinColumnName;
|
||||
};
|
||||
Reference in New Issue
Block a user