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:
@ -7,7 +7,6 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
|
|||||||
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
|
||||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||||
import { JestObjectMetadataItemSetter } from '~/testing/jest/JestObjectMetadataItemSetter';
|
import { JestObjectMetadataItemSetter } from '~/testing/jest/JestObjectMetadataItemSetter';
|
||||||
@ -128,10 +127,8 @@ describe('useActivityTargetObjectRecords', () => {
|
|||||||
objectMetadataItemsState,
|
objectMetadataItemsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { activityTargetObjectRecords } = useActivityTargetObjectRecords(
|
const { activityTargetObjectRecords } =
|
||||||
task,
|
useActivityTargetObjectRecords(task);
|
||||||
CoreObjectNameSingular.Task,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activityTargetObjectRecords,
|
activityTargetObjectRecords,
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useApolloClient } from '@apollo/client';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { Nullable } from 'twenty-ui';
|
import { Nullable } from 'twenty-ui';
|
||||||
|
|
||||||
@ -7,46 +6,37 @@ import { Note } from '@/activities/types/Note';
|
|||||||
import { NoteTarget } from '@/activities/types/NoteTarget';
|
import { NoteTarget } from '@/activities/types/NoteTarget';
|
||||||
import { Task } from '@/activities/types/Task';
|
import { Task } from '@/activities/types/Task';
|
||||||
import { TaskTarget } from '@/activities/types/TaskTarget';
|
import { TaskTarget } from '@/activities/types/TaskTarget';
|
||||||
import { getJoinObjectNameSingular } from '@/activities/utils/getJoinObjectNameSingular';
|
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
export const useActivityTargetObjectRecords = (
|
export const useActivityTargetObjectRecords = (
|
||||||
activity: Task | Note,
|
activity?: Task | Note,
|
||||||
objectNameSingular: CoreObjectNameSingular,
|
activityTargets?: NoteTarget[] | TaskTarget[],
|
||||||
) => {
|
) => {
|
||||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||||
|
|
||||||
const activityTargets =
|
if (!isDefined(activity) && !isDefined(activityTargets)) {
|
||||||
'noteTargets' in activity && activity.noteTargets
|
return { activityTargetObjectRecords: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
const targets = activityTargets
|
||||||
|
? activityTargets
|
||||||
|
: activity && 'noteTargets' in activity && activity.noteTargets
|
||||||
? activity.noteTargets
|
? activity.noteTargets
|
||||||
: 'taskTargets' in activity && activity.taskTargets
|
: activity && 'taskTargets' in activity && activity.taskTargets
|
||||||
? activity.taskTargets
|
? activity.taskTargets
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const getRecordFromCache = useGetRecordFromCache({
|
const activityTargetObjectRecords = targets
|
||||||
objectNameSingular: getJoinObjectNameSingular(objectNameSingular),
|
|
||||||
});
|
|
||||||
|
|
||||||
const apolloClient = useApolloClient();
|
|
||||||
|
|
||||||
const activityTargetObjectRecords = activityTargets
|
|
||||||
.map<Nullable<ActivityTargetWithTargetRecord>>((activityTarget) => {
|
.map<Nullable<ActivityTargetWithTargetRecord>>((activityTarget) => {
|
||||||
const activityTargetFromCache = getRecordFromCache<
|
if (!isDefined(activityTarget)) {
|
||||||
NoteTarget | TaskTarget
|
throw new Error(`Cannot find activity target`);
|
||||||
>(activityTarget.id, apolloClient.cache);
|
|
||||||
|
|
||||||
if (!isDefined(activityTargetFromCache)) {
|
|
||||||
throw new Error(
|
|
||||||
`Cannot find activity target ${activityTarget.id} in cache, this shouldn't happen.`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const correspondingObjectMetadataItem = objectMetadataItems.find(
|
const correspondingObjectMetadataItem = objectMetadataItems.find(
|
||||||
(objectMetadataItem) =>
|
(objectMetadataItem) =>
|
||||||
isDefined(activityTargetFromCache[objectMetadataItem.nameSingular]) &&
|
isDefined(activityTarget[objectMetadataItem.nameSingular]) &&
|
||||||
![CoreObjectNameSingular.Note, CoreObjectNameSingular.Task].includes(
|
![CoreObjectNameSingular.Note, CoreObjectNameSingular.Task].includes(
|
||||||
objectMetadataItem.nameSingular as CoreObjectNameSingular,
|
objectMetadataItem.nameSingular as CoreObjectNameSingular,
|
||||||
),
|
),
|
||||||
@ -57,7 +47,7 @@ export const useActivityTargetObjectRecords = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const targetObjectRecord =
|
const targetObjectRecord =
|
||||||
activityTargetFromCache[correspondingObjectMetadataItem.nameSingular];
|
activityTarget[correspondingObjectMetadataItem.nameSingular];
|
||||||
|
|
||||||
if (!targetObjectRecord) {
|
if (!targetObjectRecord) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -66,7 +56,7 @@ export const useActivityTargetObjectRecords = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activityTarget: activityTargetFromCache ?? activityTarget,
|
activityTarget,
|
||||||
targetObject: targetObjectRecord ?? undefined,
|
targetObject: targetObjectRecord ?? undefined,
|
||||||
targetObjectMetadataItem: correspondingObjectMetadataItem,
|
targetObjectMetadataItem: correspondingObjectMetadataItem,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,10 +35,8 @@ export const ActivityTargetsInlineCell = ({
|
|||||||
readonly,
|
readonly,
|
||||||
activityObjectNameSingular,
|
activityObjectNameSingular,
|
||||||
}: ActivityTargetsInlineCellProps) => {
|
}: ActivityTargetsInlineCellProps) => {
|
||||||
const { activityTargetObjectRecords } = useActivityTargetObjectRecords(
|
const { activityTargetObjectRecords } =
|
||||||
activity,
|
useActivityTargetObjectRecords(activity);
|
||||||
activityObjectNameSingular,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { closeInlineCell } = useInlineCell();
|
const { closeInlineCell } = useInlineCell();
|
||||||
|
|
||||||
|
|||||||
@ -16,14 +16,6 @@ export const getLabelIdentifierFieldValue = (
|
|||||||
return `${record.name?.firstName ?? ''} ${record.name?.lastName ?? ''}`;
|
return `${record.name?.firstName ?? ''} ${record.name?.lastName ?? ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectNameSingular === CoreObjectNameSingular.NoteTarget) {
|
|
||||||
return record.note?.title ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (objectNameSingular === CoreObjectNameSingular.TaskTarget) {
|
|
||||||
return record.task?.title ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(labelIdentifierFieldMetadataItem?.name)) {
|
if (isDefined(labelIdentifierFieldMetadataItem?.name)) {
|
||||||
return String(record[labelIdentifierFieldMetadataItem.name]);
|
return String(record[labelIdentifierFieldMetadataItem.name]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 { RecordChip } from '@/object-record/components/RecordChip';
|
||||||
import { useFieldFocus } from '@/object-record/record-field/hooks/useFieldFocus';
|
import { useFieldFocus } from '@/object-record/record-field/hooks/useFieldFocus';
|
||||||
import { useRelationFromManyFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useRelationFromManyFieldDisplay';
|
import { useRelationFromManyFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useRelationFromManyFieldDisplay';
|
||||||
@ -7,24 +11,74 @@ export const RelationFromManyFieldDisplay = () => {
|
|||||||
const { fieldValue, fieldDefinition } = useRelationFromManyFieldDisplay();
|
const { fieldValue, fieldDefinition } = useRelationFromManyFieldDisplay();
|
||||||
const { isFocused } = useFieldFocus();
|
const { isFocused } = useFieldFocus();
|
||||||
|
|
||||||
|
const { fieldName, objectMetadataNameSingular } = fieldDefinition.metadata;
|
||||||
|
|
||||||
const relationObjectNameSingular =
|
const relationObjectNameSingular =
|
||||||
fieldDefinition?.metadata.relationObjectMetadataNameSingular;
|
fieldDefinition?.metadata.relationObjectMetadataNameSingular;
|
||||||
|
|
||||||
|
const { activityTargetObjectRecords } = useActivityTargetObjectRecords(
|
||||||
|
undefined,
|
||||||
|
fieldValue as NoteTarget[] | TaskTarget[],
|
||||||
|
);
|
||||||
|
|
||||||
if (!fieldValue || !relationObjectNameSingular) {
|
if (!fieldValue || !relationObjectNameSingular) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const isRelationFromActivityTargets =
|
||||||
<ExpandableList isChipCountDisplayed={isFocused}>
|
(fieldName === 'noteTargets' &&
|
||||||
{fieldValue.map((record) => {
|
objectMetadataNameSingular === CoreObjectNameSingular.Note) ||
|
||||||
return (
|
(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
|
<RecordChip
|
||||||
key={record.id}
|
key={record.id}
|
||||||
objectNameSingular={relationObjectNameSingular}
|
objectNameSingular={relationObjectNameSingular}
|
||||||
record={record}
|
record={record}
|
||||||
/>
|
/>
|
||||||
);
|
))}
|
||||||
})}
|
</ExpandableList>
|
||||||
</ExpandableList>
|
);
|
||||||
);
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { Meta, StoryObj } from '@storybook/react';
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { useEffect } from 'react';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
import { ComponentDecorator } from 'twenty-ui';
|
import { ComponentDecorator } from 'twenty-ui';
|
||||||
|
|
||||||
@ -94,9 +94,10 @@ type Story = StoryObj<typeof RelationFromManyFieldDisplay>;
|
|||||||
|
|
||||||
export const Default: Story = {};
|
export const Default: Story = {};
|
||||||
|
|
||||||
|
// TODO: optimize this component once we have morph many
|
||||||
export const Performance = getProfilingStory({
|
export const Performance = getProfilingStory({
|
||||||
componentName: 'RelationFromManyFieldDisplay',
|
componentName: 'RelationFromManyFieldDisplay',
|
||||||
averageThresholdInMs: 0.5,
|
averageThresholdInMs: 1,
|
||||||
numberOfRuns: 20,
|
numberOfRuns: 20,
|
||||||
numberOfTestsPerRun: 100,
|
numberOfTestsPerRun: 100,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
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 { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { getObjectMetadataIdentifierFields } from '@/object-metadata/utils/getObjectMetadataIdentifierFields';
|
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 { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
@ -27,6 +30,16 @@ export const useRecordTableRecordGqlFields = ({
|
|||||||
identifierQueryFields[imageIdentifierFieldMetadataItem.name] = true;
|
identifierQueryFields[imageIdentifierFieldMetadataItem.name] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { objectMetadataItem: noteTargetObjectMetadataItem } =
|
||||||
|
useObjectMetadataItem({
|
||||||
|
objectNameSingular: CoreObjectNameSingular.NoteTarget,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { objectMetadataItem: taskTargetObjectMetadataItem } =
|
||||||
|
useObjectMetadataItem({
|
||||||
|
objectNameSingular: CoreObjectNameSingular.TaskTarget,
|
||||||
|
});
|
||||||
|
|
||||||
const recordGqlFields: Record<string, any> = {
|
const recordGqlFields: Record<string, any> = {
|
||||||
id: true,
|
id: true,
|
||||||
...Object.fromEntries(
|
...Object.fromEntries(
|
||||||
@ -34,18 +47,12 @@ export const useRecordTableRecordGqlFields = ({
|
|||||||
),
|
),
|
||||||
...identifierQueryFields,
|
...identifierQueryFields,
|
||||||
position: true,
|
position: true,
|
||||||
noteTargets: {
|
noteTargets: generateDepthOneRecordGqlFields({
|
||||||
note: {
|
objectMetadataItem: noteTargetObjectMetadataItem,
|
||||||
id: true,
|
}),
|
||||||
title: true,
|
taskTargets: generateDepthOneRecordGqlFields({
|
||||||
},
|
objectMetadataItem: taskTargetObjectMetadataItem,
|
||||||
},
|
}),
|
||||||
taskTargets: {
|
|
||||||
task: {
|
|
||||||
id: true,
|
|
||||||
title: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return recordGqlFields;
|
return recordGqlFields;
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export const notesAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
|
||||||
NOTE_STANDARD_FIELD_IDS.body
|
NOTE_STANDARD_FIELD_IDS.noteTargets
|
||||||
],
|
],
|
||||||
position: 1,
|
position: 1,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
@ -39,7 +39,7 @@ export const notesAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
|
||||||
NOTE_STANDARD_FIELD_IDS.createdBy
|
NOTE_STANDARD_FIELD_IDS.body
|
||||||
],
|
],
|
||||||
position: 2,
|
position: 2,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
@ -48,12 +48,21 @@ export const notesAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
|
||||||
BASE_OBJECT_STANDARD_FIELD_IDS.createdAt
|
NOTE_STANDARD_FIELD_IDS.createdBy
|
||||||
],
|
],
|
||||||
position: 3,
|
position: 3,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
size: 150,
|
size: 150,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldMetadataId:
|
||||||
|
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[
|
||||||
|
BASE_OBJECT_STANDARD_FIELD_IDS.createdAt
|
||||||
|
],
|
||||||
|
position: 4,
|
||||||
|
isVisible: true,
|
||||||
|
size: 150,
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
TODO: Add later, since we don't have real-time it probably doesn't work well?
|
TODO: Add later, since we don't have real-time it probably doesn't work well?
|
||||||
{
|
{
|
||||||
|
|||||||
@ -49,7 +49,7 @@ export const tasksAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||||
TASK_STANDARD_FIELD_IDS.createdBy
|
TASK_STANDARD_FIELD_IDS.taskTargets
|
||||||
],
|
],
|
||||||
position: 3,
|
position: 3,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
@ -58,7 +58,7 @@ export const tasksAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||||
TASK_STANDARD_FIELD_IDS.dueAt
|
TASK_STANDARD_FIELD_IDS.createdBy
|
||||||
],
|
],
|
||||||
position: 4,
|
position: 4,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
@ -67,7 +67,7 @@ export const tasksAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||||
TASK_STANDARD_FIELD_IDS.assignee
|
TASK_STANDARD_FIELD_IDS.dueAt
|
||||||
],
|
],
|
||||||
position: 5,
|
position: 5,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
@ -76,7 +76,7 @@ export const tasksAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||||
TASK_STANDARD_FIELD_IDS.body
|
TASK_STANDARD_FIELD_IDS.assignee
|
||||||
],
|
],
|
||||||
position: 6,
|
position: 6,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
@ -85,12 +85,21 @@ export const tasksAllView = async (
|
|||||||
{
|
{
|
||||||
fieldMetadataId:
|
fieldMetadataId:
|
||||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||||
BASE_OBJECT_STANDARD_FIELD_IDS.createdAt
|
TASK_STANDARD_FIELD_IDS.body
|
||||||
],
|
],
|
||||||
position: 7,
|
position: 7,
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
size: 150,
|
size: 150,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldMetadataId:
|
||||||
|
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||||
|
BASE_OBJECT_STANDARD_FIELD_IDS.createdAt
|
||||||
|
],
|
||||||
|
position: 8,
|
||||||
|
isVisible: true,
|
||||||
|
size: 150,
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
TODO: Add later, since we don't have real-time it probably doesn't work well?
|
TODO: Add later, since we don't have real-time it probably doesn't work well?
|
||||||
{
|
{
|
||||||
|
|||||||
@ -78,15 +78,14 @@ export class NoteWorkspaceEntity extends BaseWorkspaceEntity {
|
|||||||
|
|
||||||
@WorkspaceRelation({
|
@WorkspaceRelation({
|
||||||
standardId: NOTE_STANDARD_FIELD_IDS.noteTargets,
|
standardId: NOTE_STANDARD_FIELD_IDS.noteTargets,
|
||||||
label: 'Targets',
|
label: 'Relations',
|
||||||
description: 'Note targets',
|
description: 'Note targets',
|
||||||
icon: 'IconCheckbox',
|
icon: 'IconArrowUpRight',
|
||||||
type: RelationMetadataType.ONE_TO_MANY,
|
type: RelationMetadataType.ONE_TO_MANY,
|
||||||
inverseSideTarget: () => NoteTargetWorkspaceEntity,
|
inverseSideTarget: () => NoteTargetWorkspaceEntity,
|
||||||
onDelete: RelationOnDeleteAction.SET_NULL,
|
onDelete: RelationOnDeleteAction.SET_NULL,
|
||||||
})
|
})
|
||||||
@WorkspaceIsNullable()
|
@WorkspaceIsNullable()
|
||||||
@WorkspaceIsSystem()
|
|
||||||
noteTargets: Relation<NoteTargetWorkspaceEntity[]>;
|
noteTargets: Relation<NoteTargetWorkspaceEntity[]>;
|
||||||
|
|
||||||
@WorkspaceRelation({
|
@WorkspaceRelation({
|
||||||
|
|||||||
@ -116,15 +116,14 @@ export class TaskWorkspaceEntity extends BaseWorkspaceEntity {
|
|||||||
|
|
||||||
@WorkspaceRelation({
|
@WorkspaceRelation({
|
||||||
standardId: TASK_STANDARD_FIELD_IDS.taskTargets,
|
standardId: TASK_STANDARD_FIELD_IDS.taskTargets,
|
||||||
label: 'Targets',
|
label: 'Relations',
|
||||||
description: 'Task targets',
|
description: 'Task targets',
|
||||||
icon: 'IconCheckbox',
|
icon: 'IconArrowUpRight',
|
||||||
type: RelationMetadataType.ONE_TO_MANY,
|
type: RelationMetadataType.ONE_TO_MANY,
|
||||||
inverseSideTarget: () => TaskTargetWorkspaceEntity,
|
inverseSideTarget: () => TaskTargetWorkspaceEntity,
|
||||||
onDelete: RelationOnDeleteAction.SET_NULL,
|
onDelete: RelationOnDeleteAction.SET_NULL,
|
||||||
})
|
})
|
||||||
@WorkspaceIsNullable()
|
@WorkspaceIsNullable()
|
||||||
@WorkspaceIsSystem()
|
|
||||||
taskTargets: Relation<TaskTargetWorkspaceEntity[]>;
|
taskTargets: Relation<TaskTargetWorkspaceEntity[]>;
|
||||||
|
|
||||||
@WorkspaceRelation({
|
@WorkspaceRelation({
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export class ViewService {
|
|||||||
fieldId: string;
|
fieldId: string;
|
||||||
viewsIds: string[];
|
viewsIds: string[];
|
||||||
positions?: {
|
positions?: {
|
||||||
[key: string]: number;
|
[viewId: string]: number;
|
||||||
}[];
|
}[];
|
||||||
size?: number;
|
size?: number;
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
Reference in New Issue
Block a user