Add relations to notes/tasks list view (#6971)
<img width="664" alt="Screenshot 2024-09-10 at 17 00 11" src="https://github.com/user-attachments/assets/37132805-ff67-4d28-b664-b03da680e166"> --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -1,3 +1,7 @@
|
||||
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
||||
import { NoteTarget } from '@/activities/types/NoteTarget';
|
||||
import { TaskTarget } from '@/activities/types/TaskTarget';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { RecordChip } from '@/object-record/components/RecordChip';
|
||||
import { useFieldFocus } from '@/object-record/record-field/hooks/useFieldFocus';
|
||||
import { useRelationFromManyFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useRelationFromManyFieldDisplay';
|
||||
@ -7,24 +11,74 @@ export const RelationFromManyFieldDisplay = () => {
|
||||
const { fieldValue, fieldDefinition } = useRelationFromManyFieldDisplay();
|
||||
const { isFocused } = useFieldFocus();
|
||||
|
||||
const { fieldName, objectMetadataNameSingular } = fieldDefinition.metadata;
|
||||
|
||||
const relationObjectNameSingular =
|
||||
fieldDefinition?.metadata.relationObjectMetadataNameSingular;
|
||||
|
||||
const { activityTargetObjectRecords } = useActivityTargetObjectRecords(
|
||||
undefined,
|
||||
fieldValue as NoteTarget[] | TaskTarget[],
|
||||
);
|
||||
|
||||
if (!fieldValue || !relationObjectNameSingular) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ExpandableList isChipCountDisplayed={isFocused}>
|
||||
{fieldValue.map((record) => {
|
||||
return (
|
||||
const isRelationFromActivityTargets =
|
||||
(fieldName === 'noteTargets' &&
|
||||
objectMetadataNameSingular === CoreObjectNameSingular.Note) ||
|
||||
(fieldName === 'taskTargets' &&
|
||||
objectMetadataNameSingular === CoreObjectNameSingular.Task);
|
||||
|
||||
const isRelationFromManyActivities =
|
||||
(fieldName === 'noteTargets' &&
|
||||
objectMetadataNameSingular !== CoreObjectNameSingular.Note) ||
|
||||
(fieldName === 'taskTargets' &&
|
||||
objectMetadataNameSingular !== CoreObjectNameSingular.Task);
|
||||
|
||||
if (isRelationFromManyActivities) {
|
||||
const objectNameSingular =
|
||||
fieldName === 'noteTargets'
|
||||
? CoreObjectNameSingular.Note
|
||||
: CoreObjectNameSingular.Task;
|
||||
|
||||
const relationFieldName = fieldName === 'noteTargets' ? 'note' : 'task';
|
||||
|
||||
return (
|
||||
<ExpandableList isChipCountDisplayed={isFocused}>
|
||||
{fieldValue.map((record) => (
|
||||
<RecordChip
|
||||
key={record.id}
|
||||
objectNameSingular={objectNameSingular}
|
||||
record={record[relationFieldName]}
|
||||
/>
|
||||
))}
|
||||
</ExpandableList>
|
||||
);
|
||||
} else if (isRelationFromActivityTargets) {
|
||||
return (
|
||||
<ExpandableList isChipCountDisplayed={isFocused}>
|
||||
{activityTargetObjectRecords.map((record) => (
|
||||
<RecordChip
|
||||
key={record.targetObject.id}
|
||||
objectNameSingular={record.targetObjectMetadataItem.nameSingular}
|
||||
record={record.targetObject}
|
||||
/>
|
||||
))}
|
||||
</ExpandableList>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<ExpandableList isChipCountDisplayed={isFocused}>
|
||||
{fieldValue.map((record) => (
|
||||
<RecordChip
|
||||
key={record.id}
|
||||
objectNameSingular={relationObjectNameSingular}
|
||||
record={record}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ExpandableList>
|
||||
);
|
||||
))}
|
||||
</ExpandableList>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { useEffect } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { ComponentDecorator } from 'twenty-ui';
|
||||
|
||||
@ -94,9 +94,10 @@ type Story = StoryObj<typeof RelationFromManyFieldDisplay>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
// TODO: optimize this component once we have morph many
|
||||
export const Performance = getProfilingStory({
|
||||
componentName: 'RelationFromManyFieldDisplay',
|
||||
averageThresholdInMs: 0.5,
|
||||
averageThresholdInMs: 1,
|
||||
numberOfRuns: 20,
|
||||
numberOfTestsPerRun: 100,
|
||||
});
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { getObjectMetadataIdentifierFields } from '@/object-metadata/utils/getObjectMetadataIdentifierFields';
|
||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
||||
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
@ -27,6 +30,16 @@ export const useRecordTableRecordGqlFields = ({
|
||||
identifierQueryFields[imageIdentifierFieldMetadataItem.name] = true;
|
||||
}
|
||||
|
||||
const { objectMetadataItem: noteTargetObjectMetadataItem } =
|
||||
useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.NoteTarget,
|
||||
});
|
||||
|
||||
const { objectMetadataItem: taskTargetObjectMetadataItem } =
|
||||
useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.TaskTarget,
|
||||
});
|
||||
|
||||
const recordGqlFields: Record<string, any> = {
|
||||
id: true,
|
||||
...Object.fromEntries(
|
||||
@ -34,18 +47,12 @@ export const useRecordTableRecordGqlFields = ({
|
||||
),
|
||||
...identifierQueryFields,
|
||||
position: true,
|
||||
noteTargets: {
|
||||
note: {
|
||||
id: true,
|
||||
title: true,
|
||||
},
|
||||
},
|
||||
taskTargets: {
|
||||
task: {
|
||||
id: true,
|
||||
title: true,
|
||||
},
|
||||
},
|
||||
noteTargets: generateDepthOneRecordGqlFields({
|
||||
objectMetadataItem: noteTargetObjectMetadataItem,
|
||||
}),
|
||||
taskTargets: generateDepthOneRecordGqlFields({
|
||||
objectMetadataItem: taskTargetObjectMetadataItem,
|
||||
}),
|
||||
};
|
||||
|
||||
return recordGqlFields;
|
||||
|
||||
Reference in New Issue
Block a user