From 80c0fc7ff108d61c0e8d89fd334da64bd224f7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Wed, 31 Jul 2024 15:36:11 +0200 Subject: [PATCH] Activity as standard object (#6219) In this PR I layout the first steps to migrate Activity to a traditional Standard objects Since this is a big transition, I'd rather split it into several deployments / PRs image --------- Co-authored-by: Charles Bochet Co-authored-by: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Co-authored-by: Weiko Co-authored-by: Faisal-imtiyaz123 <142205282+Faisal-imtiyaz123@users.noreply.github.com> Co-authored-by: Prateek Jain --- packages/twenty-front/.eslintrc.cjs | 1 + packages/twenty-front/src/App.tsx | 2 - .../effect-components/PageChangeEffect.tsx | 8 +- .../src/generated-metadata/graphql.ts | 1 + .../twenty-front/src/generated/graphql.tsx | 1 + .../modules/activities/comment/Comment.tsx | 37 - .../activities/comment/CommentCounter.tsx | 27 - .../activities/comment/CommentHeader.tsx | 85 - .../comment/__stories__/Comment.stories.tsx | 54 - .../__stories__/CommentHeader.stories.tsx | 108 - .../comment/__stories__/mock-comment.ts | 55 - .../components/ActivityComments.tsx | 129 - .../components/ActivityCreationDate.tsx | 43 - .../activities/components/ActivityEditor.tsx | 89 - .../components/ActivityEditorEffect.tsx | 102 - .../components/ActivityEditorFields.tsx | 115 - .../activities/components/ActivityTitle.tsx | 199 - .../components/ActivityTitleEffect.tsx | 28 - .../components/ActivityTypeDropdown.tsx | 40 - ...ivityBodyEditor.tsx => RichTextEditor.tsx} | 27 +- .../CreateOneActivityOperationSignature.ts | 34 - ...ateOneActivityOperationSignatureFactory.ts | 40 + ...findActivitiesOperationSignatureFactory.ts | 44 +- ...ctivityTargetsOperationSignatureFactory.ts | 11 +- .../hooks/__tests__/useActivities.test.tsx | 31 +- .../useActivityTargetObjectRecords.test.tsx | 175 +- ...ctivityTargetsForTargetableObject.test.tsx | 131 - .../useCreateActivityInCache.test.tsx | 106 - .../__tests__/useCreateActivityInDB.test.tsx | 27 +- .../useOpenActivityRightDrawer.test.tsx | 12 +- .../useOpenCreateActivityDrawer.test.tsx | 74 +- .../modules/activities/hooks/useActivities.ts | 23 +- .../hooks/useActivityTargetObjectRecords.ts | 32 +- .../useActivityTargetsForTargetableObject.ts | 40 - .../useActivityTargetsForTargetableObjects.ts | 15 +- .../hooks/useCreateActivityInCache.ts | 188 - .../activities/hooks/useCreateActivityInDB.ts | 42 +- .../hooks/useOpenActivityRightDrawer.ts | 21 +- .../hooks/useOpenCreateActivityDrawer.ts | 79 +- .../usePrepareFindManyActivitiesQuery.ts | 33 +- ...efreshShowPageFindManyActivitiesQueries.ts | 28 +- .../activities/hooks/useUpsertActivity.ts | 45 +- .../ActivityTargetInlineCellEditMode.tsx | 60 +- .../components/ActivityTargetsInlineCell.tsx | 21 +- .../activities/notes/components/NoteCard.tsx | 70 +- .../activities/notes/components/Notes.tsx | 7 +- .../notes/hooks/__tests__/useNotes.test.ts | 4 +- .../activities/notes/hooks/useNotes.ts | 10 +- .../components/ActivityActionBar.tsx | 133 - .../components/RightDrawerActivity.tsx | 39 - .../create/RightDrawerCreateActivity.tsx | 21 - .../edit/RightDrawerEditActivity.tsx | 17 - .../states/activityIdInDrawerState.ts | 6 - .../TasksRecoilScopeContext.ts | 3 - .../states/temporaryActivityForEditorState.ts | 9 - .../tasks/__stories__/TaskGroups.stories.tsx | 8 +- .../tasks/__stories__/TaskList.stories.tsx | 164 +- .../tasks/components/AddTaskButton.tsx | 6 +- .../CurrentUserDueTaskCountEffect.tsx | 48 - .../tasks/components/ObjectTasks.tsx | 10 +- .../tasks/components/PageAddTaskButton.tsx | 6 +- .../tasks/components/TaskGroups.tsx | 71 +- .../activities/tasks/components/TaskList.tsx | 7 +- .../activities/tasks/components/TaskRow.tsx | 58 +- .../hooks/__tests__/useCompleteTask.test.tsx | 29 +- .../useCurrentUserTaskCount.test.tsx | 31 - .../tasks/hooks/__tests__/useTasks.test.tsx | 40 +- .../activities/tasks/hooks/useCompleteTask.ts | 12 +- .../tasks/hooks/useCurrentUserDueTaskCount.ts | 33 - .../activities/tasks/hooks/useTasks.ts | 155 +- .../timeline/components/TimelineActivity.tsx | 218 - .../components/TimelineActivityTitle.tsx | 62 - .../components/TimelineItemsContainer.tsx | 55 - .../components/TimelineQueryEffect.tsx | 113 - .../components/TimelingeActivityGroup.tsx | 78 - .../__tests__/useTimelineActivities.test.tsx | 38 - .../timeline/hooks/useTimelineActivities.ts | 77 - .../states/timelineActivitiesFamilyState.ts | 10 - .../states/timelineActivitiesForGroupState.ts | 10 - ...melineActivityWithoutTargetsFamilyState.ts | 10 - .../__tests__/groupActivitiesByMonth.test.ts | 22 - .../timeline/utils/groupActivitiesByMonth.ts | 40 - .../makeTimelineActivitiesQueryVariables.ts | 22 - .../components/EventRow.tsx | 4 +- .../components/TimelineActivities.tsx | 6 +- .../TimelineActivitiesQueryEffect.tsx | 5 +- .../components/TimelineCreateButtonGroup.tsx | 10 +- .../FindManyTimelineActivitiesOrderBy.ts | 0 .../hooks/useLinkedObject.ts | 0 .../hooks/useTimelineActivities.tsx | 19 +- .../activity/components/EventRowActivity.tsx | 10 +- .../components/EventRowDynamicComponent.tsx | 16 +- .../objectShowPageTargetableObjectIdState.ts | 0 .../types/TimelineActivity.ts | 2 +- .../src/modules/activities/types/Activity.ts | 19 +- .../activities/types/ActivityForDrawer.ts | 3 - .../activities/types/ActivityForEditor.ts | 31 +- .../activities/types/ActivityTargetObject.ts | 5 +- .../activities/types/GraphQLActivity.ts | 33 - .../src/modules/activities/types/Note.ts | 4 +- .../{ActivityTarget.ts => NoteTarget.ts} | 8 +- .../src/modules/activities/types/Task.ts | 14 +- .../modules/activities/types/TaskTarget.ts | 19 + .../activities/utils/getActivityPreview.ts | 4 +- .../activities/utils/getActivitySummary.ts | 3 +- ...ityTargetsToCreateFromTargetableObjects.ts | 12 +- .../utils/getJoinObjectNameSingular.ts | 11 + ...coreObjectNamesToDeleteOnRelationDetach.ts | 3 +- .../src/modules/auth/hooks/useAuth.ts | 1 + .../command-menu/components/CommandMenu.tsx | 71 +- .../components/MainNavigationDrawerItems.tsx | 18 +- .../components/ObjectMetadataNavItems.tsx | 47 +- .../types/CoreObjectNameSingular.ts | 4 + .../mapFieldMetadataToGraphQLQuery.test.tsx | 24 +- .../mapObjectMetadataToGraphQLQuery.test.tsx | 161 +- .../utils/getLabelIdentifierFieldValue.ts | 8 + .../utils/getLinkToShowPage.ts | 18 +- .../utils/getObjectMetadataItemsMock.ts | 17799 ++++++++++++---- .../utils/isLabelIdentifierField.ts | 5 +- .../utils/mapFieldMetadataToGraphQLQuery.ts | 1 + .../cache/hooks/useGetRecordFromCache.ts | 2 +- .../object-record/components/RecordChip.tsx | 35 +- .../useUpdateOneRecordMutation.test.tsx | 13 +- .../hooks/useRecordActionBar.tsx | 4 +- .../record-field/components/FieldDisplay.tsx | 5 +- .../record-field/components/FieldInput.tsx | 4 + .../record-field/hooks/useIsFieldReadOnly.ts | 14 + .../components/RichTextFieldDisplay.tsx | 11 + .../input/components/RichTextFieldInput.tsx | 5 + .../record-field/types/FieldMetadata.ts | 5 + .../types/guards/assertFieldMetadata.ts | 4 +- .../types/guards/isFieldRichText.ts | 9 + .../record-field/utils/isFieldValueEmpty.ts | 2 + .../hooks/useRecordTableRecordGqlFields.ts | 12 + .../options/hooks/useDeleteTableData.ts | 19 +- .../components/RecordShowContainer.tsx | 231 +- ...ordForShowPageOperationSignatureFactory.ts | 40 +- .../record-show/hooks/useRecordShowPage.ts | 7 +- .../hooks/useRecordShowPagePagination.ts | 4 +- .../RecordDetailRelationSection.tsx | 2 +- .../components/RecordTableCellFieldInput.tsx | 4 +- .../RecordTableCellSoftFocusMode.tsx | 13 +- .../hooks/__tests__/useUpsertRecord.test.tsx | 5 + .../hooks/useUpsertRecord.ts | 21 +- ...etInlineCellEditModeMultiRecordsEffect.tsx | 6 + .../hooks/useMultiObjectSearch.ts | 4 + ...archMatchesSearchFilterAndToSelectQuery.ts | 11 +- .../select/utils/getObjectFilterFields.ts | 4 - .../utils/generateEmptyFieldValue.ts | 3 + .../utils/isFieldCellSupported.ts | 28 +- .../utils/sanitizeRecordInput.ts | 2 +- .../constants/SettingsFieldTypeConfigs.ts | 6 + .../getFirstNonEmptyLineOfRichText.test.tsx | 77 + .../utils/getFirstNonEmptyLineOfRichText.ts | 23 + .../right-drawer/components/RightDrawer.tsx | 13 +- .../components/RightDrawerRouter.tsx | 10 - .../components/RightDrawerTopBar.tsx | 37 +- .../RightDrawerTopBarExpandButton.tsx | 38 +- .../constants/RightDrawerPageIcons.ts | 2 - .../constants/RightDrawerPageTitles.ts | 2 - .../hooks/__tests__/useRightDrawer.test.tsx | 14 +- .../right-drawer/hooks/useRightDrawer.ts | 37 +- .../states/isRightDrawerExpandedState.ts | 6 - .../right-drawer/types/RightDrawerPages.ts | 2 - .../components/ShowPageActivityContainer.tsx | 31 + .../components/ShowPageAddButton.tsx | 38 +- .../components/ShowPageRightContainer.tsx | 90 +- .../components/NavigationDrawerItem.tsx | 2 +- .../components/NavigationDrawerSubItem.tsx | 43 + .../users/components/UserProviderEffect.tsx | 1 + .../components/ViewPickerListContent.tsx | 18 +- .../workspace-member/types/WorkspaceMember.ts | 2 +- .../SettingsObjectNewFieldStep2.tsx | 6 +- .../twenty-front/src/pages/tasks/Tasks.tsx | 86 - .../src/pages/tasks/TasksEffect.tsx | 53 - .../pages/tasks/__stories__/Tasks.stories.tsx | 44 - .../pages/tasks/tasks-filter-definitions.tsx | 17 - .../twenty-front/src/testing/graphqlMocks.ts | 37 +- .../src/testing/mock-data/activities.ts | 228 - .../standard-metadata-query-result.ts | 6 +- .../src/testing/mock-data/notes.ts | 124 + .../src/testing/mock-data/tasks.ts | 87 + .../src/utils/normalizeGQLField.ts | 8 + .../src/utils/normalizeGQLQuery.ts | 8 + packages/twenty-front/tsconfig.json | 1 + .../commands/database-command.module.ts | 3 +- .../0-23/0-23-update-activities.command.ts | 464 + .../0-23/0-23-upgrade-version.command.ts | 3 + .../0-23/0-23-upgrade-version.module.ts | 4 + .../upgrade-version.command.ts | 128 + .../upgrade-version/upgrade-version.module.ts | 62 + .../typeorm-seeds/core/demo/workspaces.ts | 4 + .../__mocks__/object-metadata-item.mock.ts | 8 + .../services/type-mapper.service.ts | 15 +- ...p-field-metadata-to-graphql-query.utils.ts | 1 + .../utils/__tests__/components.utils.spec.ts | 7 +- .../open-api/utils/components.utils.ts | 7 +- .../dtos/default-value.input.ts | 6 + .../field-metadata/field-metadata.entity.ts | 21 +- .../field-metadata-default-value.interface.ts | 8 +- .../validate-default-value-for-type.util.ts | 11 +- ...field-metadata-type-to-column-type.util.ts | 1 + .../workspace-migration.factory.ts | 9 +- .../workspace-migration.service.ts | 18 +- .../twenty-orm/custom.workspace-entity.ts | 42 +- .../pipeline-step.ts | 41 - .../view-company-fields.ts | 84 - .../view-opportunity-fields.ts | 61 - .../view-person-fields.ts | 104 - .../standard-objects-prefill-data/view.ts | 168 +- .../views/activities-all.view.ts | 71 + .../views/companies-all.view.ts | 86 + .../views/notes-all.view.ts | 62 + .../views/opportunities-all.view.ts | 65 + .../views/opportunity-by-stage.view.ts | 68 + .../views/people-all.view.ts | 104 + .../views/tasks-all.view.ts | 99 + .../views/tasks-by-status.view.ts | 93 + .../views/tasks-todo.view.ts | 1 + .../workspace-migration-field.factory.ts | 10 +- .../workspace-migration-runner.service.ts | 14 +- .../constants/standard-field-ids.ts | 50 + .../constants/standard-object-ids.ts | 4 + .../workspace-sync-field-metadata.service.ts | 34 +- .../standard-objects/index.ts | 16 + .../workspace-sync-metadata.service.ts | 1 + .../attachment.workspace-entity.ts | 32 + .../company.workspace-entity.ts | 25 + .../note-target.workspace-entity.ts | 103 + .../standard-objects/note.workspace-entity.ts | 96 + .../opportunity.workspace-entity.ts | 25 + .../person.workspace-entity.ts | 25 + .../task-target.workspace-entity.ts | 103 + .../standard-objects/task.workspace-entity.ts | 150 + ...meline-activity-from-internal-event.job.ts | 14 +- .../services/timeline-activity.service.ts | 61 +- .../timeline-activity.workspace-entity.ts | 32 + .../workspace-member.workspace-entity.ts | 13 + .../display/icon/components/TablerIcons.ts | 13 +- 239 files changed, 18418 insertions(+), 8671 deletions(-) delete mode 100644 packages/twenty-front/src/modules/activities/comment/Comment.tsx delete mode 100644 packages/twenty-front/src/modules/activities/comment/CommentCounter.tsx delete mode 100644 packages/twenty-front/src/modules/activities/comment/CommentHeader.tsx delete mode 100644 packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx delete mode 100644 packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx delete mode 100644 packages/twenty-front/src/modules/activities/comment/__stories__/mock-comment.ts delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityComments.tsx delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityCreationDate.tsx delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityEditor.tsx delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityEditorFields.tsx delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityTitleEffect.tsx delete mode 100644 packages/twenty-front/src/modules/activities/components/ActivityTypeDropdown.tsx rename packages/twenty-front/src/modules/activities/components/{ActivityBodyEditor.tsx => RichTextEditor.tsx} (95%) delete mode 100644 packages/twenty-front/src/modules/activities/graphql/operation-signatures/CreateOneActivityOperationSignature.ts create mode 100644 packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/createOneActivityOperationSignatureFactory.ts delete mode 100644 packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx delete mode 100644 packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx delete mode 100644 packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObject.ts delete mode 100644 packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts delete mode 100644 packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx delete mode 100644 packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivity.tsx delete mode 100644 packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx delete mode 100644 packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx delete mode 100644 packages/twenty-front/src/modules/activities/states/activityIdInDrawerState.ts delete mode 100644 packages/twenty-front/src/modules/activities/states/recoil-scope-contexts/TasksRecoilScopeContext.ts delete mode 100644 packages/twenty-front/src/modules/activities/states/temporaryActivityForEditorState.ts delete mode 100644 packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx delete mode 100644 packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCurrentUserTaskCount.test.tsx delete mode 100644 packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/components/TimelineActivity.tsx delete mode 100644 packages/twenty-front/src/modules/activities/timeline/components/TimelineActivityTitle.tsx delete mode 100644 packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx delete mode 100644 packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx delete mode 100644 packages/twenty-front/src/modules/activities/timeline/components/TimelingeActivityGroup.tsx delete mode 100644 packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useTimelineActivities.test.tsx delete mode 100644 packages/twenty-front/src/modules/activities/timeline/hooks/useTimelineActivities.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesFamilyState.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesForGroupState.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/states/timelineActivityWithoutTargetsFamilyState.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/utils/__tests__/groupActivitiesByMonth.test.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/utils/groupActivitiesByMonth.ts delete mode 100644 packages/twenty-front/src/modules/activities/timeline/utils/makeTimelineActivitiesQueryVariables.ts rename packages/twenty-front/src/modules/activities/{timeline => timelineActivities}/components/TimelineCreateButtonGroup.tsx (81%) rename packages/twenty-front/src/modules/activities/{timeline => timelineActivities}/constants/FindManyTimelineActivitiesOrderBy.ts (100%) rename packages/twenty-front/src/modules/activities/{timeline => timelineActivities}/hooks/useLinkedObject.ts (100%) rename packages/twenty-front/src/modules/activities/{timeline => timelineActivities}/states/objectShowPageTargetableObjectIdState.ts (100%) delete mode 100644 packages/twenty-front/src/modules/activities/types/ActivityForDrawer.ts delete mode 100644 packages/twenty-front/src/modules/activities/types/GraphQLActivity.ts rename packages/twenty-front/src/modules/activities/types/{ActivityTarget.ts => NoteTarget.ts} (66%) create mode 100644 packages/twenty-front/src/modules/activities/types/TaskTarget.ts create mode 100644 packages/twenty-front/src/modules/activities/utils/getJoinObjectNameSingular.ts create mode 100644 packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldReadOnly.ts create mode 100644 packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/RichTextFieldDisplay.tsx create mode 100644 packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/RichTextFieldInput.tsx create mode 100644 packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRichText.ts create mode 100644 packages/twenty-front/src/modules/ui/input/editor/utils/__tests__/getFirstNonEmptyLineOfRichText.test.tsx create mode 100644 packages/twenty-front/src/modules/ui/input/editor/utils/getFirstNonEmptyLineOfRichText.ts delete mode 100644 packages/twenty-front/src/modules/ui/layout/right-drawer/states/isRightDrawerExpandedState.ts create mode 100644 packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageActivityContainer.tsx create mode 100644 packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem.tsx delete mode 100644 packages/twenty-front/src/pages/tasks/Tasks.tsx delete mode 100644 packages/twenty-front/src/pages/tasks/TasksEffect.tsx delete mode 100644 packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx delete mode 100644 packages/twenty-front/src/pages/tasks/tasks-filter-definitions.tsx delete mode 100644 packages/twenty-front/src/testing/mock-data/activities.ts create mode 100644 packages/twenty-front/src/testing/mock-data/notes.ts create mode 100644 packages/twenty-front/src/testing/mock-data/tasks.ts create mode 100644 packages/twenty-front/src/utils/normalizeGQLField.ts create mode 100644 packages/twenty-front/src/utils/normalizeGQLQuery.ts create mode 100644 packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-update-activities.command.ts create mode 100644 packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.command.ts create mode 100644 packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.module.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/pipeline-step.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/activities-all.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunities-all.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-by-stage.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/people-all.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-todo.view.ts create mode 100644 packages/twenty-server/src/modules/note/standard-objects/note-target.workspace-entity.ts create mode 100644 packages/twenty-server/src/modules/note/standard-objects/note.workspace-entity.ts create mode 100644 packages/twenty-server/src/modules/task/standard-objects/task-target.workspace-entity.ts create mode 100644 packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts diff --git a/packages/twenty-front/.eslintrc.cjs b/packages/twenty-front/.eslintrc.cjs index df4daf763..bb5753126 100644 --- a/packages/twenty-front/.eslintrc.cjs +++ b/packages/twenty-front/.eslintrc.cjs @@ -6,6 +6,7 @@ module.exports = { 'mockServiceWorker.js', '**/generated*/*', '**/generated/standard-metadata-query-result.ts', + '**/getObjectMetadataItemsMock.ts', 'tsup.config.ts', 'build', 'coverage', diff --git a/packages/twenty-front/src/App.tsx b/packages/twenty-front/src/App.tsx index dd65834c4..75460ee37 100644 --- a/packages/twenty-front/src/App.tsx +++ b/packages/twenty-front/src/App.tsx @@ -84,7 +84,6 @@ import { SettingsBilling } from '~/pages/settings/SettingsBilling'; import { SettingsProfile } from '~/pages/settings/SettingsProfile'; import { SettingsWorkspace } from '~/pages/settings/SettingsWorkspace'; import { SettingsWorkspaceMembers } from '~/pages/settings/SettingsWorkspaceMembers'; -import { Tasks } from '~/pages/tasks/Tasks'; import { getPageTitleFromPath } from '~/utils/title-utils'; const ProvidersThatNeedRouterContext = () => { @@ -158,7 +157,6 @@ const createRouter = ( element={} /> } /> - } /> } /> } /> } /> diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx index 785780166..19da0d36d 100644 --- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx +++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx @@ -9,6 +9,7 @@ import { useRequestFreshCaptchaToken } from '@/captcha/hooks/useRequestFreshCapt import { isCaptchaScriptLoadedState } from '@/captcha/states/isCaptchaScriptLoadedState'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { CommandType } from '@/command-menu/types/Command'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope'; import { AppBasePath } from '@/types/AppBasePath'; import { AppPath } from '@/types/AppPath'; @@ -38,7 +39,9 @@ export const PageChangeEffect = () => { const { addToCommandMenu, setToInitialCommandMenu } = useCommandMenu(); - const openCreateActivity = useOpenCreateActivityDrawer(); + const openCreateActivity = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Task, + }); useEffect(() => { if (!previousLocation || previousLocation !== location.pathname) { @@ -143,8 +146,7 @@ export const PageChangeEffect = () => { label: 'Create Task', type: CommandType.Create, Icon: IconCheckbox, - onCommandClick: () => - openCreateActivity({ type: 'Task', targetableObjects: [] }), + onCommandClick: () => openCreateActivity({ targetableObjects: [] }), }, ]); }, [addToCommandMenu, setToInitialCommandMenu, openCreateActivity]); diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index df44e0152..51a4c0851 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -361,6 +361,7 @@ export enum FieldMetadataType { Rating = 'RATING', RawJson = 'RAW_JSON', Relation = 'RELATION', + RichText = 'RICH_TEXT', Select = 'SELECT', Text = 'TEXT', Uuid = 'UUID' diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index 8f607ef32..10fe470cf 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -250,6 +250,7 @@ export enum FieldMetadataType { Rating = 'RATING', RawJson = 'RAW_JSON', Relation = 'RELATION', + RichText = 'RICH_TEXT', Select = 'SELECT', Text = 'TEXT', Uuid = 'UUID' diff --git a/packages/twenty-front/src/modules/activities/comment/Comment.tsx b/packages/twenty-front/src/modules/activities/comment/Comment.tsx deleted file mode 100644 index 810453eea..000000000 --- a/packages/twenty-front/src/modules/activities/comment/Comment.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import styled from '@emotion/styled'; - -import { Comment as CommentType } from '@/activities/types/Comment'; - -import { CommentHeader } from './CommentHeader'; - -type CommentProps = { - comment: CommentType; - actionBar?: React.ReactNode; -}; - -const StyledContainer = styled.div` - align-items: flex-start; - display: flex; - flex-direction: column; - gap: ${({ theme }) => theme.spacing(1)}; - justify-content: flex-start; - width: 100%; -`; - -const StyledCommentBody = styled.div` - color: ${({ theme }) => theme.font.color.secondary}; - font-size: ${({ theme }) => theme.font.size.md}; - - line-height: ${({ theme }) => theme.text.lineHeight.md}; - overflow-wrap: anywhere; - - padding-left: 24px; - text-align: left; -`; - -export const Comment = ({ comment, actionBar }: CommentProps) => ( - - - {comment.body} - -); diff --git a/packages/twenty-front/src/modules/activities/comment/CommentCounter.tsx b/packages/twenty-front/src/modules/activities/comment/CommentCounter.tsx deleted file mode 100644 index 29abcea3a..000000000 --- a/packages/twenty-front/src/modules/activities/comment/CommentCounter.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; -import { IconComment } from 'twenty-ui'; - -const StyledCommentIcon = styled.div` - align-items: center; - color: ${({ theme }) => theme.font.color.light}; - display: flex; - gap: ${({ theme }) => theme.spacing(1)}; -`; - -const CommentCounter = ({ commentCount }: { commentCount: number }) => { - const theme = useTheme(); - return ( -
- {commentCount > 0 && ( - - - {commentCount} - - )} -
- ); -}; - -export default CommentCounter; diff --git a/packages/twenty-front/src/modules/activities/comment/CommentHeader.tsx b/packages/twenty-front/src/modules/activities/comment/CommentHeader.tsx deleted file mode 100644 index c40cd8f26..000000000 --- a/packages/twenty-front/src/modules/activities/comment/CommentHeader.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import styled from '@emotion/styled'; -import { AppTooltip, Avatar } from 'twenty-ui'; - -import { Comment } from '@/activities/types/Comment'; -import { - beautifyExactDateTime, - beautifyPastDateRelativeToNow, -} from '~/utils/date-utils'; - -const StyledContainer = styled.div` - align-items: center; - display: flex; - - justify-content: space-between; - - padding: ${({ theme }) => theme.spacing(1)}; - width: calc(100% - ${({ theme }) => theme.spacing(1)}); -`; - -const StyledLeftContainer = styled.div` - align-items: end; - display: flex; - gap: ${({ theme }) => theme.spacing(1)}; -`; - -const StyledName = styled.div` - color: ${({ theme }) => theme.font.color.primary}; - font-size: ${({ theme }) => theme.font.size.md}; - font-weight: ${({ theme }) => theme.font.weight.regular}; - max-width: 160px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -`; - -const StyledDate = styled.div` - color: ${({ theme }) => theme.font.color.light}; - font-size: ${({ theme }) => theme.font.size.sm}; - font-weight: ${({ theme }) => theme.font.weight.regular}; - margin-left: ${({ theme }) => theme.spacing(1)}; -`; - -type CommentHeaderProps = { - comment: Pick; - actionBar?: React.ReactNode; -}; - -export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => { - const beautifiedCreatedAt = beautifyPastDateRelativeToNow(comment.createdAt); - const exactCreatedAt = beautifyExactDateTime(comment.createdAt); - const showDate = beautifiedCreatedAt !== ''; - - const author = comment.author; - const authorName = author?.name?.firstName + ' ' + author?.name?.lastName; - const avatarUrl = author?.avatarUrl; - const commentId = comment.id; - - return ( - - - - {authorName} - {showDate && ( - <> - - {beautifiedCreatedAt} - - - - )} - -
{actionBar}
-
- ); -}; diff --git a/packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx b/packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx deleted file mode 100644 index 8df2da809..000000000 --- a/packages/twenty-front/src/modules/activities/comment/__stories__/Comment.stories.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { useEffect } from 'react'; -import { Meta, StoryObj } from '@storybook/react'; -import { useSetRecoilState } from 'recoil'; -import { ComponentDecorator } from 'twenty-ui'; - -import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; - -import { ActivityActionBar } from '../../right-drawer/components/ActivityActionBar'; -import { Comment } from '../Comment'; - -import { mockComment, mockCommentWithLongValues } from './mock-comment'; - -const CommentSetterEffect = () => { - const setViewableRecord = useSetRecoilState(viewableRecordIdState); - - useEffect(() => { - setViewableRecord('test-id'); - }, [setViewableRecord]); - - return null; -}; - -const meta: Meta = { - title: 'Modules/Activity/Comment/Comment', - component: Comment, - decorators: [ - (Story) => ( - <> - - - - ), - ComponentDecorator, - ], - argTypes: { - actionBar: { - type: 'boolean', - mapping: { - true: , - false: undefined, - }, - }, - }, - args: { comment: mockComment }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; - -export const WithLongValues: Story = { - args: { comment: mockCommentWithLongValues }, -}; diff --git a/packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx b/packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx deleted file mode 100644 index 25c01d745..000000000 --- a/packages/twenty-front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { useEffect } from 'react'; -import { Meta, StoryObj } from '@storybook/react'; -import { DateTime } from 'luxon'; -import { useSetRecoilState } from 'recoil'; - -import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar'; -import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; -import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator'; -import { avatarUrl } from '~/testing/mock-data/users'; - -import { CommentHeader } from '../CommentHeader'; - -import { mockComment, mockCommentWithLongValues } from './mock-comment'; - -const CommentHeaderSetterEffect = () => { - const setViewableRecord = useSetRecoilState(viewableRecordIdState); - - useEffect(() => { - setViewableRecord('test-id'); - }, [setViewableRecord]); - - return null; -}; - -const meta: Meta = { - title: 'Modules/Activity/Comment/CommentHeader', - component: CommentHeader, - decorators: [ - (Story) => ( - <> - - - - ), - ComponentWithRouterDecorator, - ], - argTypes: { - actionBar: { - type: 'boolean', - mapping: { - true: , - false: undefined, - }, - }, - }, - args: { comment: mockComment }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; - -export const FewHoursAgo: Story = { - args: { - comment: { - ...mockComment, - createdAt: DateTime.now().minus({ hours: 2 }).toISO() ?? '', - }, - }, -}; - -export const FewDaysAgo: Story = { - args: { - comment: { - ...mockComment, - createdAt: DateTime.now().minus({ days: 2 }).toISO() ?? '', - }, - }, -}; - -export const FewMonthsAgo: Story = { - args: { - comment: { - ...mockComment, - createdAt: DateTime.now().minus({ months: 2 }).toISO() ?? '', - }, - }, -}; - -export const FewYearsAgo: Story = { - args: { - comment: { - ...mockComment, - createdAt: DateTime.now().minus({ years: 2 }).toISO() ?? '', - }, - }, -}; - -export const WithAvatar: Story = { - args: { - comment: { - ...mockComment, - author: { - ...mockComment.author, - avatarUrl, - }, - }, - }, -}; - -export const WithLongUserName: Story = { - args: { comment: mockCommentWithLongValues }, -}; - -export const WithActionBar: Story = { - args: { actionBar: true }, -}; diff --git a/packages/twenty-front/src/modules/activities/comment/__stories__/mock-comment.ts b/packages/twenty-front/src/modules/activities/comment/__stories__/mock-comment.ts deleted file mode 100644 index b95cf7250..000000000 --- a/packages/twenty-front/src/modules/activities/comment/__stories__/mock-comment.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { DateTime } from 'luxon'; - -import { Comment } from '@/activities/types/Comment'; - -export const mockComment: Pick< - Comment, - | 'id' - | 'author' - | 'createdAt' - | 'body' - | 'updatedAt' - | 'activityId' - | '__typename' -> = { - id: 'fake_comment_1_uuid', - body: 'Hello, this is a comment.', - author: { - id: 'fake_comment_1_author_uuid', - name: { - firstName: 'Jony' ?? '', - lastName: 'Ive' ?? '', - }, - avatarUrl: null, - }, - createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '', - updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '', - activityId: 'fake_activity_1_uuid', - __typename: 'Comment', -}; - -export const mockCommentWithLongValues: Pick< - Comment, - | 'id' - | 'author' - | 'createdAt' - | 'body' - | 'updatedAt' - | 'activityId' - | '__typename' -> = { - id: 'fake_comment_2_uuid', - body: 'Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment.', - author: { - id: 'fake_comment_1_author_uuid', - name: { - firstName: 'Jony' ?? '', - lastName: 'Ive' ?? '', - }, - avatarUrl: null, - }, - createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '', - updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '', - activityId: 'fake_activity_1_uuid', - __typename: 'Comment', -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityComments.tsx b/packages/twenty-front/src/modules/activities/components/ActivityComments.tsx deleted file mode 100644 index 16bdbed69..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityComments.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import styled from '@emotion/styled'; -import { isNonEmptyString } from '@sniptt/guards'; -import { useRecoilValue } from 'recoil'; -import { v4 } from 'uuid'; - -import { Comment } from '@/activities/comment/Comment'; -import { Comment as CommentType } from '@/activities/types/Comment'; -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; -import { - AutosizeTextInput, - AutosizeTextInputVariant, -} from '@/ui/input/components/AutosizeTextInput'; -import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; - -const StyledThreadItemListContainer = styled.div` - align-items: flex-start; - border-top: 1px solid ${({ theme }) => theme.border.color.light}; - - box-sizing: border-box; - display: flex; - flex-direction: column; - - gap: ${({ theme }) => theme.spacing(4)}; - - justify-content: flex-start; - padding: ${({ theme }) => theme.spacing(8)}; - padding-left: ${({ theme }) => theme.spacing(12)}; - width: 100%; -`; - -const StyledCommentActionBar = styled.div` - background: ${({ theme }) => theme.background.primary}; - border-top: 1px solid ${({ theme }) => theme.border.color.light}; - display: flex; - padding: 16px 24px 16px 48px; - width: calc( - ${({ theme }) => (useIsMobile() ? '100%' : theme.rightDrawerWidth)} - 72px - ); -`; - -const StyledThreadCommentTitle = styled.div` - color: ${({ theme }) => theme.font.color.tertiary}; - font-size: ${({ theme }) => theme.font.size.xs}; - font-weight: ${({ theme }) => theme.font.weight.semiBold}; - text-transform: uppercase; -`; - -type ActivityCommentsProps = { - activityId: string; - scrollableContainerRef: React.RefObject; -}; - -export const ActivityComments = ({ - activityId, - scrollableContainerRef, -}: ActivityCommentsProps) => { - const { createOneRecord: createOneComment } = useCreateOneRecord({ - objectNameSingular: CoreObjectNameSingular.Comment, - }); - - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - - const { records: comments } = useFindManyRecords({ - objectNameSingular: CoreObjectNameSingular.Comment, - skip: !isNonEmptyString(activityId), - filter: { - activityId: { - eq: activityId, - }, - }, - }); - - if (!currentWorkspaceMember) { - return <>; - } - - const handleSendComment = (commentText: string) => { - if (!isNonEmptyString(commentText)) { - return; - } - - createOneComment?.({ - id: v4(), - authorId: currentWorkspaceMember?.id ?? '', - author: currentWorkspaceMember, - activityId: activityId, - body: commentText, - createdAt: new Date().toISOString(), - }); - }; - - const handleFocus = () => { - const scrollableContainer = scrollableContainerRef.current; - - scrollableContainer?.scrollTo({ - top: scrollableContainer.scrollHeight, - behavior: 'smooth', - }); - }; - - return ( - <> - {comments.length > 0 && ( - <> - - Comments - {comments?.map((comment) => ( - - ))} - - - )} - - - {currentWorkspaceMember && ( - 0 ? 'Reply...' : undefined} - /> - )} - - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityCreationDate.tsx b/packages/twenty-front/src/modules/activities/components/ActivityCreationDate.tsx deleted file mode 100644 index 6d0fdf75f..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityCreationDate.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import styled from '@emotion/styled'; -import { useRecoilState } from 'recoil'; - -import { Activity } from '@/activities/types/Activity'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; - -const StyledCreationDisplay = styled.span` - color: ${({ theme }) => theme.font.color.light}; - display: flex; - font-size: ${({ theme }) => theme.font.size.sm}; - user-select: none; - width: 100%; -`; - -type ActivityCreationDateProps = { - activityId: string; -}; - -export const ActivityCreationDate = ({ - activityId, -}: ActivityCreationDateProps) => { - const [activityInStore] = useRecoilState(recordStoreFamilyState(activityId)); - const activity = activityInStore as Activity; - - const beautifiedDate = activity.createdAt - ? beautifyPastDateRelativeToNow(activity.createdAt) - : null; - - const authorName = activity.author?.name - ? `${activity.author.name.firstName} ${activity.author.name.lastName}` - : null; - - if (!activity.createdAt || !authorName) { - return <>; - } - - return ( - - Created {beautifiedDate} by {authorName} - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityEditor.tsx b/packages/twenty-front/src/modules/activities/components/ActivityEditor.tsx deleted file mode 100644 index dc8214c40..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityEditor.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import styled from '@emotion/styled'; -import { useRef } from 'react'; - -import { ActivityBodyEditor } from '@/activities/components/ActivityBodyEditor'; -import { ActivityBodyEffect } from '@/activities/components/ActivityBodyEffect'; -import { ActivityComments } from '@/activities/components/ActivityComments'; -import { ActivityCreationDate } from '@/activities/components/ActivityCreationDate'; -import { ActivityEditorFields } from '@/activities/components/ActivityEditorFields'; -import { ActivityTitleEffect } from '@/activities/components/ActivityTitleEffect'; -import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; - -import { ActivityTitle } from './ActivityTitle'; - -const StyledContainer = styled.div` - box-sizing: border-box; - display: flex; - flex-direction: column; - height: 100%; - overflow-y: auto; - gap: ${({ theme }) => theme.spacing(4)}; -`; - -const StyledUpperPartContainer = styled.div` - align-items: flex-start; - box-sizing: border-box; - display: flex; - flex-direction: column; - - justify-content: flex-start; -`; - -const StyledTitleContainer = styled.div` - display: flex; - flex-direction: column; - width: 100%; - gap: ${({ theme }) => theme.spacing(2)}; -`; - -const StyledTopContainer = styled.div` - align-items: flex-start; - align-self: stretch; - background: ${({ theme }) => theme.background.secondary}; - border-bottom: ${({ theme }) => - useIsMobile() ? 'none' : `1px solid ${theme.border.color.medium}`}; - display: flex; - flex-direction: column; - gap: 24px; - padding: ${({ theme }) => theme.spacing(6)}; -`; - -type ActivityEditorProps = { - activityId: string; - showComment?: boolean; - fillTitleFromBody?: boolean; -}; - -export const ActivityEditor = ({ - activityId, - showComment = true, - fillTitleFromBody = false, -}: ActivityEditorProps) => { - const containerRef = useRef(null); - - return ( - - - - - - - - - - - - - - {showComment && ( - - )} - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx b/packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx deleted file mode 100644 index 3d6a03d99..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityEditorEffect.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { useRecoilCallback } from 'recoil'; - -import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity'; -import { activityBodyFamilyState } from '@/activities/states/activityBodyFamilyState'; -import { activityTitleFamilyState } from '@/activities/states/activityTitleFamilyState'; -import { canCreateActivityState } from '@/activities/states/canCreateActivityState'; -import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState'; -import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState'; -import { Activity } from '@/activities/types/Activity'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useDeleteRecordFromCache } from '@/object-record/cache/hooks/useDeleteRecordFromCache'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID } from '@/ui/layout/right-drawer/constants/RightDrawerClickOutsideListener'; -import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener'; -import { isDefined } from '~/utils/isDefined'; - -export const ActivityEditorEffect = ({ - activityId, -}: { - activityId: string; -}) => { - const { useRegisterClickOutsideListenerCallback } = useClickOutsideListener( - RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID, - ); - - const { upsertActivity } = useUpsertActivity(); - const deleteRecordFromCache = useDeleteRecordFromCache({ - objectNameSingular: CoreObjectNameSingular.Activity, - }); - - const upsertActivityCallback = useRecoilCallback( - ({ snapshot, set }) => - () => { - const isUpsertingActivityInDB = snapshot - .getLoadable(isUpsertingActivityInDBState) - .getValue(); - - const canCreateActivity = snapshot - .getLoadable(canCreateActivityState) - .getValue(); - - const isActivityInCreateMode = snapshot - .getLoadable(isActivityInCreateModeState) - .getValue(); - - const activityFromStore = snapshot - .getLoadable(recordStoreFamilyState(activityId)) - .getValue(); - - const activity = activityFromStore as Activity | null; - - const activityTitle = snapshot - .getLoadable(activityTitleFamilyState({ activityId })) - .getValue(); - - const activityBody = snapshot - .getLoadable(activityBodyFamilyState({ activityId })) - .getValue(); - - if (isUpsertingActivityInDB || !activityFromStore) { - return; - } - - if (isActivityInCreateMode && isDefined(activity)) { - if (canCreateActivity) { - upsertActivity({ - activity, - input: { - title: activityFromStore.title, - body: activityFromStore.body, - }, - }); - } else { - deleteRecordFromCache(activity); - } - - set(isActivityInCreateModeState, false); - } else if (isDefined(activity)) { - if ( - activity.title !== activityTitle || - activity.body !== activityBody - ) { - upsertActivity({ - activity, - input: { - title: activityTitle, - body: activityBody, - }, - }); - } - } - }, - [activityId, deleteRecordFromCache, upsertActivity], - ); - - useRegisterClickOutsideListenerCallback({ - callbackId: 'activity-editor', - callbackFunction: upsertActivityCallback, - }); - - return <>; -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityEditorFields.tsx b/packages/twenty-front/src/modules/activities/components/ActivityEditorFields.tsx deleted file mode 100644 index e29b774b6..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityEditorFields.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import styled from '@emotion/styled'; -import { useRecoilValue } from 'recoil'; - -import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity'; -import { ActivityTargetsInlineCell } from '@/activities/inline-cell/components/ActivityTargetsInlineCell'; -import { Activity } from '@/activities/types/Activity'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache'; -import { useFieldContext } from '@/object-record/hooks/useFieldContext'; -import { - RecordUpdateHook, - RecordUpdateHookParams, -} from '@/object-record/record-field/contexts/FieldContext'; -import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; -import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { isRightDrawerAnimationCompletedState } from '@/ui/layout/right-drawer/states/isRightDrawerAnimationCompletedState'; -import { isDefined } from '~/utils/isDefined'; - -const StyledPropertyBox = styled(PropertyBox)` - padding: 0; -`; - -export const ActivityEditorFields = ({ - activityId, -}: { - activityId: string; -}) => { - const { upsertActivity } = useUpsertActivity(); - - const isRightDrawerAnimationCompleted = useRecoilValue( - isRightDrawerAnimationCompletedState, - ); - - const getRecordFromCache = useGetRecordFromCache({ - objectNameSingular: CoreObjectNameSingular.Activity, - }); - - const activityFromCache = getRecordFromCache(activityId); - - const activityFromStore = useRecoilValue(recordStoreFamilyState(activityId)); - - const activity = activityFromStore as Activity; - - const useUpsertOneActivityMutation: RecordUpdateHook = () => { - const upsertActivityMutation = async ({ - variables, - }: RecordUpdateHookParams) => { - if (isDefined(activityFromStore)) { - await upsertActivity({ - activity: activityFromStore as Activity, - input: variables.updateOneRecordInput, - }); - } - }; - - return [upsertActivityMutation, { loading: false }]; - }; - - const { FieldContextProvider: ReminderAtFieldContextProvider } = - useFieldContext({ - objectNameSingular: CoreObjectNameSingular.Activity, - objectRecordId: activityId, - fieldMetadataName: 'reminderAt', - fieldPosition: 0, - clearable: true, - customUseUpdateOneObjectHook: useUpsertOneActivityMutation, - }); - - const { FieldContextProvider: DueAtFieldContextProvider } = useFieldContext({ - objectNameSingular: CoreObjectNameSingular.Activity, - objectRecordId: activityId, - fieldMetadataName: 'dueAt', - fieldPosition: 1, - clearable: true, - customUseUpdateOneObjectHook: useUpsertOneActivityMutation, - }); - - const { FieldContextProvider: AssigneeFieldContextProvider } = - useFieldContext({ - objectNameSingular: CoreObjectNameSingular.Activity, - objectRecordId: activityId, - fieldMetadataName: 'assignee', - fieldPosition: 2, - clearable: true, - customUseUpdateOneObjectHook: useUpsertOneActivityMutation, - }); - - return ( - - {activity.type === 'Task' && - ReminderAtFieldContextProvider && - DueAtFieldContextProvider && - AssigneeFieldContextProvider && ( - <> - - - - - - - - - - - )} - {isDefined(activityFromCache) && isRightDrawerAnimationCompleted && ( - - )} - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx b/packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx deleted file mode 100644 index da1c10d2f..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityTitle.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import { useRef } from 'react'; -import { useApolloClient } from '@apollo/client'; -import styled from '@emotion/styled'; -import { isNonEmptyString } from '@sniptt/guards'; -import { useRecoilState } from 'recoil'; -import { Key } from 'ts-key-enum'; -import { useDebouncedCallback } from 'use-debounce'; - -import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity'; -import { activityTitleFamilyState } from '@/activities/states/activityTitleFamilyState'; -import { activityTitleHasBeenSetFamilyState } from '@/activities/states/activityTitleHasBeenSetFamilyState'; -import { canCreateActivityState } from '@/activities/states/canCreateActivityState'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope'; -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { - Checkbox, - CheckboxShape, - CheckboxSize, -} from '@/ui/input/components/Checkbox'; -import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; -import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; -import { isDefined } from '~/utils/isDefined'; - -const StyledEditableTitleInput = styled.input<{ - completed: boolean; - value: string; -}>` - background: transparent; - - border: none; - color: ${({ theme, value }) => - value ? theme.font.color.primary : theme.font.color.light}; - display: flex; - - flex-direction: column; - font-size: ${({ theme }) => theme.font.size.xl}; - font-weight: ${({ theme }) => theme.font.weight.semiBold}; - - line-height: ${({ theme }) => theme.text.lineHeight.md}; - outline: none; - text-decoration: ${({ completed }) => (completed ? 'line-through' : 'none')}; - &::placeholder { - color: ${({ theme }) => theme.font.color.light}; - } - width: calc(100% - ${({ theme }) => theme.spacing(2)}); -`; - -const StyledContainer = styled.div` - display: flex; - flex-direction: row; - gap: ${({ theme }) => theme.spacing(2)}; - width: 100%; -`; - -type ActivityTitleProps = { - activityId: string; -}; - -export const ActivityTitle = ({ activityId }: ActivityTitleProps) => { - const [activityInStore, setActivityInStore] = useRecoilState( - recordStoreFamilyState(activityId), - ); - - const cache = useApolloClient().cache; - - const [activityTitle, setActivityTitle] = useRecoilState( - activityTitleFamilyState({ activityId }), - ); - - const activity = activityInStore as Activity; - - const [canCreateActivity, setCanCreateActivity] = useRecoilState( - canCreateActivityState, - ); - - const { upsertActivity } = useUpsertActivity(); - - const { - setHotkeyScopeAndMemorizePreviousScope, - goBackToPreviousHotkeyScope, - } = usePreviousHotkeyScope(); - const titleInputRef = useRef(null); - - useScopedHotkeys( - Key.Escape, - () => { - handleBlur(); - }, - ActivityEditorHotkeyScope.ActivityTitle, - ); - - const handleBlur = () => { - goBackToPreviousHotkeyScope(); - titleInputRef.current?.blur(); - }; - - const handleFocus = () => { - setHotkeyScopeAndMemorizePreviousScope( - ActivityEditorHotkeyScope.ActivityTitle, - ); - }; - - const [activityTitleHasBeenSet, setActivityTitleHasBeenSet] = useRecoilState( - activityTitleHasBeenSetFamilyState({ - activityId: activityId, - }), - ); - - const { objectMetadataItem: objectMetadataItemActivity } = - useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.Activity, - }); - - const persistTitleDebounced = useDebouncedCallback((newTitle: string) => { - upsertActivity({ - activity, - input: { - title: newTitle, - }, - }); - - if (!activityTitleHasBeenSet) { - setActivityTitleHasBeenSet(true); - } - }, 500); - - const setTitleDebounced = useDebouncedCallback((newTitle: string) => { - setActivityInStore((currentActivity) => { - return { - ...currentActivity, - id: activity.id, - title: newTitle, - __typename: activity.__typename, - }; - }); - - if (isNonEmptyString(newTitle) && !canCreateActivity) { - setCanCreateActivity(true); - } - - modifyRecordFromCache({ - recordId: activity.id, - fieldModifiers: { - title: () => { - return newTitle; - }, - }, - cache: cache, - objectMetadataItem: objectMetadataItemActivity, - }); - }, 500); - - const handleTitleChange = (newTitle: string) => { - setActivityTitle(newTitle); - - setTitleDebounced(newTitle); - - persistTitleDebounced(newTitle); - }; - - const handleActivityCompletionChange = (value: boolean) => { - upsertActivity({ - activity, - input: { - completedAt: value ? new Date().toISOString() : null, - }, - }); - }; - - const completed = isDefined(activity.completedAt); - - return ( - - {activity.type === 'Task' && ( - handleActivityCompletionChange(value)} - /> - )} - handleTitleChange(event.target.value)} - value={activityTitle} - completed={completed} - onBlur={handleBlur} - onFocus={handleFocus} - /> - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityTitleEffect.tsx b/packages/twenty-front/src/modules/activities/components/ActivityTitleEffect.tsx deleted file mode 100644 index 50d3e4dff..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityTitleEffect.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { useEffect } from 'react'; -import { useRecoilState } from 'recoil'; - -import { activityTitleFamilyState } from '@/activities/states/activityTitleFamilyState'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { isDefined } from '~/utils/isDefined'; - -export const ActivityTitleEffect = ({ activityId }: { activityId: string }) => { - const [activityFromStore] = useRecoilState( - recordStoreFamilyState(activityId), - ); - - const [activityTitle, setActivityTitle] = useRecoilState( - activityTitleFamilyState({ activityId }), - ); - - useEffect(() => { - if ( - activityTitle === '' && - isDefined(activityFromStore) && - activityTitle !== activityFromStore.title - ) { - setActivityTitle(activityFromStore.title); - } - }, [activityFromStore, activityTitle, setActivityTitle]); - - return <>; -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityTypeDropdown.tsx b/packages/twenty-front/src/modules/activities/components/ActivityTypeDropdown.tsx deleted file mode 100644 index 4bb23a11d..000000000 --- a/packages/twenty-front/src/modules/activities/components/ActivityTypeDropdown.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { useTheme } from '@emotion/react'; -import { useRecoilState } from 'recoil'; -import { - Chip, - ChipAccent, - ChipSize, - ChipVariant, - IconCheckbox, - IconNotes, -} from 'twenty-ui'; - -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; - -type ActivityTypeDropdownProps = { - activityId: string; -}; - -export const ActivityTypeDropdown = ({ - activityId, -}: ActivityTypeDropdownProps) => { - const [activityInStore] = useRecoilState(recordStoreFamilyState(activityId)); - - const theme = useTheme(); - - return ( - - ) : ( - - ) - } - size={ChipSize.Large} - accent={ChipAccent.TextSecondary} - variant={ChipVariant.Highlighted} - /> - ); -}; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx b/packages/twenty-front/src/modules/activities/components/RichTextEditor.tsx similarity index 95% rename from packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx rename to packages/twenty-front/src/modules/activities/components/RichTextEditor.tsx index f28727eb5..8a546e0bf 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx +++ b/packages/twenty-front/src/modules/activities/components/RichTextEditor.tsx @@ -12,10 +12,8 @@ import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity'; import { activityBodyFamilyState } from '@/activities/states/activityBodyFamilyState'; import { activityTitleHasBeenSetFamilyState } from '@/activities/states/activityTitleHasBeenSetFamilyState'; import { canCreateActivityState } from '@/activities/states/canCreateActivityState'; -import { Activity } from '@/activities/types/Activity'; import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { BlockEditor } from '@/ui/input/editor/components/BlockEditor'; @@ -29,22 +27,31 @@ import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { getFileType } from '../files/utils/getFileType'; -import { getFileAbsoluteURI } from '~/utils/file/getFileAbsoluteURI'; +import { Note } from '@/activities/types/Note'; +import { Task } from '@/activities/types/Task'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import '@blocknote/core/fonts/inter.css'; import '@blocknote/mantine/style.css'; +import '@blocknote/react/style.css'; +import { getFileAbsoluteURI } from '~/utils/file/getFileAbsoluteURI'; -type ActivityBodyEditorProps = { +type RichTextEditorProps = { activityId: string; fillTitleFromBody: boolean; + activityObjectNameSingular: + | CoreObjectNameSingular.Task + | CoreObjectNameSingular.Note; }; -export const ActivityBodyEditor = ({ +export const RichTextEditor = ({ activityId, fillTitleFromBody, -}: ActivityBodyEditorProps) => { + activityObjectNameSingular, +}: RichTextEditorProps) => { const [activityInStore] = useRecoilState(recordStoreFamilyState(activityId)); + const cache = useApolloClient().cache; - const activity = activityInStore as Activity | null; + const activity = activityInStore as Task | Note | null; const [activityTitleHasBeenSet, setActivityTitleHasBeenSet] = useRecoilState( activityTitleHasBeenSetFamilyState({ @@ -60,7 +67,7 @@ export const ActivityBodyEditor = ({ const { objectMetadataItem: objectMetadataItemActivity } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.Activity, + objectNameSingular: activityObjectNameSingular, }); const { @@ -68,7 +75,9 @@ export const ActivityBodyEditor = ({ setHotkeyScopeAndMemorizePreviousScope, } = usePreviousHotkeyScope(); - const { upsertActivity } = useUpsertActivity(); + const { upsertActivity } = useUpsertActivity({ + activityObjectNameSingular: activityObjectNameSingular, + }); const persistBodyDebounced = useDebouncedCallback((newBody: string) => { if (isDefined(activity)) { diff --git a/packages/twenty-front/src/modules/activities/graphql/operation-signatures/CreateOneActivityOperationSignature.ts b/packages/twenty-front/src/modules/activities/graphql/operation-signatures/CreateOneActivityOperationSignature.ts deleted file mode 100644 index 5a01a56a6..000000000 --- a/packages/twenty-front/src/modules/activities/graphql/operation-signatures/CreateOneActivityOperationSignature.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature'; - -export const CREATE_ONE_ACTIVITY_OPERATION_SIGNATURE: RecordGqlOperationSignature = - { - objectNameSingular: CoreObjectNameSingular.Activity, - variables: {}, - fields: { - id: true, - __typename: true, - createdAt: true, - updatedAt: true, - author: { - id: true, - name: true, - __typename: true, - }, - authorId: true, - assigneeId: true, - assignee: { - id: true, - name: true, - __typename: true, - }, - comments: true, - attachments: true, - body: true, - title: true, - completedAt: true, - dueAt: true, - reminderAt: true, - type: true, - }, - }; diff --git a/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/createOneActivityOperationSignatureFactory.ts b/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/createOneActivityOperationSignatureFactory.ts new file mode 100644 index 000000000..9a6ed73c1 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/createOneActivityOperationSignatureFactory.ts @@ -0,0 +1,40 @@ +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { RecordGqlOperationSignatureFactory } from '@/object-record/graphql/types/RecordGqlOperationSignatureFactory'; + +export const createOneActivityOperationSignatureFactory: RecordGqlOperationSignatureFactory = + ({ objectNameSingular }: { objectNameSingular: CoreObjectNameSingular }) => + objectNameSingular === CoreObjectNameSingular.Note + ? { + objectNameSingular: CoreObjectNameSingular.Note, + variables: {}, + fields: { + id: true, + __typename: true, + createdAt: true, + updatedAt: true, + attachments: true, + body: true, + title: true, + }, + } + : { + objectNameSingular: CoreObjectNameSingular.Task, + variables: {}, + fields: { + id: true, + __typename: true, + createdAt: true, + updatedAt: true, + assigneeId: true, + assignee: { + id: true, + name: true, + __typename: true, + }, + attachments: true, + body: true, + title: true, + status: true, + dueAt: true, + }, + }; diff --git a/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivitiesOperationSignatureFactory.ts b/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivitiesOperationSignatureFactory.ts index 6dca7c5da..36f9096ac 100644 --- a/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivitiesOperationSignatureFactory.ts +++ b/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivitiesOperationSignatureFactory.ts @@ -4,8 +4,14 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { RecordGqlOperationSignatureFactory } from '@/object-record/graphql/types/RecordGqlOperationSignatureFactory'; export const findActivitiesOperationSignatureFactory: RecordGqlOperationSignatureFactory = - ({ objectMetadataItems }: { objectMetadataItems: ObjectMetadataItem[] }) => ({ - objectNameSingular: CoreObjectNameSingular.Activity, + ({ + objectMetadataItems, + objectNameSingular, + }: { + objectMetadataItems: ObjectMetadataItem[]; + objectNameSingular: CoreObjectNameSingular; + }) => ({ + objectNameSingular: objectNameSingular, variables: {}, fields: { id: true, @@ -28,18 +34,32 @@ export const findActivitiesOperationSignatureFactory: RecordGqlOperationSignatur attachments: true, body: true, title: true, - completedAt: true, + status: true, dueAt: true, reminderAt: true, type: true, - activityTargets: { - id: true, - __typename: true, - createdAt: true, - updatedAt: true, - activity: true, - activityId: true, - ...generateActivityTargetMorphFieldKeys(objectMetadataItems), - }, + ...(objectNameSingular === CoreObjectNameSingular.Note + ? { + noteTargets: { + id: true, + __typename: true, + createdAt: true, + updatedAt: true, + note: true, + noteId: true, + ...generateActivityTargetMorphFieldKeys(objectMetadataItems), + }, + } + : { + taskTargets: { + id: true, + __typename: true, + createdAt: true, + updatedAt: true, + task: true, + taskId: true, + ...generateActivityTargetMorphFieldKeys(objectMetadataItems), + }, + }), }, }); diff --git a/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivityTargetsOperationSignatureFactory.ts b/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivityTargetsOperationSignatureFactory.ts index 259550ce5..f71407866 100644 --- a/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivityTargetsOperationSignatureFactory.ts +++ b/packages/twenty-front/src/modules/activities/graphql/operation-signatures/factories/findActivityTargetsOperationSignatureFactory.ts @@ -1,11 +1,18 @@ import { generateActivityTargetMorphFieldKeys } from '@/activities/utils/generateActivityTargetMorphFieldKeys'; +import { getJoinObjectNameSingular } from '@/activities/utils/getJoinObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { RecordGqlOperationSignatureFactory } from '@/object-record/graphql/types/RecordGqlOperationSignatureFactory'; export const findActivityTargetsOperationSignatureFactory: RecordGqlOperationSignatureFactory = - ({ objectMetadataItems }: { objectMetadataItems: ObjectMetadataItem[] }) => ({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, + ({ + objectNameSingular, + objectMetadataItems, + }: { + objectNameSingular: CoreObjectNameSingular; + objectMetadataItems: ObjectMetadataItem[]; + }) => ({ + objectNameSingular: getJoinObjectNameSingular(objectNameSingular), variables: {}, fields: { id: true, diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx index 723a6f82e..1f2dbf62c 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivities.test.tsx @@ -6,6 +6,7 @@ import { RecoilRoot, useSetRecoilState } from 'recoil'; import { useActivities } from '@/activities/hooks/useActivities'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope'; import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members'; @@ -20,16 +21,14 @@ const mockActivityTarget = { }; const mockActivity = { - __typename: 'Activity', + __typename: 'Note', updatedAt: '2021-08-03T19:20:06.000Z', createdAt: '2021-08-03T19:20:06.000Z', - completedAt: '2021-08-03T19:20:06.000Z', + status: 'DONE', reminderAt: '2021-08-03T19:20:06.000Z', title: 'title', - authorId: '1', body: 'body', dueAt: '2021-08-03T19:20:06.000Z', - type: 'type', assigneeId: '1', id: '234', }; @@ -102,13 +101,13 @@ const mocks: MockedResponse[] = [ { request: { query: gql` - query FindManyActivities( - $filter: ActivityFilterInput - $orderBy: [ActivityOrderByInput] + query FindManyTasks( + $filter: TaskFilterInput + $orderBy: [TaskOrderByInput] $lastCursor: String $limit: Int ) { - activities( + tasks( filter: $filter orderBy: $orderBy first: $limit @@ -117,17 +116,13 @@ const mocks: MockedResponse[] = [ edges { node { __typename - createdAt - reminderAt - authorId title - completedAt - updatedAt - body - dueAt - type id - assigneeId + updatedAt + createdAt + body + status + dueAt } cursor } @@ -178,6 +173,7 @@ describe('useActivities', () => { const { result } = renderHook( () => useActivities({ + objectNameSingular: CoreObjectNameSingular.Task, targetableObjects: [], activitiesFilters: {}, activitiesOrderByVariables: [{}], @@ -200,6 +196,7 @@ describe('useActivities', () => { ); const activities = useActivities({ + objectNameSingular: CoreObjectNameSingular.Task, targetableObjects: [ { targetObjectNameSingular: 'company', id: '123' }, ], diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx index 6d161906d..15b40d17f 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetObjectRecords.test.tsx @@ -7,8 +7,8 @@ import { RecoilRoot, useSetRecoilState } from 'recoil'; import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock'; -import { getRecordFromRecordNode } from '@/object-record/cache/utils/getRecordFromRecordNode'; import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope'; import { JestObjectMetadataItemSetter } from '~/testing/jest/JestObjectMetadataItemSetter'; import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members'; @@ -16,108 +16,95 @@ const mockObjectMetadataItems = getObjectMetadataItemsMock(); const cache = new InMemoryCache(); -const activityNode = { - id: '3ecaa1be-aac7-463a-a38e-64078dd451d5', +const taskTarget = { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb300', createdAt: '2023-04-26T10:12:42.33625+00:00', updatedAt: '2023-04-26T10:23:42.33625+00:00', - reminderAt: null, - title: 'My very first note', - type: 'Note', - body: '', - dueAt: '2023-04-26T10:12:42.33625+00:00', - completedAt: null, - author: null, - assignee: null, - assigneeId: null, - authorId: null, - comments: { - edges: [], + companyId: null, + company: null, + personId: '89bb825c-171e-4bcc-9cf7-43448d6fb280', + person: { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb280', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + city: 'City', + name: { + firstName: 'John', + lastName: 'Doe', + }, + __typename: 'Person', }, - activityTargets: { - edges: [ - { - node: { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb300', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - personId: null, - companyId: '89bb825c-171e-4bcc-9cf7-43448d6fb280', - company: { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb280', - name: 'Airbnb', - domainName: { - primaryLinkUrl: 'https://www.airbnb.com', - primaryLinkLabel: '', - secondaryLinks: null, - }, - }, - person: null, - activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb230', - activity: { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - }, - __typename: 'ActivityTarget', - }, - __typename: 'ActivityTargetEdge', - }, - ], - __typename: 'ActivityTargetConnection', + taskId: '89bb825c-171e-4bcc-9cf7-43448d6fb230', + task: { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + dueAt: null, + body: '{}', + title: 'Task title', + assigneeId: null, + __typename: 'Task', }, - __typename: 'Activity' as const, + __typename: 'TaskTarget', }; cache.writeFragment({ fragment: gql` - fragment CreateOneActivityInCache on Activity { - id - createdAt + fragment TaskTargetFragment on TaskTarget { + __typename updatedAt - reminderAt - title - body - dueAt - completedAt - author - assignee - assigneeId - authorId - activityTargets { - edges { - node { - id - createdAt - updatedAt - personId - companyId - company { - id - name - domainName { - primaryLinkUrl - primaryLinkLabel - secondaryLinks - } - } - person - activityId - activity { - id - createdAt - updatedAt - } - __typename - } + createdAt + personId + taskId + companyId + id + task { + __typename + createdAt + title + updatedAt + body + dueAt + id + assigneeId + } + person { + __typename + id + createdAt + updatedAt + city + name { + firstName + lastName } } - __typename + company { + __typename + id + createdAt + updatedAt + } } `, - id: activityNode.id, - data: activityNode, + id: `TaskTarget:${taskTarget.id}`, + data: taskTarget, }); +const task = { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + title: 'Task title', + body: null, + assigneeId: null, + status: null, + dueAt: '2023-04-26T10:12:42.33625+00:00', + assignee: null, + __typename: 'Task' as any, + taskTargets: [taskTarget], +}; + const Wrapper = ({ children }: { children: ReactNode }) => ( @@ -142,7 +129,8 @@ describe('useActivityTargetObjectRecords', () => { ); const { activityTargetObjectRecords } = useActivityTargetObjectRecords( - getRecordFromRecordNode({ recordNode: activityNode as any }), + task, + CoreObjectNameSingular.Task, ); return { @@ -158,18 +146,17 @@ describe('useActivityTargetObjectRecords', () => { result.current.setCurrentWorkspaceMember(mockWorkspaceMembers[0]); result.current.setObjectMetadataItems(mockObjectMetadataItems); }); + const activityTargetObjectRecords = result.current.activityTargetObjectRecords; expect(activityTargetObjectRecords).toHaveLength(1); - expect(activityTargetObjectRecords[0].activityTarget).toEqual( - activityNode.activityTargets.edges[0].node, - ); + expect(activityTargetObjectRecords[0].activityTarget).toEqual(taskTarget); expect(activityTargetObjectRecords[0].targetObject).toEqual( - activityNode.activityTargets.edges[0].node.company, + taskTarget.person, ); expect( activityTargetObjectRecords[0].targetObjectMetadataItem.nameSingular, - ).toEqual('company'); + ).toEqual('person'); }); }); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx deleted file mode 100644 index 3d833e3c2..000000000 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useActivityTargetsForTargetableObject.test.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import { MockedProvider, MockedResponse } from '@apollo/client/testing'; -import { act, renderHook, waitFor } from '@testing-library/react'; -import gql from 'graphql-tag'; -import { ReactNode } from 'react'; -import { RecoilRoot, useSetRecoilState } from 'recoil'; - -import { useActivityTargetsForTargetableObject } from '@/activities/hooks/useActivityTargetsForTargetableObject'; -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope'; -import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members'; - -const mockActivityTarget = { - __typename: 'ActivityTarget', - updatedAt: '2021-08-03T19:20:06.000Z', - createdAt: '2021-08-03T19:20:06.000Z', - personId: '1', - activityId: '234', - companyId: '1', - id: '123', -}; - -const defaultResponseData = { - pageInfo: { - hasNextPage: false, - startCursor: '', - endCursor: '', - }, - totalCount: 1, -}; - -const mocks: MockedResponse[] = [ - { - request: { - query: gql` - query FindManyActivityTargets( - $filter: ActivityTargetFilterInput - $orderBy: [ActivityTargetOrderByInput] - $lastCursor: String - $limit: Int - ) { - activityTargets( - filter: $filter - orderBy: $orderBy - first: $limit - after: $lastCursor - ) { - edges { - node { - __typename - updatedAt - createdAt - personId - activityId - companyId - id - } - cursor - } - pageInfo { - hasNextPage - hasPreviousPage - startCursor - endCursor - } - totalCount - } - } - `, - variables: { - filter: { personId: { eq: '1234' } }, - orderBy: undefined, - lastCursor: undefined, - limit: undefined, - }, - }, - result: jest.fn(() => ({ - data: { - activityTargets: { - ...defaultResponseData, - edges: [ - { - node: mockActivityTarget, - cursor: '1', - }, - ], - }, - }, - })), - }, -]; - -const Wrapper = ({ children }: { children: ReactNode }) => ( - - - - {children} - - - -); - -describe('useActivityTargetsForTargetableObject', () => { - it('works as expected', async () => { - const { result } = renderHook( - () => { - const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState, - ); - - const res = useActivityTargetsForTargetableObject({ - targetableObject: { - id: '1234', - targetObjectNameSingular: 'person', - }, - }); - return { ...res, setCurrentWorkspaceMember }; - }, - { wrapper: Wrapper }, - ); - - act(() => { - result.current.setCurrentWorkspaceMember(mockWorkspaceMembers[0]); - }); - - expect(result.current.loadingActivityTargets).toBe(true); - - await waitFor(() => !result.current.loadingActivityTargets); - - expect(result.current.activityTargets).toEqual([mockActivityTarget]); - }); -}); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx deleted file mode 100644 index ca824d267..000000000 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInCache.test.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { ReactNode } from 'react'; -import { MockedProvider, MockedResponse } from '@apollo/client/testing'; -import { act, renderHook } from '@testing-library/react'; -import gql from 'graphql-tag'; -import { RecoilRoot, useSetRecoilState } from 'recoil'; - -import { useCreateActivityInCache } from '@/activities/hooks/useCreateActivityInCache'; -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope'; -import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members'; - -const mocks: MockedResponse[] = [ - { - request: { - query: gql` - query FindOneWorkspaceMember($objectRecordId: ID!) { - workspaceMember(filter: { id: { eq: $objectRecordId } }) { - __typename - colorScheme - name { - firstName - lastName - } - locale - userId - avatarUrl - createdAt - updatedAt - id - } - } - `, - variables: { objectRecordId: '20202020-1553-45c6-a028-5a9064cce07f' }, - }, - result: jest.fn(() => ({ - data: { - workspaceMember: mockWorkspaceMembers[0], - }, - })), - }, -]; - -const Wrapper = ({ children }: { children: ReactNode }) => ( - - - - {children} - - - -); - -const mockObjectMetadataItems = getObjectMetadataItemsMock(); - -describe('useCreateActivityInCache', () => { - it('Should create activity in cache', async () => { - const { result } = renderHook( - () => { - const setCurrentWorkspaceMember = useSetRecoilState( - currentWorkspaceMemberState, - ); - const setObjectMetadataItems = useSetRecoilState( - objectMetadataItemsState, - ); - const setRecordStore = useSetRecoilState( - recordStoreFamilyState('1234'), - ); - - const res = useCreateActivityInCache(); - return { - ...res, - setCurrentWorkspaceMember, - setObjectMetadataItems, - setRecordStore, - }; - }, - { wrapper: Wrapper }, - ); - - act(() => { - result.current.setRecordStore({ - id: '1234', - __typename: 'Person', - }); - result.current.setCurrentWorkspaceMember(mockWorkspaceMembers[0]); - result.current.setObjectMetadataItems(mockObjectMetadataItems); - }); - - act(() => { - const res = result.current.createActivityInCache({ - type: 'Note', - targetObject: { - targetObjectNameSingular: 'person', - id: '1234', - }, - }); - - expect(res.createdActivityInCache).toHaveProperty('id'); - expect(res.createdActivityInCache).toHaveProperty('__typename'); - expect(res.createdActivityInCache).toHaveProperty('activityTargets'); - }); - }); -}); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInDB.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInDB.test.tsx index 8967e9859..b136aaed5 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInDB.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useCreateActivityInDB.test.tsx @@ -6,22 +6,16 @@ import { ReactNode } from 'react'; import { RecoilRoot } from 'recoil'; import { useCreateActivityInDB } from '@/activities/hooks/useCreateActivityInDB'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope'; -import { mockedActivities } from '~/testing/mock-data/activities'; +import { mockedTasks } from '~/testing/mock-data/tasks'; const mockedDate = '2024-03-15T12:00:00.000Z'; const toISOStringMock = jest.fn(() => mockedDate); global.Date.prototype.toISOString = toISOStringMock; const mockedActivity = { - ...pick(mockedActivities[0], [ - 'id', - 'title', - 'body', - 'type', - 'completedAt', - 'dueAt', - ]), + ...pick(mockedTasks[0], ['id', 'title', 'body', 'type', 'status', 'dueAt']), updatedAt: mockedDate, }; @@ -36,7 +30,7 @@ const mocks: MockedResponse[] = [ reminderAt authorId title - completedAt + status updatedAt body dueAt @@ -77,14 +71,19 @@ const Wrapper = ({ children }: { children: ReactNode }) => ( describe('useCreateActivityInDB', () => { it('Should create activity in DB', async () => { - const { result } = renderHook(() => useCreateActivityInDB(), { - wrapper: Wrapper, - }); + const { result } = renderHook( + () => + useCreateActivityInDB({ + activityObjectNameSingular: CoreObjectNameSingular.Task, + }), + { + wrapper: Wrapper, + }, + ); await act(async () => { await result.current.createActivityInDB({ ...mockedActivity, - __typename: 'Activity', }); }); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx index 1294d6ca2..81a6b61da 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenActivityRightDrawer.test.tsx @@ -1,10 +1,10 @@ -import { ReactNode } from 'react'; import { MockedProvider } from '@apollo/client/testing'; import { act, renderHook } from '@testing-library/react'; +import { ReactNode } from 'react'; import { RecoilRoot, useRecoilValue } from 'recoil'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; -import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; const Wrapper = ({ children }: { children: ReactNode }) => ( @@ -17,12 +17,12 @@ describe('useOpenActivityRightDrawer', () => { it('works as expected', () => { const { result } = renderHook( () => { - const openActivityRightDrawer = useOpenActivityRightDrawer(); + const openActivityRightDrawer = useOpenActivityRightDrawer({ + objectNameSingular: CoreObjectNameSingular.Task, + }); const viewableRecordId = useRecoilValue(viewableRecordIdState); - const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); return { openActivityRightDrawer, - activityIdInDrawer, viewableRecordId, }; }, @@ -31,12 +31,10 @@ describe('useOpenActivityRightDrawer', () => { }, ); - expect(result.current.activityIdInDrawer).toBeNull(); expect(result.current.viewableRecordId).toBeNull(); act(() => { result.current.openActivityRightDrawer('123'); }); - expect(result.current.activityIdInDrawer).toBe('123'); expect(result.current.viewableRecordId).toBe('123'); }); }); diff --git a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx index b545e455c..9b03ac5e5 100644 --- a/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx +++ b/packages/twenty-front/src/modules/activities/hooks/__tests__/useOpenCreateActivityDrawer.test.tsx @@ -1,23 +1,71 @@ -import { ReactNode } from 'react'; -import { MockedProvider } from '@apollo/client/testing'; +import { MockedProvider, MockedResponse } from '@apollo/client/testing'; import { act, renderHook } from '@testing-library/react'; +import { ReactNode } from 'react'; import { RecoilRoot, useRecoilValue, useSetRecoilState } from 'recoil'; import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; -import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock'; import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; +import gql from 'graphql-tag'; +import pick from 'lodash.pick'; +import { mockedTasks } from '~/testing/mock-data/tasks'; -const mockUUID = '37873e04-2f83-4468-9ab7-3f87da6cafad'; +const mockedDate = '2024-03-15T12:00:00.000Z'; +const toISOStringMock = jest.fn(() => mockedDate); +global.Date.prototype.toISOString = toISOStringMock; -jest.mock('uuid', () => ({ - v4: () => mockUUID, -})); +const mockedActivity = { + ...pick(mockedTasks[0], ['id', 'title', 'body', 'type', 'status', 'dueAt']), + updatedAt: mockedDate, +}; + +const mocks: MockedResponse[] = [ + { + request: { + query: gql` + mutation CreateOneActivity($input: ActivityCreateInput!) { + createActivity(data: $input) { + __typename + createdAt + reminderAt + authorId + title + status + updatedAt + body + dueAt + type + id + assigneeId + } + } + `, + variables: { + input: mockedActivity, + }, + }, + result: jest.fn(() => ({ + data: { + createActivity: { + ...mockedActivity, + __typename: 'Activity', + assigneeId: '', + authorId: '1', + reminderAt: null, + createdAt: mockedDate, + }, + }, + })), + }, +]; const Wrapper = ({ children }: { children: ReactNode }) => ( - {children} + + {children} + ); @@ -27,15 +75,15 @@ describe('useOpenCreateActivityDrawer', () => { it('works as expected', async () => { const { result } = renderHook( () => { - const openActivityRightDrawer = useOpenCreateActivityDrawer(); + const openActivityRightDrawer = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Note, + }); const viewableRecordId = useRecoilValue(viewableRecordIdState); - const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); const setObjectMetadataItems = useSetRecoilState( objectMetadataItemsState, ); return { openActivityRightDrawer, - activityIdInDrawer, viewableRecordId, setObjectMetadataItems, }; @@ -49,15 +97,11 @@ describe('useOpenCreateActivityDrawer', () => { result.current.setObjectMetadataItems(mockObjectMetadataItems); }); - expect(result.current.activityIdInDrawer).toBeNull(); expect(result.current.viewableRecordId).toBeNull(); await act(async () => { result.current.openActivityRightDrawer({ - type: 'Note', targetableObjects: [], }); }); - expect(result.current.activityIdInDrawer).toBe(mockUUID); - expect(result.current.viewableRecordId).toBe(mockUUID); }); }); diff --git a/packages/twenty-front/src/modules/activities/hooks/useActivities.ts b/packages/twenty-front/src/modules/activities/hooks/useActivities.ts index ee253bf87..d63109339 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useActivities.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useActivities.ts @@ -3,21 +3,25 @@ import { useRecoilCallback } from 'recoil'; import { findActivitiesOperationSignatureFactory } from '@/activities/graphql/operation-signatures/factories/findActivitiesOperationSignatureFactory'; import { useActivityTargetsForTargetableObjects } from '@/activities/hooks/useActivityTargetsForTargetableObjects'; -import { Activity } from '@/activities/types/Activity'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { Note } from '@/activities/types/Note'; +import { Task } from '@/activities/types/Task'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { RecordGqlOperationFilter } from '@/object-record/graphql/types/RecordGqlOperationFilter'; import { RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { sortByAscString } from '~/utils/array/sortByAscString'; -export const useActivities = ({ +export const useActivities = ({ + objectNameSingular, targetableObjects, activitiesFilters, activitiesOrderByVariables, skip, }: { + objectNameSingular: CoreObjectNameSingular; targetableObjects: ActivityTargetableObject[]; activitiesFilters: RecordGqlOperationFilter; activitiesOrderByVariables: RecordGqlOperationOrderBy; @@ -27,6 +31,7 @@ export const useActivities = ({ const { activityTargets, loadingActivityTargets } = useActivityTargetsForTargetableObjects({ + objectNameSingular, targetableObjects, skip: skip, }); @@ -36,7 +41,10 @@ export const useActivities = ({ activityTargets ? [ ...activityTargets - .map((activityTarget) => activityTarget.activityId) + .map( + (activityTarget) => + activityTarget.taskId ?? activityTarget.noteId, + ) .filter(isNonEmptyString), ].sort(sortByAscString) : [], @@ -54,10 +62,13 @@ export const useActivities = ({ }; const FIND_ACTIVITIES_OPERATION_SIGNATURE = - findActivitiesOperationSignatureFactory({ objectMetadataItems }); + findActivitiesOperationSignatureFactory({ + objectMetadataItems, + objectNameSingular, + }); const { records: activities, loading: loadingActivities } = - useFindManyRecords({ + useFindManyRecords({ skip: skip || loadingActivityTargets, objectNameSingular: FIND_ACTIVITIES_OPERATION_SIGNATURE.objectNameSingular, @@ -76,7 +87,7 @@ export const useActivities = ({ }); return { - activities, + activities: activities as T[], loading: loadingActivities || loadingActivityTargets, }; }; diff --git a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts b/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts index 2670e4270..2fe34d8c2 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useActivityTargetObjectRecords.ts @@ -2,31 +2,41 @@ import { useApolloClient } from '@apollo/client'; import { useRecoilValue } from 'recoil'; import { Nullable } from 'twenty-ui'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject'; +import { Note } from '@/activities/types/Note'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { Task } from '@/activities/types/Task'; +import { TaskTarget } from '@/activities/types/TaskTarget'; +import { getJoinObjectNameSingular } from '@/activities/utils/getJoinObjectNameSingular'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache'; import { isDefined } from '~/utils/isDefined'; -export const useActivityTargetObjectRecords = (activity: Activity) => { +export const useActivityTargetObjectRecords = ( + activity: Task | Note, + objectNameSingular: CoreObjectNameSingular, +) => { const objectMetadataItems = useRecoilValue(objectMetadataItemsState); - const activityTargets = activity.activityTargets ?? []; + const activityTargets = + 'noteTargets' in activity && activity.noteTargets + ? activity.noteTargets + : 'taskTargets' in activity && activity.taskTargets + ? activity.taskTargets + : []; const getRecordFromCache = useGetRecordFromCache({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, + objectNameSingular: getJoinObjectNameSingular(objectNameSingular), }); const apolloClient = useApolloClient(); const activityTargetObjectRecords = activityTargets .map>((activityTarget) => { - const activityTargetFromCache = getRecordFromCache( - activityTarget.id, - apolloClient.cache, - ); + const activityTargetFromCache = getRecordFromCache< + NoteTarget | TaskTarget + >(activityTarget.id, apolloClient.cache); if (!isDefined(activityTargetFromCache)) { throw new Error( @@ -37,7 +47,9 @@ export const useActivityTargetObjectRecords = (activity: Activity) => { const correspondingObjectMetadataItem = objectMetadataItems.find( (objectMetadataItem) => isDefined(activityTargetFromCache[objectMetadataItem.nameSingular]) && - !objectMetadataItem.isSystem, + ![CoreObjectNameSingular.Note, CoreObjectNameSingular.Task].includes( + objectMetadataItem.nameSingular as CoreObjectNameSingular, + ), ); if (!correspondingObjectMetadataItem) { diff --git a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObject.ts b/packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObject.ts deleted file mode 100644 index 159330bbd..000000000 --- a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObject.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { isNonEmptyString } from '@sniptt/guards'; - -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; -import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getActivityTargetObjectFieldIdName'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; - -export const useActivityTargetsForTargetableObject = ({ - targetableObject, -}: { - targetableObject: ActivityTargetableObject; -}) => { - const targetObjectFieldName = getActivityTargetObjectFieldIdName({ - nameSingular: targetableObject.targetObjectNameSingular, - }); - - const targetableObjectId = targetableObject.id; - - const skipRequest = !isNonEmptyString(targetableObjectId); - - // TODO: We want to optimistically remove from this request - // If we are on a show page and we remove the current show page object corresponding activity target - // See also if we need to update useTimelineActivities - const { records: activityTargets, loading: loadingActivityTargets } = - useFindManyRecords({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, - skip: skipRequest, - filter: { - [targetObjectFieldName]: { - eq: targetableObject.id, - }, - }, - }); - - return { - activityTargets, - loadingActivityTargets, - }; -}; diff --git a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObjects.ts b/packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObjects.ts index 4d1985808..6f71ddd80 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObjects.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useActivityTargetsForTargetableObjects.ts @@ -1,23 +1,27 @@ import { useRecoilValue } from 'recoil'; import { findActivityTargetsOperationSignatureFactory } from '@/activities/graphql/operation-signatures/factories/findActivityTargetsOperationSignatureFactory'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { TaskTarget } from '@/activities/types/TaskTarget'; import { getActivityTargetsFilter } from '@/activities/utils/getActivityTargetsFilter'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; export const useActivityTargetsForTargetableObjects = ({ + objectNameSingular, targetableObjects, skip, onCompleted, }: { + objectNameSingular: CoreObjectNameSingular; targetableObjects: Pick< ActivityTargetableObject, 'id' | 'targetObjectNameSingular' >[]; skip?: boolean; - onCompleted?: (activityTargets: ActivityTarget[]) => void; + onCompleted?: (activityTargets: (TaskTarget | NoteTarget)[]) => void; }) => { const activityTargetsFilter = getActivityTargetsFilter({ targetableObjects: targetableObjects, @@ -26,13 +30,16 @@ export const useActivityTargetsForTargetableObjects = ({ const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const FIND_ACTIVITY_TARGETS_OPERATION_SIGNATURE = - findActivityTargetsOperationSignatureFactory({ objectMetadataItems }); + findActivityTargetsOperationSignatureFactory({ + objectNameSingular, + objectMetadataItems, + }); // TODO: We want to optimistically remove from this request // If we are on a show page and we remove the current show page object corresponding activity target // See also if we need to update useTimelineActivities const { records: activityTargets, loading: loadingActivityTargets } = - useFindManyRecords({ + useFindManyRecords({ skip, objectNameSingular: FIND_ACTIVITY_TARGETS_OPERATION_SIGNATURE.objectNameSingular, diff --git a/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts b/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts deleted file mode 100644 index d90953473..000000000 --- a/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInCache.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { Reference, useApolloClient } from '@apollo/client'; -import { useRecoilCallback, useRecoilValue } from 'recoil'; -import { v4 } from 'uuid'; - -import { Activity, ActivityType } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; -import { makeActivityTargetsToCreateFromTargetableObjects } from '@/activities/utils/getActivityTargetsToCreateFromTargetableObjects'; -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; -import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useCreateManyRecordsInCache } from '@/object-record/cache/hooks/useCreateManyRecordsInCache'; -import { useCreateOneRecordInCache } from '@/object-record/cache/hooks/useCreateOneRecordInCache'; -import { getRecordConnectionFromRecords } from '@/object-record/cache/utils/getRecordConnectionFromRecords'; -import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache'; -import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; -import { isDefined } from '~/utils/isDefined'; -import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; - -export const useCreateActivityInCache = () => { - const { createManyRecordsInCache: createManyActivityTargetsInCache } = - useCreateManyRecordsInCache({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, - }); - - const cache = useApolloClient().cache; - - const objectMetadataItems = useRecoilValue(objectMetadataItemsState); - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - - const { record: currentWorkspaceMemberRecord } = useFindOneRecord({ - objectNameSingular: CoreObjectNameSingular.WorkspaceMember, - objectRecordId: currentWorkspaceMember?.id, - }); - - const { objectMetadataItem: objectMetadataItemActivity } = - useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.Activity, - }); - - const { objectMetadataItem: objectMetadataItemActivityTarget } = - useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, - }); - - const createOneActivityInCache = useCreateOneRecordInCache({ - objectMetadataItem: objectMetadataItemActivity, - }); - - const createActivityInCache = useRecoilCallback( - ({ snapshot, set }) => - ({ - type, - targetObject, - customAssignee, - }: { - type: ActivityType; - targetObject?: ActivityTargetableObject; - customAssignee?: WorkspaceMember; - }) => { - const activityId = v4(); - - const createdActivityInCache = createOneActivityInCache({ - id: activityId, - __typename: 'Activity', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - author: currentWorkspaceMemberRecord, - authorId: currentWorkspaceMemberRecord?.id, - assignee: customAssignee ?? currentWorkspaceMemberRecord, - assigneeId: customAssignee?.id ?? currentWorkspaceMemberRecord?.id, - type, - }); - - if (isUndefinedOrNull(createdActivityInCache)) { - throw new Error('Failed to create activity in cache'); - } - - if (isUndefinedOrNull(targetObject)) { - set(recordStoreFamilyState(activityId), { - ...createdActivityInCache, - activityTargets: [], - comments: [], - }); - - return { - createdActivityInCache: { - ...createdActivityInCache, - activityTargets: [], - }, - }; - } - - const targetObjectRecord = snapshot - .getLoadable(recordStoreFamilyState(targetObject.id)) - .getValue(); - - if (isUndefinedOrNull(targetObjectRecord)) { - throw new Error('Failed to find target object record'); - } - - const activityTargetsToCreate = - makeActivityTargetsToCreateFromTargetableObjects({ - activity: createdActivityInCache, - targetableObjects: [targetObject], - targetObjectRecords: [targetObjectRecord], - }); - - const createdActivityTargetsInCache = createManyActivityTargetsInCache( - activityTargetsToCreate, - ); - - const activityTargetsConnection = getRecordConnectionFromRecords({ - objectMetadataItems: objectMetadataItems, - objectMetadataItem: objectMetadataItemActivityTarget, - records: createdActivityTargetsInCache, - withPageInfo: false, - computeReferences: true, - isRootLevel: false, - }); - - modifyRecordFromCache({ - recordId: createdActivityInCache.id, - cache, - fieldModifiers: { - activityTargets: () => activityTargetsConnection, - }, - objectMetadataItem: objectMetadataItemActivity, - }); - - const targetObjectMetadataItem = objectMetadataItems.find( - (item) => item.nameSingular === targetObject.targetObjectNameSingular, - ); - - if (isDefined(targetObjectMetadataItem)) { - modifyRecordFromCache({ - cache, - objectMetadataItem: targetObjectMetadataItem, - recordId: targetObject.id, - fieldModifiers: { - activityTargets: (activityTargetsRef, { readField }) => { - const edges = readField<{ node: Reference }[]>( - 'edges', - activityTargetsRef, - ); - - if (!edges) return activityTargetsRef; - - return { - ...activityTargetsRef, - edges: [...edges, ...activityTargetsConnection.edges], - }; - }, - }, - }); - } - - set(recordStoreFamilyState(activityId), { - ...createdActivityInCache, - activityTargets: createdActivityTargetsInCache, - comments: [], - }); - - return { - createdActivityInCache: { - ...createdActivityInCache, - activityTargets: createdActivityTargetsInCache, - }, - }; - }, - [ - createOneActivityInCache, - currentWorkspaceMemberRecord, - createManyActivityTargetsInCache, - objectMetadataItems, - objectMetadataItemActivityTarget, - cache, - objectMetadataItemActivity, - ], - ); - - return { - createActivityInCache, - }; -}; diff --git a/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInDB.ts b/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInDB.ts index 470e9fda0..7408e208a 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInDB.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useCreateActivityInDB.ts @@ -1,8 +1,6 @@ import { isNonEmptyArray } from '@sniptt/guards'; -import { CREATE_ONE_ACTIVITY_OPERATION_SIGNATURE } from '@/activities/graphql/operation-signatures/CreateOneActivityOperationSignature'; import { ActivityForEditor } from '@/activities/types/ActivityForEditor'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; @@ -13,33 +11,48 @@ import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { useApolloClient } from '@apollo/client'; +import { createOneActivityOperationSignatureFactory } from '@/activities/graphql/operation-signatures/factories/createOneActivityOperationSignatureFactory'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { TaskTarget } from '@/activities/types/TaskTarget'; +import { getJoinObjectNameSingular } from '@/activities/utils/getJoinObjectNameSingular'; import { useRecoilCallback } from 'recoil'; import { capitalize } from '~/utils/string/capitalize'; -export const useCreateActivityInDB = () => { +export const useCreateActivityInDB = ({ + activityObjectNameSingular, +}: { + activityObjectNameSingular: + | CoreObjectNameSingular.Task + | CoreObjectNameSingular.Note; +}) => { + const createOneActivityOperationSignature = + createOneActivityOperationSignatureFactory({ + objectNameSingular: activityObjectNameSingular, + }); + const { createOneRecord: createOneActivity } = useCreateOneRecord({ - objectNameSingular: - CREATE_ONE_ACTIVITY_OPERATION_SIGNATURE.objectNameSingular, - recordGqlFields: CREATE_ONE_ACTIVITY_OPERATION_SIGNATURE.fields, + objectNameSingular: activityObjectNameSingular, + recordGqlFields: createOneActivityOperationSignature.fields, shouldMatchRootQueryFilter: true, }); - const { createManyRecords: createManyActivityTargets } = - useCreateManyRecords({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, - shouldMatchRootQueryFilter: true, - }); + const { createManyRecords: createManyActivityTargets } = useCreateManyRecords< + TaskTarget | NoteTarget + >({ + objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular), + shouldMatchRootQueryFilter: true, + }); const { objectMetadataItems } = useObjectMetadataItems(); const { objectMetadataItem: objectMetadataItemActivityTarget } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, + objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular), }); const { objectMetadataItem: objectMetadataItemActivity } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.Activity, + objectNameSingular: activityObjectNameSingular, }); const cache = useApolloClient().cache; @@ -52,7 +65,8 @@ export const useCreateActivityInDB = () => { updatedAt: new Date().toISOString(), }); - const activityTargetsToCreate = activityToCreate.activityTargets ?? []; + const activityTargetsToCreate = + activityToCreate.noteTargets ?? activityToCreate.taskTargets ?? []; if (isNonEmptyArray(activityTargetsToCreate)) { await createManyActivityTargets(activityTargetsToCreate); diff --git a/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts b/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts index 185661f2a..9abed7130 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts @@ -1,25 +1,34 @@ import { useRecoilState, useSetRecoilState } from 'recoil'; -import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; +import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope'; import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; -export const useOpenActivityRightDrawer = () => { +export const useOpenActivityRightDrawer = ({ + objectNameSingular, +}: { + objectNameSingular: CoreObjectNameSingular; +}) => { const { openRightDrawer, isRightDrawerOpen, rightDrawerPage } = useRightDrawer(); const [viewableRecordId, setViewableRecordId] = useRecoilState( viewableRecordIdState, ); - const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); + + const setViewableRecordNameSingular = useSetRecoilState( + viewableRecordNameSingularState, + ); + const setHotkeyScope = useSetHotkeyScope(); return (activityId: string) => { if ( isRightDrawerOpen && - rightDrawerPage === RightDrawerPages.EditActivity && + rightDrawerPage === RightDrawerPages.ViewRecord && viewableRecordId === activityId ) { return; @@ -27,7 +36,7 @@ export const useOpenActivityRightDrawer = () => { setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); setViewableRecordId(activityId); - setActivityIdInDrawer(activityId); - openRightDrawer(RightDrawerPages.EditActivity); + setViewableRecordNameSingular(objectNameSingular); + openRightDrawer(RightDrawerPages.ViewRecord); }; }; diff --git a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts index d85646096..e8fb4f366 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts @@ -1,12 +1,7 @@ -import { useRecoilState, useSetRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; -import { useCreateActivityInCache } from '@/activities/hooks/useCreateActivityInCache'; -import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState'; import { activityTargetableEntityArrayState } from '@/activities/states/activityTargetableEntityArrayState'; -import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState'; import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState'; -import { temporaryActivityForEditorState } from '@/activities/states/temporaryActivityForEditorState'; -import { ActivityType } from '@/activities/types/Activity'; import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope'; @@ -14,54 +9,84 @@ import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPage import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; +import { Note } from '@/activities/types/Note'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { Task } from '@/activities/types/Task'; +import { TaskTarget } from '@/activities/types/TaskTarget'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; +import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState'; import { ActivityTargetableObject } from '../types/ActivityTargetableEntity'; -export const useOpenCreateActivityDrawer = () => { +export const useOpenCreateActivityDrawer = ({ + activityObjectNameSingular, +}: { + activityObjectNameSingular: + | CoreObjectNameSingular.Note + | CoreObjectNameSingular.Task; +}) => { const { openRightDrawer } = useRightDrawer(); const setHotkeyScope = useSetHotkeyScope(); - const { createActivityInCache } = useCreateActivityInCache(); + const { createOneRecord: createOneActivity } = useCreateOneRecord< + Task | Note + >({ + objectNameSingular: activityObjectNameSingular, + }); + + const { createOneRecord: createOneActivityTarget } = useCreateOneRecord< + TaskTarget | NoteTarget + >({ + objectNameSingular: + activityObjectNameSingular === CoreObjectNameSingular.Task + ? CoreObjectNameSingular.TaskTarget + : CoreObjectNameSingular.NoteTarget, + }); const setActivityTargetableEntityArray = useSetRecoilState( activityTargetableEntityArrayState, ); const setViewableRecordId = useSetRecoilState(viewableRecordIdState); - - const setIsCreatingActivity = useSetRecoilState(isActivityInCreateModeState); - - const setTemporaryActivityForEditor = useSetRecoilState( - temporaryActivityForEditorState, + const setViewableRecordNameSingular = useSetRecoilState( + viewableRecordNameSingularState, ); - const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); - - const [, setIsUpsertingActivityInDB] = useRecoilState( + const setIsUpsertingActivityInDB = useSetRecoilState( isUpsertingActivityInDBState, ); const openCreateActivityDrawer = async ({ - type, targetableObjects, customAssignee, }: { - type: ActivityType; targetableObjects: ActivityTargetableObject[]; customAssignee?: WorkspaceMember; }) => { - const { createdActivityInCache } = createActivityInCache({ - type, - targetObject: targetableObjects[0], - customAssignee, + const activity = await createOneActivity({ + assigneeId: customAssignee?.id, + }); + + const targetableObjectRelationIdName = `${targetableObjects[0].targetObjectNameSingular}Id`; + + await createOneActivityTarget({ + taskId: + activityObjectNameSingular === CoreObjectNameSingular.Task + ? activity.id + : undefined, + noteId: + activityObjectNameSingular === CoreObjectNameSingular.Note + ? activity.id + : undefined, + [targetableObjectRelationIdName]: targetableObjects[0].id, }); - setActivityIdInDrawer(createdActivityInCache.id); - setTemporaryActivityForEditor(createdActivityInCache); - setIsCreatingActivity(true); setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); - setViewableRecordId(createdActivityInCache.id); + setViewableRecordId(activity.id); + setViewableRecordNameSingular(activityObjectNameSingular); setActivityTargetableEntityArray(targetableObjects ?? []); - openRightDrawer(RightDrawerPages.CreateActivity); + + openRightDrawer(RightDrawerPages.ViewRecord); setIsUpsertingActivityInDB(false); }; diff --git a/packages/twenty-front/src/modules/activities/hooks/usePrepareFindManyActivitiesQuery.ts b/packages/twenty-front/src/modules/activities/hooks/usePrepareFindManyActivitiesQuery.ts index 2951b7522..21c5e539b 100644 --- a/packages/twenty-front/src/modules/activities/hooks/usePrepareFindManyActivitiesQuery.ts +++ b/packages/twenty-front/src/modules/activities/hooks/usePrepareFindManyActivitiesQuery.ts @@ -1,9 +1,11 @@ import { useApolloClient } from '@apollo/client'; import { findActivitiesOperationSignatureFactory } from '@/activities/graphql/operation-signatures/factories/findActivitiesOperationSignatureFactory'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { Note } from '@/activities/types/Note'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { Task } from '@/activities/types/Task'; +import { TaskTarget } from '@/activities/types/TaskTarget'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; @@ -14,14 +16,18 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { sortByAscString } from '~/utils/array/sortByAscString'; import { isDefined } from '~/utils/isDefined'; -export const usePrepareFindManyActivitiesQuery = () => { +export const usePrepareFindManyActivitiesQuery = ({ + activityObjectNameSingular, +}: { + activityObjectNameSingular: CoreObjectNameSingular; +}) => { const { objectMetadataItem: objectMetadataItemActivity } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.Activity, + objectNameSingular: activityObjectNameSingular, }); const getActivityFromCache = useGetRecordFromCache({ - objectNameSingular: CoreObjectNameSingular.Activity, + objectNameSingular: activityObjectNameSingular, }); const cache = useApolloClient().cache; @@ -39,7 +45,7 @@ export const usePrepareFindManyActivitiesQuery = () => { }: { additionalFilter?: Record; targetableObject: ActivityTargetableObject; - shouldActivityBeExcluded?: (activityTarget: Activity) => boolean; + shouldActivityBeExcluded?: (activityTarget: Task | Note) => boolean; }) => { const targetableObjectMetadataItem = objectMetadataItems.find( (objectMetadataItem) => @@ -60,8 +66,10 @@ export const usePrepareFindManyActivitiesQuery = () => { cache, }); - const activityTargets: ActivityTarget[] = - targetableObjectRecord?.activityTargets ?? []; + const activityTargets: (TaskTarget | NoteTarget)[] = + targetableObjectRecord?.taskTargets ?? + targetableObjectRecord?.noteTargets ?? + []; const activityTargetIds = [ ...new Set( @@ -71,7 +79,7 @@ export const usePrepareFindManyActivitiesQuery = () => { ), ]; - const activities: Activity[] = activityTargetIds + const activities: (Task | Note)[] = activityTargetIds .map((activityTargetId) => { const activityTarget = activityTargets.find( (activityTarget) => activityTarget.id === activityTargetId, @@ -81,7 +89,7 @@ export const usePrepareFindManyActivitiesQuery = () => { return undefined; } - return getActivityFromCache(activityTarget.activityId); + return getActivityFromCache(activityTarget.activityId); }) .filter(isDefined); @@ -103,7 +111,10 @@ export const usePrepareFindManyActivitiesQuery = () => { }); const FIND_ACTIVITIES_OPERATION_SIGNATURE = - findActivitiesOperationSignatureFactory({ objectMetadataItems }); + findActivitiesOperationSignatureFactory({ + objectNameSingular: activityObjectNameSingular, + objectMetadataItems, + }); upsertFindManyActivitiesInCache({ objectRecordsToOverwrite: filteredActivities, diff --git a/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts b/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts index cbf0e2f41..e054014aa 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useRefreshShowPageFindManyActivitiesQueries.ts @@ -1,20 +1,25 @@ import { useRecoilValue } from 'recoil'; import { usePrepareFindManyActivitiesQuery } from '@/activities/hooks/usePrepareFindManyActivitiesQuery'; -import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectIdState'; -import { Activity } from '@/activities/types/Activity'; +import { objectShowPageTargetableObjectState } from '@/activities/timelineActivities/states/objectShowPageTargetableObjectIdState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { isDefined } from '~/utils/isDefined'; // This hook should only be executed if the normalized cache is up-to-date // It will take a targetableObject and prepare the queries for the activities // based on the activityTargets of the targetableObject -export const useRefreshShowPageFindManyActivitiesQueries = () => { +export const useRefreshShowPageFindManyActivitiesQueries = ({ + activityObjectNameSingular, +}: { + activityObjectNameSingular: CoreObjectNameSingular; +}) => { const objectShowPageTargetableObject = useRecoilValue( objectShowPageTargetableObjectState, ); - const { prepareFindManyActivitiesQuery } = - usePrepareFindManyActivitiesQuery(); + const { prepareFindManyActivitiesQuery } = usePrepareFindManyActivitiesQuery({ + activityObjectNameSingular, + }); const refreshShowPageFindManyActivitiesQueries = () => { if (isDefined(objectShowPageTargetableObject)) { @@ -24,21 +29,12 @@ export const useRefreshShowPageFindManyActivitiesQueries = () => { prepareFindManyActivitiesQuery({ targetableObject: objectShowPageTargetableObject, additionalFilter: { - completedAt: { is: 'NULL' }, - type: { eq: 'Task' }, - }, - shouldActivityBeExcluded: (activity: Activity) => { - return activity.type !== 'Task'; + status: { eq: 'TODO' }, }, }); prepareFindManyActivitiesQuery({ targetableObject: objectShowPageTargetableObject, - additionalFilter: { - type: { eq: 'Note' }, - }, - shouldActivityBeExcluded: (activity: Activity) => { - return activity.type !== 'Note'; - }, + additionalFilter: {}, }); } }; diff --git a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts index 636519921..4c1c6e249 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useUpsertActivity.ts @@ -1,50 +1,58 @@ -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilState, useRecoilValue } from 'recoil'; import { useCreateActivityInDB } from '@/activities/hooks/useCreateActivityInDB'; import { useRefreshShowPageFindManyActivitiesQueries } from '@/activities/hooks/useRefreshShowPageFindManyActivitiesQueries'; -import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState'; import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState'; import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState'; -import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectIdState'; -import { Activity } from '@/activities/types/Activity'; +import { objectShowPageTargetableObjectState } from '@/activities/timelineActivities/states/objectShowPageTargetableObjectIdState'; +import { Note } from '@/activities/types/Note'; +import { Task } from '@/activities/types/Task'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { isDefined } from '~/utils/isDefined'; -export const useUpsertActivity = () => { - const [isActivityInCreateMode, setIsActivityInCreateMode] = useRecoilState( - isActivityInCreateModeState, - ); +export const useUpsertActivity = ({ + activityObjectNameSingular, +}: { + activityObjectNameSingular: + | CoreObjectNameSingular.Task + | CoreObjectNameSingular.Note; +}) => { + const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); - const { updateOneRecord: updateOneActivity } = useUpdateOneRecord({ - objectNameSingular: CoreObjectNameSingular.Activity, + const { updateOneRecord: updateOneActivity } = useUpdateOneRecord< + Task | Note + >({ + objectNameSingular: activityObjectNameSingular, }); - const { createActivityInDB } = useCreateActivityInDB(); + const { createActivityInDB } = useCreateActivityInDB({ + activityObjectNameSingular, + }); const [, setIsUpsertingActivityInDB] = useRecoilState( isUpsertingActivityInDBState, ); - const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); - const objectShowPageTargetableObject = useRecoilValue( objectShowPageTargetableObjectState, ); const { refreshShowPageFindManyActivitiesQueries } = - useRefreshShowPageFindManyActivitiesQueries(); + useRefreshShowPageFindManyActivitiesQueries({ + activityObjectNameSingular, + }); const upsertActivity = async ({ activity, input, }: { - activity: Activity; - input: Partial; + activity: Task | Note; + input: Partial; }) => { setIsUpsertingActivityInDB(true); if (isActivityInCreateMode) { - const activityToCreate: Activity = { + const activityToCreate: Partial = { ...activity, ...input, }; @@ -54,9 +62,6 @@ export const useUpsertActivity = () => { } await createActivityInDB(activityToCreate); - - setActivityIdInDrawer(activityToCreate.id); - setIsActivityInCreateMode(false); } else { await updateOneActivity?.({ idToUpdate: activity.id, diff --git a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx index 5ebc52826..4ed47174a 100644 --- a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx +++ b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetInlineCellEditMode.tsx @@ -6,10 +6,13 @@ import { v4 } from 'uuid'; import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity'; import { ActivityTargetObjectRecordEffect } from '@/activities/inline-cell/components/ActivityTargetObjectRecordEffect'; import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject'; +import { Note } from '@/activities/types/Note'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { Task } from '@/activities/types/Task'; +import { TaskTarget } from '@/activities/types/TaskTarget'; import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getActivityTargetObjectFieldIdName'; +import { getJoinObjectNameSingular } from '@/activities/utils/getJoinObjectNameSingular'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useCreateManyRecordsInCache } from '@/object-record/cache/hooks/useCreateManyRecordsInCache'; @@ -35,13 +38,17 @@ const StyledSelectContainer = styled.div` `; type ActivityTargetInlineCellEditModeProps = { - activity: Activity; + activity: Task | Note; activityTargetWithTargetRecords: ActivityTargetWithTargetRecord[]; + activityObjectNameSingular: + | CoreObjectNameSingular.Note + | CoreObjectNameSingular.Task; }; export const ActivityTargetInlineCellEditMode = ({ activity, activityTargetWithTargetRecords, + activityObjectNameSingular, }: ActivityTargetInlineCellEditModeProps) => { const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); const relationPickerScopeId = `relation-picker-${activity.id}`; @@ -53,24 +60,27 @@ export const ActivityTargetInlineCellEditMode = ({ }), ); - const { createManyRecords: createManyActivityTargets } = - useCreateManyRecords({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, - }); + const { createManyRecords: createManyActivityTargets } = useCreateManyRecords< + NoteTarget | TaskTarget + >({ + objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular), + }); const { deleteManyRecords: deleteManyActivityTargets } = useDeleteManyRecords( { - objectNameSingular: CoreObjectNameSingular.ActivityTarget, + objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular), }, ); const { closeInlineCell: closeEditableField } = useInlineCell(); - const { upsertActivity } = useUpsertActivity(); + const { upsertActivity } = useUpsertActivity({ + activityObjectNameSingular, + }); const { objectMetadataItem: objectMetadataItemActivityTarget } = useObjectMetadataItem({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, + objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular), }); const setActivityFromStore = useSetRecoilState( @@ -78,8 +88,8 @@ export const ActivityTargetInlineCellEditMode = ({ ); const { createManyRecordsInCache: createManyActivityTargetsInCache } = - useCreateManyRecordsInCache({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, + useCreateManyRecordsInCache({ + objectNameSingular: getJoinObjectNameSingular(activityObjectNameSingular), }); const handleSubmit = useRecoilCallback( @@ -166,12 +176,19 @@ export const ActivityTargetInlineCellEditMode = ({ const fieldNameWithIdSuffix = getActivityTargetObjectFieldIdName({ nameSingular: record.objectMetadataItem.nameSingular, }); - const newActivityTarget = prefillRecord({ + + const newActivityTarget = prefillRecord({ objectMetadataItem: objectMetadataItemActivityTarget, input: { id: newActivityTargetId, - activityId: activity.id, - activity, + taskId: + activityObjectNameSingular === CoreObjectNameSingular.Task + ? activity.id + : null, + noteId: + activityObjectNameSingular === CoreObjectNameSingular.Note + ? activity.id + : null, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), [fieldName]: record.record, @@ -186,7 +203,11 @@ export const ActivityTargetInlineCellEditMode = ({ upsertActivity({ activity, input: { - activityTargets: activityTargetsAfterUpdate, + [activityObjectNameSingular === CoreObjectNameSingular.Task + ? 'taskTargets' + : activityObjectNameSingular === CoreObjectNameSingular.Note + ? 'noteTargets' + : '']: activityTargetsAfterUpdate, }, }); } else { @@ -219,7 +240,11 @@ export const ActivityTargetInlineCellEditMode = ({ upsertActivity({ activity, input: { - activityTargets: activityTargetsAfterUpdate, + [activityObjectNameSingular === CoreObjectNameSingular.Task + ? 'taskTargets' + : activityObjectNameSingular === CoreObjectNameSingular.Note + ? 'noteTargets' + : '']: activityTargetsAfterUpdate, }, }); } else { @@ -241,6 +266,7 @@ export const ActivityTargetInlineCellEditMode = ({ objectMetadataItemActivityTarget, relationPickerScopeId, upsertActivity, + activityObjectNameSingular, ], ); diff --git a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx index f1490e1d4..b275231ca 100644 --- a/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx +++ b/packages/twenty-front/src/modules/activities/inline-cell/components/ActivityTargetsInlineCell.tsx @@ -5,8 +5,9 @@ import { IconArrowUpRight, IconPencil } from 'twenty-ui'; import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips'; import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords'; import { ActivityTargetInlineCellEditMode } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditMode'; -import { Activity } from '@/activities/types/Activity'; import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope'; +import { Note } from '@/activities/types/Note'; +import { Task } from '@/activities/types/Task'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useFieldContext } from '@/object-record/hooks/useFieldContext'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; @@ -17,10 +18,13 @@ import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlin import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; type ActivityTargetsInlineCellProps = { - activity: Activity; + activity: Task | Note; showLabel?: boolean; maxWidth?: number; readonly?: boolean; + activityObjectNameSingular: + | CoreObjectNameSingular.Note + | CoreObjectNameSingular.Task; }; export const ActivityTargetsInlineCell = ({ @@ -28,9 +32,13 @@ export const ActivityTargetsInlineCell = ({ showLabel = true, maxWidth, readonly, + activityObjectNameSingular, }: ActivityTargetsInlineCellProps) => { - const { activityTargetObjectRecords } = - useActivityTargetObjectRecords(activity); + const { activityTargetObjectRecords } = useActivityTargetObjectRecords( + activity, + activityObjectNameSingular, + ); + const { closeInlineCell } = useInlineCell(); const { fieldDefinition } = useContext(FieldContext); @@ -45,9 +53,9 @@ export const ActivityTargetsInlineCell = ({ const { FieldContextProvider: ActivityTargetsContextProvider } = useFieldContext({ - objectNameSingular: CoreObjectNameSingular.Activity, + objectNameSingular: activityObjectNameSingular, objectRecordId: activity.id, - fieldMetadataName: 'activityTargets', + fieldMetadataName: fieldDefinition.metadata.fieldName, fieldPosition: 3, overridenIsFieldEmpty: activityTargetObjectRecords.length === 0, }); @@ -70,6 +78,7 @@ export const ActivityTargetsInlineCell = ({ } label="Relations" diff --git a/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx b/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx index caefb987a..c5c40761b 100644 --- a/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx +++ b/packages/twenty-front/src/modules/activities/notes/components/NoteCard.tsx @@ -1,16 +1,11 @@ -import { useMemo } from 'react'; -import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { IconComment } from 'twenty-ui'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; import { ActivityTargetsInlineCell } from '@/activities/inline-cell/components/ActivityTargetsInlineCell'; import { Note } from '@/activities/types/Note'; import { getActivityPreview } from '@/activities/utils/getActivityPreview'; -import { - FieldContext, - GenericFieldContextType, -} from '@/object-record/record-field/contexts/FieldContext'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useFieldContext } from '@/object-record/hooks/useFieldContext'; const StyledCard = styled.div<{ isSingleNote: boolean }>` align-items: flex-start; @@ -66,14 +61,6 @@ const StyledFooter = styled.div` width: calc(100% - ${({ theme }) => theme.spacing(4)}); `; -const StyledCommentIcon = styled.div` - align-items: center; - color: ${({ theme }) => theme.font.color.light}; - display: flex; - gap: ${({ theme }) => theme.spacing(1)}; - margin-left: ${({ theme }) => theme.spacing(2)}; -`; - export const NoteCard = ({ note, isSingleNote, @@ -81,34 +68,37 @@ export const NoteCard = ({ note: Note; isSingleNote: boolean; }) => { - const theme = useTheme(); - const openActivityRightDrawer = useOpenActivityRightDrawer(); + const openActivityRightDrawer = useOpenActivityRightDrawer({ + objectNameSingular: CoreObjectNameSingular.Note, + }); const body = getActivityPreview(note.body); - const fieldContext = useMemo( - () => ({ recoilScopeId: note?.id ?? '' }), - [note?.id], - ); + const { FieldContextProvider: NoteTargetsContextProvider } = useFieldContext({ + objectNameSingular: CoreObjectNameSingular.Note, + objectRecordId: note.id, + fieldMetadataName: 'noteTargets', + fieldPosition: 0, + }); return ( - - - openActivityRightDrawer(note.id)} - > - {note.title ?? 'Task Title'} - {body} - - - - {note.comments && note.comments.length > 0 && ( - - - {note.comments.length} - - )} - - - + + openActivityRightDrawer(note.id)} + > + {note.title ?? 'Task Title'} + {body} + + + {NoteTargetsContextProvider && ( + + + + )} + + ); }; diff --git a/packages/twenty-front/src/modules/activities/notes/components/Notes.tsx b/packages/twenty-front/src/modules/activities/notes/components/Notes.tsx index 4f3e83656..b26624e1a 100644 --- a/packages/twenty-front/src/modules/activities/notes/components/Notes.tsx +++ b/packages/twenty-front/src/modules/activities/notes/components/Notes.tsx @@ -6,6 +6,7 @@ import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateAct import { NoteList } from '@/activities/notes/components/NoteList'; import { useNotes } from '@/activities/notes/hooks/useNotes'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { Button } from '@/ui/input/button/components/Button'; import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder'; import { @@ -31,7 +32,9 @@ export const Notes = ({ }) => { const { notes, loading } = useNotes(targetableObject); - const openCreateActivity = useOpenCreateActivityDrawer(); + const openCreateActivity = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Note, + }); const isNotesEmpty = !notes || notes.length === 0; @@ -60,7 +63,6 @@ export const Notes = ({ variant="secondary" onClick={() => openCreateActivity({ - type: 'Note', targetableObjects: [targetableObject], }) } @@ -82,7 +84,6 @@ export const Notes = ({ title="Add note" onClick={() => openCreateActivity({ - type: 'Note', targetableObjects: [targetableObject], }) } diff --git a/packages/twenty-front/src/modules/activities/notes/hooks/__tests__/useNotes.test.ts b/packages/twenty-front/src/modules/activities/notes/hooks/__tests__/useNotes.test.ts index caf343010..c1eb06c0d 100644 --- a/packages/twenty-front/src/modules/activities/notes/hooks/__tests__/useNotes.test.ts +++ b/packages/twenty-front/src/modules/activities/notes/hooks/__tests__/useNotes.test.ts @@ -16,9 +16,7 @@ jest.mock('recoil', () => { ...actualRecoil, useRecoilState: jest.fn(() => { const mockCurrentNotesQueryVariables = { - filter: { - type: { eq: 'Note' }, - }, + filter: {}, orderBy: 'mockOrderBy', }; return [mockCurrentNotesQueryVariables, jest.fn()]; diff --git a/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts b/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts index 383061c5e..04aa231d4 100644 --- a/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts +++ b/packages/twenty-front/src/modules/activities/notes/hooks/useNotes.ts @@ -3,26 +3,26 @@ import { useRecoilState } from 'recoil'; import { useActivities } from '@/activities/hooks/useActivities'; import { currentNotesQueryVariablesState } from '@/activities/notes/states/currentNotesQueryVariablesState'; -import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FindManyTimelineActivitiesOrderBy'; +import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timelineActivities/constants/FindManyTimelineActivitiesOrderBy'; import { Note } from '@/activities/types/Note'; import { RecordGqlOperationVariables } from '@/object-record/graphql/types/RecordGqlOperationVariables'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { ActivityTargetableObject } from '../../types/ActivityTargetableEntity'; export const useNotes = (targetableObject: ActivityTargetableObject) => { const notesQueryVariables = useMemo( () => ({ - filter: { - type: { eq: 'Note' }, - }, + filter: {}, orderBy: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY, }) as RecordGqlOperationVariables, [], ); - const { activities, loading } = useActivities({ + const { activities, loading } = useActivities({ + objectNameSingular: CoreObjectNameSingular.Note, activitiesFilters: notesQueryVariables.filter ?? {}, activitiesOrderByVariables: notesQueryVariables.orderBy ?? [{}], targetableObjects: [targetableObject], diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx deleted file mode 100644 index 60cce744e..000000000 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import styled from '@emotion/styled'; -import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards'; -import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil'; -import { IconTrash } from 'twenty-ui'; - -import { useRefreshShowPageFindManyActivitiesQueries } from '@/activities/hooks/useRefreshShowPageFindManyActivitiesQueries'; -import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState'; -import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState'; -import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState'; -import { temporaryActivityForEditorState } from '@/activities/states/temporaryActivityForEditorState'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useDeleteRecordFromCache } from '@/object-record/cache/hooks/useDeleteRecordFromCache'; -import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords'; -import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; -import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { mapToRecordId } from '@/object-record/utils/mapToObjectId'; -import { IconButton } from '@/ui/input/button/components/IconButton'; -import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState'; -import { isDefined } from '~/utils/isDefined'; - -const StyledButtonContainer = styled.div` - display: inline-flex; - gap: ${({ theme }) => theme.spacing(2)}; -`; - -export const ActivityActionBar = () => { - const viewableRecordId = useRecoilValue(viewableRecordIdState); - const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); - - const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState); - const { deleteOneRecord: deleteOneActivity } = useDeleteOneRecord({ - objectNameSingular: CoreObjectNameSingular.Activity, - }); - - const { deleteManyRecords: deleteManyActivityTargets } = useDeleteManyRecords( - { - objectNameSingular: CoreObjectNameSingular.ActivityTarget, - }, - ); - - const [temporaryActivityForEditor, setTemporaryActivityForEditor] = - useRecoilState(temporaryActivityForEditorState); - - const deleteActivityFromCache = useDeleteRecordFromCache({ - objectNameSingular: CoreObjectNameSingular.Activity, - }); - const deleteActivityTargetFromCache = useDeleteRecordFromCache({ - objectNameSingular: CoreObjectNameSingular.ActivityTarget, - }); - - const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); - const [isUpsertingActivityInDB] = useRecoilState( - isUpsertingActivityInDBState, - ); - - const { refreshShowPageFindManyActivitiesQueries } = - useRefreshShowPageFindManyActivitiesQueries(); - - const deleteActivity = useRecoilCallback( - ({ snapshot }) => - async () => { - if (!activityIdInDrawer) { - throw new Error( - 'activityIdInDrawer is not defined, this should not happen', - ); - } - - const activity = snapshot - .getLoadable(recordStoreFamilyState(activityIdInDrawer)) - .getValue() as Activity; - - setIsRightDrawerOpen(false); - - if (!isNonEmptyString(viewableRecordId)) { - return; - } - - if (isActivityInCreateMode && isDefined(temporaryActivityForEditor)) { - deleteActivityFromCache(temporaryActivityForEditor); - setTemporaryActivityForEditor(null); - return; - } - - if (isNonEmptyString(activityIdInDrawer)) { - const activityTargetIdsToDelete: string[] = - activity.activityTargets.map(mapToRecordId) ?? []; - - deleteActivityFromCache(activity); - activity.activityTargets.forEach((activityTarget: ActivityTarget) => { - deleteActivityTargetFromCache(activityTarget); - }); - - refreshShowPageFindManyActivitiesQueries(); - - if (isNonEmptyArray(activityTargetIdsToDelete)) { - await deleteManyActivityTargets(activityTargetIdsToDelete); - } - - await deleteOneActivity?.(viewableRecordId); - } - }, - [ - activityIdInDrawer, - setIsRightDrawerOpen, - viewableRecordId, - isActivityInCreateMode, - temporaryActivityForEditor, - deleteActivityFromCache, - setTemporaryActivityForEditor, - refreshShowPageFindManyActivitiesQueries, - deleteOneActivity, - deleteActivityTargetFromCache, - deleteManyActivityTargets, - ], - ); - - const actionsAreDisabled = isUpsertingActivityInDB; - - return ( - - - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivity.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivity.tsx deleted file mode 100644 index 620e5ce39..000000000 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/RightDrawerActivity.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import styled from '@emotion/styled'; - -import { ActivityEditor } from '@/activities/components/ActivityEditor'; -import { ActivityEditorEffect } from '@/activities/components/ActivityEditorEffect'; -import { RecordValueSetterEffect } from '@/object-record/record-store/components/RecordValueSetterEffect'; - -const StyledContainer = styled.div` - box-sizing: border-box; - display: flex; - flex-direction: column; - height: 100%; - justify-content: space-between; - overflow-y: auto; - position: relative; -`; - -type RightDrawerActivityProps = { - activityId: string; - showComment?: boolean; - fillTitleFromBody?: boolean; -}; - -export const RightDrawerActivity = ({ - activityId, - showComment = false, - fillTitleFromBody = false, -}: RightDrawerActivityProps) => { - return ( - - - - - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx deleted file mode 100644 index d4b64f7f5..000000000 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/create/RightDrawerCreateActivity.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { useRecoilValue } from 'recoil'; - -import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; - -import { RightDrawerActivity } from '../RightDrawerActivity'; - -export const RightDrawerCreateActivity = () => { - const viewableRecordId = useRecoilValue(viewableRecordIdState); - - return ( - <> - {viewableRecordId && ( - - )} - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx b/packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx deleted file mode 100644 index 84d016869..000000000 --- a/packages/twenty-front/src/modules/activities/right-drawer/components/edit/RightDrawerEditActivity.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { useRecoilValue } from 'recoil'; - -import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; - -import { RightDrawerActivity } from '../RightDrawerActivity'; - -export const RightDrawerEditActivity = () => { - const viewableRecordId = useRecoilValue(viewableRecordIdState); - - return ( - <> - {viewableRecordId && ( - - )} - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/states/activityIdInDrawerState.ts b/packages/twenty-front/src/modules/activities/states/activityIdInDrawerState.ts deleted file mode 100644 index 8c2e46d9e..000000000 --- a/packages/twenty-front/src/modules/activities/states/activityIdInDrawerState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const activityIdInDrawerState = createState({ - key: 'activityIdInDrawerState', - defaultValue: null, -}); diff --git a/packages/twenty-front/src/modules/activities/states/recoil-scope-contexts/TasksRecoilScopeContext.ts b/packages/twenty-front/src/modules/activities/states/recoil-scope-contexts/TasksRecoilScopeContext.ts deleted file mode 100644 index 330a328b5..000000000 --- a/packages/twenty-front/src/modules/activities/states/recoil-scope-contexts/TasksRecoilScopeContext.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { createContext } from 'react'; - -export const TasksRecoilScopeContext = createContext(null); diff --git a/packages/twenty-front/src/modules/activities/states/temporaryActivityForEditorState.ts b/packages/twenty-front/src/modules/activities/states/temporaryActivityForEditorState.ts deleted file mode 100644 index b92ba320e..000000000 --- a/packages/twenty-front/src/modules/activities/states/temporaryActivityForEditorState.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createState } from 'twenty-ui'; - -import { ActivityForEditor } from '@/activities/types/ActivityForEditor'; - -export const temporaryActivityForEditorState = - createState({ - key: 'temporaryActivityForEditorState', - defaultValue: null, - }); diff --git a/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskGroups.stories.tsx b/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskGroups.stories.tsx index df530871b..444049cc1 100644 --- a/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskGroups.stories.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskGroups.stories.tsx @@ -1,6 +1,5 @@ import { Meta, StoryObj } from '@storybook/react'; -import { TasksRecoilScopeContext } from '@/activities/states/recoil-scope-contexts/TasksRecoilScopeContext'; import { TaskGroups } from '@/activities/tasks/components/TaskGroups'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { ObjectFilterDropdownScope } from '@/object-record/object-filter-dropdown/scopes/ObjectFilterDropdownScope'; @@ -9,7 +8,7 @@ import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWith import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator'; import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { mockedTasks } from '~/testing/mock-data/activities'; +import { mockedTasks } from '~/testing/mock-data/tasks'; const meta: Meta = { title: 'Modules/Activity/TaskGroups', @@ -25,9 +24,6 @@ const meta: Meta = { ObjectMetadataItemsDecorator, SnackBarDecorator, ], - parameters: { - customRecoilScopeContext: TasksRecoilScopeContext, - }, }; export default meta; @@ -39,7 +35,7 @@ export const WithTasks: Story = { args: { targetableObjects: [ { - id: mockedTasks[0].authorId, + id: mockedTasks[0].taskTargets?.[0].personId, targetObjectNameSingular: 'person', }, ] as ActivityTargetableObject[], diff --git a/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskList.stories.tsx b/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskList.stories.tsx index 4006fa33f..1113febb6 100644 --- a/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskList.stories.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/__stories__/TaskList.stories.tsx @@ -2,168 +2,10 @@ import { Meta, StoryObj } from '@storybook/react'; import { ComponentDecorator } from 'twenty-ui'; import { TaskList } from '@/activities/tasks/components/TaskList'; -import { Activity } from '@/activities/types/Activity'; -import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator'; import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; - -const workspaceMember: WorkspaceMember = { - __typename: 'WorkspaceMember', - id: '374fe3a5-df1e-4119-afe0-2a62a2ba481e', - name: { - firstName: 'Charles', - lastName: 'Test', - }, - avatarUrl: '', - locale: 'en', - createdAt: '2023-04-26T10:23:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - userId: 'e2409670-1088-46b4-858e-f20a598d9d0f', - userEmail: 'charles@test.com', - colorScheme: 'Light', -}; - -const mockedActivities: Array = [ - { - id: '3ecaa1be-aac7-463a-a38e-64078dd451d5', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - reminderAt: null, - title: 'My very first note', - type: 'Note', - body: '', - dueAt: '2023-04-26T10:12:42.33625+00:00', - completedAt: null, - author: workspaceMember, - assignee: workspaceMember, - assigneeId: workspaceMember.id, - authorId: workspaceMember.id, - comments: [], - activityTargets: [ - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb300', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - targetObjectNameSingular: 'company', - personId: null, - companyId: '89bb825c-171e-4bcc-9cf7-43448d6fb280', - company: { - __typename: 'Company', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb280', - name: 'Airbnb', - domainName: 'airbnb.com', - }, - person: null, - activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb230', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - }, - __typename: 'ActivityTarget', - }, - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb301', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - targetObjectNameSingular: 'company', - personId: null, - companyId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', - company: { - __typename: 'Company', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', - name: 'Aircall', - domainName: 'aircall.io', - }, - person: null, - activityId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb231', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - }, - __typename: 'ActivityTarget', - }, - ], - __typename: 'Activity', - }, - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - reminderAt: null, - title: 'Another note', - body: '', - type: 'Note', - completedAt: null, - dueAt: '2029-08-26T10:12:42.33625+00:00', - author: { - ...workspaceMember, - }, - assignee: { ...workspaceMember }, - assigneeId: workspaceMember.id, - authorId: workspaceMember.id, - comments: [], - activityTargets: [ - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278t', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - targetObjectNameSingular: 'person', - personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', // Alexandre - person: { - __typename: 'Person', - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: { - firstName: 'Alexandre', - lastName: 'Test', - }, - avatarUrl: '', - }, - company: null, - companyId: null, - activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - }, - __typename: 'ActivityTarget', - }, - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb279t', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', // Jean d'Eau - companyId: null, - targetObjectNameSingular: 'person', - company: null, - person: { - __typename: 'Person', - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', - name: { - firstName: 'Jean', - lastName: "d'Eau", - }, - avatarUrl: '', - }, - activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - }, - __typename: 'ActivityTarget', - }, - ], - __typename: 'Activity', - }, -]; +import { mockedTasks } from '~/testing/mock-data/tasks'; const meta: Meta = { title: 'Modules/Activity/TaskList', @@ -171,7 +13,7 @@ const meta: Meta = { decorators: [MemoryRouterDecorator, ComponentDecorator, SnackBarDecorator], args: { title: 'Tasks', - tasks: mockedActivities, + tasks: mockedTasks, }, parameters: { msw: graphqlMocks, @@ -184,6 +26,6 @@ type Story = StoryObj; export const Default: Story = { args: { title: 'Tasks', - tasks: mockedActivities, + tasks: mockedTasks, }, }; diff --git a/packages/twenty-front/src/modules/activities/tasks/components/AddTaskButton.tsx b/packages/twenty-front/src/modules/activities/tasks/components/AddTaskButton.tsx index 8dfacead3..869e2f1ad 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/AddTaskButton.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/AddTaskButton.tsx @@ -3,6 +3,7 @@ import { IconPlus } from 'twenty-ui'; import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { Button } from '@/ui/input/button/components/Button'; export const AddTaskButton = ({ @@ -10,7 +11,9 @@ export const AddTaskButton = ({ }: { activityTargetableObjects?: ActivityTargetableObject[]; }) => { - const openCreateActivity = useOpenCreateActivityDrawer(); + const openCreateActivity = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Task, + }); if (!isNonEmptyArray(activityTargetableObjects)) { return <>; @@ -24,7 +27,6 @@ export const AddTaskButton = ({ title="Add task" onClick={() => openCreateActivity({ - type: 'Task', targetableObjects: activityTargetableObjects, }) } diff --git a/packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx b/packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx deleted file mode 100644 index b7c790e89..000000000 --- a/packages/twenty-front/src/modules/activities/tasks/components/CurrentUserDueTaskCountEffect.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { useEffect } from 'react'; -import { DateTime } from 'luxon'; -import { useRecoilState, useRecoilValue } from 'recoil'; - -import { currentUserDueTaskCountState } from '@/activities/tasks/states/currentUserTaskCountState'; -import { Activity } from '@/activities/types/Activity'; -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; -import { parseDate } from '~/utils/date-utils'; - -export const CurrentUserDueTaskCountEffect = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - - const [currentUserDueTaskCount, setCurrentUserDueTaskCount] = useRecoilState( - currentUserDueTaskCountState, - ); - - const { records: tasks } = useFindManyRecords({ - objectNameSingular: CoreObjectNameSingular.Activity, - filter: { - type: { eq: 'Task' }, - completedAt: { is: 'NULL' }, - assigneeId: { eq: currentWorkspaceMember?.id }, - }, - }); - - const computedCurrentUserDueTaskCount = tasks.filter((task) => { - if (!task.dueAt) { - return false; - } - const dueDate = parseDate(task.dueAt).toJSDate(); - const today = DateTime.now().endOf('day').toJSDate(); - return dueDate <= today; - }).length; - - useEffect(() => { - if (currentUserDueTaskCount !== computedCurrentUserDueTaskCount) { - setCurrentUserDueTaskCount(computedCurrentUserDueTaskCount); - } - }, [ - computedCurrentUserDueTaskCount, - currentUserDueTaskCount, - setCurrentUserDueTaskCount, - ]); - - return <>; -}; diff --git a/packages/twenty-front/src/modules/activities/tasks/components/ObjectTasks.tsx b/packages/twenty-front/src/modules/activities/tasks/components/ObjectTasks.tsx index fd54c2169..a798a818d 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/ObjectTasks.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/ObjectTasks.tsx @@ -1,10 +1,8 @@ import styled from '@emotion/styled'; -import { TasksRecoilScopeContext } from '@/activities/states/recoil-scope-contexts/TasksRecoilScopeContext'; import { TaskGroups } from '@/activities/tasks/components/TaskGroups'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { ObjectFilterDropdownScope } from '@/object-record/object-filter-dropdown/scopes/ObjectFilterDropdownScope'; -import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; const StyledContainer = styled.div` display: flex; @@ -21,11 +19,9 @@ export const ObjectTasks = ({ }) => { return ( - - - - - + + + ); }; diff --git a/packages/twenty-front/src/modules/activities/tasks/components/PageAddTaskButton.tsx b/packages/twenty-front/src/modules/activities/tasks/components/PageAddTaskButton.tsx index 8d669c7ba..265780072 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/PageAddTaskButton.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/PageAddTaskButton.tsx @@ -1,14 +1,16 @@ import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { PageAddButton } from '@/ui/layout/page/PageAddButton'; export const PageAddTaskButton = () => { - const openCreateActivity = useOpenCreateActivityDrawer(); + const openCreateActivity = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Task, + }); // TODO: fetch workspace member from filter here const handleClick = () => { openCreateActivity({ - type: 'Task', targetableObjects: [], }); }; diff --git a/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx b/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx index 03c2bdb97..4503fd991 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/TaskGroups.tsx @@ -18,6 +18,9 @@ import { } from '@/ui/layout/animated-placeholder/components/EmptyPlaceholderStyled'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; +import { Task } from '@/activities/types/Task'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import groupBy from 'lodash.groupby'; import { AddTaskButton } from './AddTaskButton'; import { TaskList } from './TaskList'; @@ -33,37 +36,27 @@ type TaskGroupsProps = { }; export const TaskGroups = ({ - filterDropdownId, targetableObjects, showAddButton, }: TaskGroupsProps) => { - const { - todayOrPreviousTasks, - upcomingTasks, - unscheduledTasks, - completedTasks, - incompleteTasksLoading, - completeTasksLoading, - } = useTasks({ - filterDropdownId: filterDropdownId, + const { tasks, tasksLoading } = useTasks({ targetableObjects: targetableObjects ?? [], }); - const openCreateActivity = useOpenCreateActivityDrawer(); + const openCreateActivity = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Task, + }); const { activeTabIdState } = useTabList(TASKS_TAB_LIST_COMPONENT_ID); const activeTabId = useRecoilValue(activeTabIdState); const isLoading = - (activeTabId !== 'done' && incompleteTasksLoading) || - (activeTabId === 'done' && completeTasksLoading); + (activeTabId !== 'done' && tasksLoading) || + (activeTabId === 'done' && tasksLoading); const isTasksEmpty = - (activeTabId !== 'done' && - todayOrPreviousTasks?.length === 0 && - upcomingTasks?.length === 0 && - unscheduledTasks?.length === 0) || - (activeTabId === 'done' && completedTasks?.length === 0); + (activeTabId !== 'done' && tasks?.length === 0) || + (activeTabId === 'done' && tasks?.length === 0); if (isLoading && isTasksEmpty) { return ; @@ -90,7 +83,6 @@ export const TaskGroups = ({ variant={'secondary'} onClick={() => openCreateActivity({ - type: 'Task', targetableObjects: targetableObjects ?? [], }) } @@ -101,48 +93,19 @@ export const TaskGroups = ({ return ( - {activeTabId === 'done' ? ( - - ) - } - /> - ) : ( - <> + {Object.entries(groupBy(tasks, ({ status }) => status)).map( + ([status, tasksByStatus]: [string, Task[]]) => ( ) } /> - - ) - } - /> - - ) - } - /> - + ), )} ); diff --git a/packages/twenty-front/src/modules/activities/tasks/components/TaskList.tsx b/packages/twenty-front/src/modules/activities/tasks/components/TaskList.tsx index 0a8b3b76c..41514541c 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/TaskList.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/TaskList.tsx @@ -1,13 +1,12 @@ -import { ReactElement } from 'react'; import styled from '@emotion/styled'; +import { ReactElement } from 'react'; -import { Activity } from '@/activities/types/Activity'; - +import { Task } from '@/activities/types/Task'; import { TaskRow } from './TaskRow'; type TaskListProps = { title?: string; - tasks: Activity[]; + tasks: Task[]; button?: ReactElement | false; }; diff --git a/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx b/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx index 2e583eafd..798bb077d 100644 --- a/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/components/TaskRow.tsx @@ -1,18 +1,16 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { - IconCalendar, - IconComment, - OverflowingTextWithTooltip, -} from 'twenty-ui'; +import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; import { ActivityTargetsInlineCell } from '@/activities/inline-cell/components/ActivityTargetsInlineCell'; -import { Activity } from '@/activities/types/Activity'; import { getActivitySummary } from '@/activities/utils/getActivitySummary'; import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox'; import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils'; +import { Task } from '@/activities/types/Task'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { useFieldContext } from '@/object-record/hooks/useFieldContext'; import { useCompleteTask } from '../hooks/useCompleteTask'; const StyledContainer = styled.div` @@ -52,13 +50,6 @@ const StyledTaskTitle = styled.div<{ text-overflow: ellipsis; `; -const StyledCommentIcon = styled.div` - align-items: center; - color: ${({ theme }) => theme.font.color.light}; - display: flex; - margin-left: ${({ theme }) => theme.spacing(2)}; -`; - const StyledDueDate = styled.div<{ isPast: boolean; }>` @@ -89,13 +80,22 @@ const StyledCheckboxContainer = styled.div` display: flex; `; -export const TaskRow = ({ task }: { task: Activity }) => { +export const TaskRow = ({ task }: { task: Task }) => { const theme = useTheme(); - const openActivityRightDrawer = useOpenActivityRightDrawer(); + const openActivityRightDrawer = useOpenActivityRightDrawer({ + objectNameSingular: CoreObjectNameSingular.Task, + }); const body = getActivitySummary(task.body); const { completeTask } = useCompleteTask(task); + const { FieldContextProvider: TaskTargetsContextProvider } = useFieldContext({ + objectNameSingular: CoreObjectNameSingular.Task, + objectRecordId: task.id, + fieldMetadataName: 'taskTargets', + fieldPosition: 0, + }); + return ( { @@ -109,33 +109,33 @@ export const TaskRow = ({ task }: { task: Activity }) => { }} > - + {task.title || Task title} - {task.comments && task.comments.length > 0 && ( - - - - )} - + {TaskTargetsContextProvider && ( + + + + )} diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.tsx b/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.tsx index 889770635..9cd5fa308 100644 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCompleteTask.test.tsx @@ -1,16 +1,25 @@ -import { ReactNode } from 'react'; import { MockedProvider, MockedResponse } from '@apollo/client/testing'; import { act, renderHook } from '@testing-library/react'; import gql from 'graphql-tag'; +import { ReactNode } from 'react'; import { RecoilRoot } from 'recoil'; import { useCompleteTask } from '@/activities/tasks/hooks/useCompleteTask'; +import { Task } from '@/activities/types/Task'; -const task = { id: '123', completedAt: '2024-03-15T07:33:14.212Z' }; - -const mockedDate = task.completedAt; -const toISOStringMock = jest.fn(() => mockedDate); -global.Date.prototype.toISOString = toISOStringMock; +const task: Task = { + id: '123', + status: null, + title: 'Test', + body: 'Test', + dueAt: '2024-03-15T07:33:14.212Z', + createdAt: '2024-03-15T07:33:14.212Z', + updatedAt: '2024-03-15T07:33:14.212Z', + assignee: null, + assigneeId: null, + taskTargets: [], + __typename: 'Task', +}; const mocks: MockedResponse[] = [ { @@ -26,7 +35,7 @@ const mocks: MockedResponse[] = [ reminderAt authorId title - completedAt + status updatedAt body dueAt @@ -38,7 +47,7 @@ const mocks: MockedResponse[] = [ `, variables: { idToUpdate: task.id, - input: { completedAt: task.completedAt }, + input: { status: task.status }, }, }, result: jest.fn(() => ({ @@ -49,11 +58,11 @@ const mocks: MockedResponse[] = [ reminderAt: null, authorId: '123', title: 'Test', - completedAt: '2024-03-15T07:33:14.212Z', + status: 'DONE', updatedAt: '2024-03-15T07:33:14.212Z', body: 'Test', dueAt: '2024-03-15T07:33:14.212Z', - type: 'Task', + type: 'TASK', id: '123', assigneeId: '123', }, diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCurrentUserTaskCount.test.tsx b/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCurrentUserTaskCount.test.tsx deleted file mode 100644 index 7d035958c..000000000 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useCurrentUserTaskCount.test.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { ReactNode } from 'react'; -import { renderHook } from '@testing-library/react'; -import { RecoilRoot } from 'recoil'; - -import { useCurrentUserTaskCount } from '@/activities/tasks/hooks/useCurrentUserDueTaskCount'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; -import { mockedActivities } from '~/testing/mock-data/activities'; - -const useFindManyRecordsMock = jest.fn(() => ({ - records: [...mockedActivities, { id: '2' }], -})); - -jest.mock('@/object-record/hooks/useFindManyRecords', () => ({ - useFindManyRecords: jest.fn(), -})); - -(useFindManyRecords as jest.Mock).mockImplementation(useFindManyRecordsMock); - -const Wrapper = ({ children }: { children: ReactNode }) => ( - {children} -); - -describe('useCurrentUserTaskCount', () => { - it('should return the current user task count', async () => { - const { result } = renderHook(() => useCurrentUserTaskCount(), { - wrapper: Wrapper, - }); - - expect(result.current.currentUserDueTaskCount).toBe(1); - }); -}); diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useTasks.test.tsx b/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useTasks.test.tsx index 0e7cdc3c4..d24485409 100644 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useTasks.test.tsx +++ b/packages/twenty-front/src/modules/activities/tasks/hooks/__tests__/useTasks.test.tsx @@ -1,33 +1,27 @@ -import { ReactNode } from 'react'; import { renderHook } from '@testing-library/react'; +import { ReactNode } from 'react'; import { RecoilRoot } from 'recoil'; import { useActivities } from '@/activities/hooks/useActivities'; import { useTasks } from '@/activities/tasks/hooks/useTasks'; import { ObjectFilterDropdownScope } from '@/object-record/object-filter-dropdown/scopes/ObjectFilterDropdownScope'; -const completedTasks = [ +const tasks = [ { id: '1', - completedAt: '2024-03-15T07:33:14.212Z', + status: 'DONE', }, { id: '2', - completedAt: '2024-03-15T07:33:14.212Z', + status: 'DONE', }, { id: '3', - completedAt: '2024-03-15T07:33:14.212Z', + status: 'DONE', }, -]; - -const unscheduledTasks = [ { id: '4', }, -]; - -const todayOrPreviousTasks = [ { id: '5', dueAt: '2024-03-15T07:33:14.212Z', @@ -38,20 +32,11 @@ const todayOrPreviousTasks = [ }, ]; -const useActivitiesMock = jest.fn( - ({ - activitiesFilters, - }: { - activitiesFilters: { completedAt: { is: 'NULL' | 'NOT_NULL' } }; - }) => { - const isCompletedFilter = activitiesFilters.completedAt.is === 'NOT_NULL'; - return { - activities: isCompletedFilter - ? completedTasks - : [...todayOrPreviousTasks, ...unscheduledTasks], - }; - }, -); +const useActivitiesMock = jest.fn(() => { + return { + activities: tasks, + }; +}); jest.mock('@/activities/hooks/useActivities', () => ({ useActivities: jest.fn(), @@ -74,10 +59,7 @@ describe('useTasks', () => { }); expect(result.current).toEqual({ - todayOrPreviousTasks, - upcomingTasks: [], - unscheduledTasks, - completedTasks, + tasks: tasks, }); }); }); diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/useCompleteTask.ts b/packages/twenty-front/src/modules/activities/tasks/hooks/useCompleteTask.ts index 73dfb1dc2..264a73e6f 100644 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/useCompleteTask.ts +++ b/packages/twenty-front/src/modules/activities/tasks/hooks/useCompleteTask.ts @@ -1,23 +1,21 @@ import { useCallback } from 'react'; -import { Activity } from '@/activities/types/Activity'; +import { Task } from '@/activities/types/Task'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; -type Task = Pick; - export const useCompleteTask = (task: Task) => { - const { updateOneRecord: updateOneActivity } = useUpdateOneRecord({ - objectNameSingular: CoreObjectNameSingular.Activity, + const { updateOneRecord: updateOneActivity } = useUpdateOneRecord({ + objectNameSingular: CoreObjectNameSingular.Task, }); const completeTask = useCallback( async (value: boolean) => { - const completedAt = value ? new Date().toISOString() : null; + const status = value ? 'DONE' : 'TODO'; await updateOneActivity?.({ idToUpdate: task.id, updateOneRecordInput: { - completedAt, + status, }, }); }, diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts b/packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts deleted file mode 100644 index 836ed21ba..000000000 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/useCurrentUserDueTaskCount.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { DateTime } from 'luxon'; -import { useRecoilValue } from 'recoil'; - -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; -import { parseDate } from '~/utils/date-utils'; - -export const useCurrentUserTaskCount = () => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - - const { records: tasks } = useFindManyRecords({ - objectNameSingular: CoreObjectNameSingular.Activity, - filter: { - type: { eq: 'Task' }, - completedAt: { is: 'NULL' }, - assigneeId: { eq: currentWorkspaceMember?.id }, - }, - }); - - const currentUserDueTaskCount = tasks.filter((task) => { - if (!task.dueAt) { - return false; - } - const dueDate = parseDate(task.dueAt).toJSDate(); - const today = DateTime.now().endOf('day').toJSDate(); - return dueDate <= today; - }).length; - - return { - currentUserDueTaskCount, - }; -}; diff --git a/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts b/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts index e560e2607..ef210d328 100644 --- a/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts +++ b/packages/twenty-front/src/modules/activities/tasks/hooks/useTasks.ts @@ -1,156 +1,23 @@ -import { useEffect, useMemo } from 'react'; -import { DateTime } from 'luxon'; -import { useRecoilState, useRecoilValue } from 'recoil'; - import { useActivities } from '@/activities/hooks/useActivities'; -import { currentCompletedTaskQueryVariablesState } from '@/activities/tasks/states/currentCompletedTaskQueryVariablesState'; -import { currentIncompleteTaskQueryVariablesState } from '@/activities/tasks/states/currentIncompleteTaskQueryVariablesState'; -import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FindManyTimelineActivitiesOrderBy'; -import { Activity } from '@/activities/types/Activity'; +import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timelineActivities/constants/FindManyTimelineActivitiesOrderBy'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; -import { RecordGqlOperationVariables } from '@/object-record/graphql/types/RecordGqlOperationVariables'; -import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; -import { parseDate } from '~/utils/date-utils'; -import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; +import { Task } from '@/activities/types/Task'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; type UseTasksProps = { - filterDropdownId?: string; targetableObjects: ActivityTargetableObject[]; }; -export const useTasks = ({ - targetableObjects, - filterDropdownId, -}: UseTasksProps) => { - const { selectedFilterState } = useFilterDropdown({ - filterDropdownId, +export const useTasks = ({ targetableObjects }: UseTasksProps) => { + const { activities: tasks, loading: tasksLoading } = useActivities({ + objectNameSingular: CoreObjectNameSingular.Task, + targetableObjects, + activitiesFilters: {}, + activitiesOrderByVariables: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY, }); - const selectedFilter = useRecoilValue(selectedFilterState); - - const assigneeIdFilter = useMemo( - () => - selectedFilter - ? { - assigneeId: { - in: JSON.parse(selectedFilter.value), - }, - } - : undefined, - [selectedFilter], - ); - - const completedQueryVariables = useMemo( - () => - ({ - filter: { - completedAt: { is: 'NOT_NULL' }, - type: { eq: 'Task' }, - ...assigneeIdFilter, - }, - orderBy: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY, - }) as RecordGqlOperationVariables, - [assigneeIdFilter], - ); - - const incompleteQueryVariables = useMemo( - () => - ({ - filter: { - completedAt: { is: 'NULL' }, - type: { eq: 'Task' }, - ...assigneeIdFilter, - }, - orderBy: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY, - }) as RecordGqlOperationVariables, - [assigneeIdFilter], - ); - - const [ - currentCompletedTaskQueryVariables, - setCurrentCompletedTaskQueryVariables, - ] = useRecoilState(currentCompletedTaskQueryVariablesState); - - const [ - currentIncompleteTaskQueryVariables, - setCurrentIncompleteTaskQueryVariables, - ] = useRecoilState(currentIncompleteTaskQueryVariablesState); - - // TODO: fix useEffect, remove with better pattern - useEffect(() => { - if ( - !isDeeplyEqual( - completedQueryVariables, - currentCompletedTaskQueryVariables, - ) - ) { - setCurrentCompletedTaskQueryVariables(completedQueryVariables); - } - }, [ - completedQueryVariables, - currentCompletedTaskQueryVariables, - setCurrentCompletedTaskQueryVariables, - ]); - - useEffect(() => { - if ( - !isDeeplyEqual( - incompleteQueryVariables, - currentIncompleteTaskQueryVariables, - ) - ) { - setCurrentIncompleteTaskQueryVariables(incompleteQueryVariables); - } - }, [ - incompleteQueryVariables, - currentIncompleteTaskQueryVariables, - setCurrentIncompleteTaskQueryVariables, - ]); - - const { activities: completeTasksData, loading: completeTasksLoading } = - useActivities({ - targetableObjects, - activitiesFilters: completedQueryVariables.filter ?? {}, - activitiesOrderByVariables: completedQueryVariables.orderBy ?? [{}], - }); - - const { activities: incompleteTaskData, loading: incompleteTasksLoading } = - useActivities({ - targetableObjects, - activitiesFilters: incompleteQueryVariables.filter ?? {}, - activitiesOrderByVariables: incompleteQueryVariables.orderBy ?? [{}], - }); - - const todayOrPreviousTasks = incompleteTaskData?.filter((task) => { - if (!task.dueAt) { - return false; - } - const dueDate = parseDate(task.dueAt).toJSDate(); - const today = DateTime.now().endOf('day').toJSDate(); - return dueDate <= today; - }); - - const upcomingTasks = incompleteTaskData?.filter((task) => { - if (!task.dueAt) { - return false; - } - const dueDate = parseDate(task.dueAt).toJSDate(); - const today = DateTime.now().endOf('day').toJSDate(); - return dueDate > today; - }); - - const unscheduledTasks = incompleteTaskData?.filter((task) => { - return !task.dueAt; - }); - - const completedTasks = completeTasksData; - return { - todayOrPreviousTasks: (todayOrPreviousTasks ?? []) as Activity[], - upcomingTasks: (upcomingTasks ?? []) as Activity[], - unscheduledTasks: (unscheduledTasks ?? []) as Activity[], - completedTasks: (completedTasks ?? []) as Activity[], - completeTasksLoading, - incompleteTasksLoading, + tasks: (tasks ?? []) as Task[], + tasksLoading, }; }; diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineActivity.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelineActivity.tsx deleted file mode 100644 index 819bcc73d..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineActivity.tsx +++ /dev/null @@ -1,218 +0,0 @@ -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; -import { useRecoilValue } from 'recoil'; -import { AppTooltip, Avatar, IconCheckbox, IconNotes } from 'twenty-ui'; - -import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; -import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; -import { - beautifyExactDateTime, - beautifyPastDateRelativeToNow, -} from '~/utils/date-utils'; - -const StyledAvatarContainer = styled.div` - align-items: center; - display: flex; - height: 26px; - justify-content: center; - user-select: none; - width: 26px; - z-index: 2; -`; - -const StyledIconContainer = styled.div` - align-items: center; - color: ${({ theme }) => theme.font.color.tertiary}; - display: flex; - height: 16px; - justify-content: center; - text-decoration-line: underline; - width: 16px; -`; - -const StyledActivityTitle = styled.div` - color: ${({ theme }) => theme.font.color.secondary}; - cursor: pointer; - display: flex; - flex: 1; - font-weight: ${({ theme }) => theme.font.weight.regular}; - overflow: hidden; -`; - -const StyledActivityLink = styled.div` - color: ${({ theme }) => theme.font.color.secondary}; - font-weight: ${({ theme }) => theme.font.weight.regular}; - overflow: hidden; - text-decoration-line: underline; - text-overflow: ellipsis; -`; - -const StyledItemContainer = styled.div` - align-content: center; - align-items: center; - color: ${({ theme }) => theme.font.color.tertiary}; - display: flex; - flex: 1; - gap: ${({ theme }) => theme.spacing(1)}; - span { - color: ${({ theme }) => theme.font.color.secondary}; - } - overflow: hidden; -`; - -const StyledItemTitleContainer = styled.div` - display: flex; - flex: 1; - flex-flow: row ${() => (useIsMobile() ? 'wrap' : 'nowrap')}; - gap: ${({ theme }) => theme.spacing(1)}; - overflow: hidden; -`; - -const StyledItemAuthorText = styled.div` - display: flex; - gap: ${({ theme }) => theme.spacing(1)}; -`; - -const StyledItemTitle = styled.div` - display: flex; - flex-flow: row nowrap; - overflow: hidden; -`; - -const StyledItemTitleDate = styled.div` - align-items: center; - color: ${({ theme }) => theme.font.color.tertiary}; - display: flex; - gap: ${({ theme }) => theme.spacing(2)}; - justify-content: flex-end; - margin-left: auto; -`; - -const StyledVerticalLineContainer = styled.div` - align-items: center; - align-self: stretch; - display: flex; - gap: ${({ theme }) => theme.spacing(2)}; - justify-content: center; - width: 26px; - z-index: 2; -`; - -const StyledVerticalLine = styled.div` - align-self: stretch; - background: ${({ theme }) => theme.border.color.light}; - flex-shrink: 0; - width: 2px; -`; - -const StyledTimelineItemContainer = styled.div<{ isGap?: boolean }>` - align-items: center; - align-self: stretch; - display: flex; - gap: ${({ theme }) => theme.spacing(4)}; - height: ${({ isGap, theme }) => - isGap ? (useIsMobile() ? theme.spacing(6) : theme.spacing(3)) : 'auto'}; - overflow: hidden; - white-space: nowrap; -`; - -type TimelineActivityProps = { - isLastActivity?: boolean; - activityId: string; -}; - -export const TimelineActivity = ({ - isLastActivity, - activityId, -}: TimelineActivityProps) => { - const activityForTimeline = useRecoilValue( - timelineActivityWithoutTargetsFamilyState(activityId), - ); - - const beautifiedCreatedAt = activityForTimeline - ? beautifyPastDateRelativeToNow(activityForTimeline.createdAt) - : ''; - const exactCreatedAt = activityForTimeline - ? beautifyExactDateTime(activityForTimeline.createdAt) - : ''; - const openActivityRightDrawer = useOpenActivityRightDrawer(); - const theme = useTheme(); - - const activityFromStore = useRecoilValue( - recordStoreFamilyState(activityForTimeline?.id ?? ''), - ); - - if (!activityForTimeline) { - return <>; - } - - return ( - <> - - - - - - - - - {activityForTimeline.author?.name.firstName}{' '} - {activityForTimeline.author?.name.lastName} - - created a {activityForTimeline.type.toLowerCase()} - - - - {activityForTimeline.type === 'Note' && ( - - )} - {activityForTimeline.type === 'Task' && ( - - )} - - {(activityForTimeline.type === 'Note' || - activityForTimeline.type === 'Task') && ( - - openActivityRightDrawer(activityForTimeline.id) - } - > - “ - - {activityFromStore?.title ?? '(No Title)'} - - “ - - )} - - - - {beautifiedCreatedAt} - - - - - {!isLastActivity && ( - - - - - - )} - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineActivityTitle.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelineActivityTitle.tsx deleted file mode 100644 index e3c90abc0..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineActivityTitle.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import styled from '@emotion/styled'; -import { OverflowingTextWithTooltip } from 'twenty-ui'; - -import { ActivityType } from '@/activities/types/Activity'; -import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox'; - -const StyledTitleContainer = styled.div` - color: ${({ theme }) => theme.font.color.primary}; - display: flex; - flex-direction: row; - font-weight: ${({ theme }) => theme.font.weight.medium}; - gap: ${({ theme }) => theme.spacing(2)}; - line-height: ${({ theme }) => theme.text.lineHeight.lg}; - - width: 100%; -`; - -const StyledTitleText = styled.div<{ - completed?: boolean; - hasCheckbox?: boolean; -}>` - text-decoration: ${({ completed }) => (completed ? 'line-through' : 'none')}; - width: ${({ hasCheckbox, theme }) => - !hasCheckbox ? '100%;' : `calc(100% - ${theme.spacing(5)});`}; -`; - -const StyledCheckboxContainer = styled.div<{ hasCheckbox?: boolean }>` - align-items: center; - display: flex; - justify-content: center; -`; - -type TimelineActivityTitleProps = { - title: string; - completed?: boolean; - type: ActivityType; - onCompletionChange?: (value: boolean) => void; -}; - -export const TimelineActivityTitle = ({ - title, - completed, - type, - onCompletionChange, -}: TimelineActivityTitleProps) => ( - - {type === 'Task' && ( - { - event.preventDefault(); - event.stopPropagation(); - onCompletionChange?.(!completed); - }} - > - - - )} - - - - -); diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx deleted file mode 100644 index f509a4781..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineItemsContainer.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import styled from '@emotion/styled'; -import { useRecoilValue } from 'recoil'; - -import { timelineActivitiesForGroupState } from '@/activities/timeline/states/timelineActivitiesForGroupState'; -import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; - -import { groupActivitiesByMonth } from '../utils/groupActivitiesByMonth'; - -import { TimelineActivityGroup } from './TimelingeActivityGroup'; - -const StyledTimelineContainer = styled.div` - align-items: center; - align-self: stretch; - - display: flex; - flex: 1 0 0; - flex-direction: column; - gap: ${({ theme }) => theme.spacing(1)}; - justify-content: flex-start; - - padding: ${({ theme }) => theme.spacing(4)}; - width: calc(100% - ${({ theme }) => theme.spacing(8)}); -`; - -const StyledScrollWrapper = styled(ScrollWrapper)``; - -export const TimelineItemsContainer = () => { - const timelineActivitiesForGroup = useRecoilValue( - timelineActivitiesForGroupState, - ); - - const groupedActivities = groupActivitiesByMonth(timelineActivitiesForGroup); - - return ( - - - {groupedActivities.map((group, index) => ( - - ))} - - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx deleted file mode 100644 index 60367044b..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineQueryEffect.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { useEffect } from 'react'; -import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil'; - -import { useActivities } from '@/activities/hooks/useActivities'; -import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FindManyTimelineActivitiesOrderBy'; -import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectIdState'; -import { timelineActivitiesFamilyState } from '@/activities/timeline/states/timelineActivitiesFamilyState'; -import { timelineActivitiesForGroupState } from '@/activities/timeline/states/timelineActivitiesForGroupState'; -import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; -import { sortObjectRecordByDateField } from '@/object-record/utils/sortObjectRecordByDateField'; -import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; -import { isDefined } from '~/utils/isDefined'; - -export const TimelineQueryEffect = ({ - targetableObject, -}: { - targetableObject: ActivityTargetableObject; -}) => { - const setTimelineTargetableObject = useSetRecoilState( - objectShowPageTargetableObjectState, - ); - - useEffect(() => { - setTimelineTargetableObject(targetableObject); - }, [targetableObject, setTimelineTargetableObject]); - - const { activities } = useActivities({ - targetableObjects: [targetableObject], - activitiesFilters: {}, - activitiesOrderByVariables: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY, - skip: !isDefined(targetableObject), - }); - - const [timelineActivitiesForGroup, setTimelineActivitiesForGroup] = - useRecoilState(timelineActivitiesForGroupState); - - useEffect(() => { - if (!isDefined(targetableObject)) { - return; - } - - const activitiesForGroup = [ - ...activities.map((activity) => ({ - id: activity.id, - createdAt: activity.createdAt, - __typename: activity.__typename, - })), - ].sort(sortObjectRecordByDateField('createdAt', 'DescNullsLast')); - - const timelineActivitiesForGroupSorted = [ - ...timelineActivitiesForGroup, - ].sort(sortObjectRecordByDateField('createdAt', 'DescNullsLast')); - - if (!isDeeplyEqual(activitiesForGroup, timelineActivitiesForGroupSorted)) { - setTimelineActivitiesForGroup(activitiesForGroup); - } - }, [ - activities, - targetableObject, - timelineActivitiesForGroup, - setTimelineActivitiesForGroup, - ]); - - const updateTimelineActivities = useRecoilCallback( - ({ snapshot, set }) => - (newActivities: Activity[]) => { - for (const newActivity of newActivities) { - const currentActivity = snapshot - .getLoadable(timelineActivitiesFamilyState(newActivity.id)) - .getValue(); - - if (!isDeeplyEqual(newActivity, currentActivity)) { - set(timelineActivitiesFamilyState(newActivity.id), newActivity); - } - - const currentActivityWithoutTarget = snapshot - .getLoadable( - timelineActivityWithoutTargetsFamilyState(newActivity.id), - ) - .getValue(); - - const newActivityWithoutTarget = { - id: newActivity.id, - title: newActivity.title, - createdAt: newActivity.createdAt, - author: newActivity.author, - type: newActivity.type, - }; - - if ( - !isDeeplyEqual( - newActivityWithoutTarget, - currentActivityWithoutTarget, - ) - ) { - set( - timelineActivityWithoutTargetsFamilyState(newActivity.id), - newActivityWithoutTarget, - ); - } - } - }, - [], - ); - - useEffect(() => { - updateTimelineActivities(activities); - }, [activities, updateTimelineActivities]); - - return <>; -}; diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelingeActivityGroup.tsx b/packages/twenty-front/src/modules/activities/timeline/components/TimelingeActivityGroup.tsx deleted file mode 100644 index 98a0933f5..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelingeActivityGroup.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import styled from '@emotion/styled'; - -import { ActivityGroup } from '../utils/groupActivitiesByMonth'; - -import { TimelineActivity } from './TimelineActivity'; - -type TimelineActivityGroupProps = { - group: ActivityGroup; - month: string; - year?: number; -}; - -const StyledActivityGroup = styled.div` - display: flex; - flex-flow: column; - gap: ${({ theme }) => theme.spacing(4)}; - margin-bottom: ${({ theme }) => theme.spacing(4)}; - width: 100%; -`; - -const StyledActivityGroupContainer = styled.div` - padding-bottom: ${({ theme }) => theme.spacing(2)}; - padding-top: ${({ theme }) => theme.spacing(2)}; - position: relative; -`; - -const StyledActivityGroupBar = styled.div` - align-items: center; - background: ${({ theme }) => theme.background.secondary}; - border: 1px solid ${({ theme }) => theme.border.color.light}; - border-radius: ${({ theme }) => theme.border.radius.xl}; - display: flex; - flex-direction: column; - height: 100%; - justify-content: center; - position: absolute; - top: 0; - width: 24px; -`; - -const StyledMonthSeperator = styled.div` - align-items: center; - align-self: stretch; - color: ${({ theme }) => theme.font.color.light}; - display: flex; - gap: ${({ theme }) => theme.spacing(4)}; -`; -const StyledMonthSeperatorLine = styled.div` - background: ${({ theme }) => theme.border.color.light}; - border-radius: 50px; - flex: 1 0 0; - height: 1px; -`; - -export const TimelineActivityGroup = ({ - group, - month, - year, -}: TimelineActivityGroupProps) => { - return ( - - - {month} {year} - - - - - {group.items.map((activity, index) => ( - - ))} - - - ); -}; diff --git a/packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useTimelineActivities.test.tsx b/packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useTimelineActivities.test.tsx deleted file mode 100644 index 59f931b04..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/hooks/__tests__/useTimelineActivities.test.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { ReactNode } from 'react'; -import { MockedProvider } from '@apollo/client/testing'; -import { renderHook } from '@testing-library/react'; -import { RecoilRoot } from 'recoil'; - -import { useTimelineActivities } from '@/activities/timeline/hooks/useTimelineActivities'; -import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope'; - -const Wrapper = ({ children }: { children: ReactNode }) => ( - - - - {children} - - - -); - -// FIXME: The hook is re-rendering so many times that it's causing a maximum -// update depth exceeded error. We need to fix this before we can write a proper test. -describe('useTimelineActivities', () => { - it('works as expected', () => { - try { - renderHook( - () => - useTimelineActivities({ - targetableObject: { - id: '123', - targetObjectNameSingular: 'person', - }, - }), - { wrapper: Wrapper }, - ); - } catch (e) { - expect((e as Error).message).toMatch(/^Maximum update depth exceeded/); - } - }); -}); diff --git a/packages/twenty-front/src/modules/activities/timeline/hooks/useTimelineActivities.ts b/packages/twenty-front/src/modules/activities/timeline/hooks/useTimelineActivities.ts deleted file mode 100644 index 73eade961..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/hooks/useTimelineActivities.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { useEffect } from 'react'; -import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards'; -import { useRecoilCallback, useRecoilState } from 'recoil'; - -import { useActivityTargetsForTargetableObject } from '@/activities/hooks/useActivityTargetsForTargetableObject'; -import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectIdState'; -import { makeTimelineActivitiesQueryVariables } from '@/activities/timeline/utils/makeTimelineActivitiesQueryVariables'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; -import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; -import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; -import { sortByAscString } from '~/utils/array/sortByAscString'; -import { isDefined } from '~/utils/isDefined'; - -export const useTimelineActivities = ({ - targetableObject, -}: { - targetableObject: ActivityTargetableObject; -}) => { - const [, setObjectShowPageTargetableObject] = useRecoilState( - objectShowPageTargetableObjectState, - ); - - useEffect(() => { - if (isDefined(targetableObject)) { - setObjectShowPageTargetableObject(targetableObject); - } - }, [targetableObject, setObjectShowPageTargetableObject]); - - const { activityTargets, loadingActivityTargets } = - useActivityTargetsForTargetableObject({ - targetableObject, - }); - - const activityIds = Array.from( - new Set( - activityTargets - ? [ - ...activityTargets - .map((activityTarget) => activityTarget.activityId) - .filter(isNonEmptyString), - ].sort(sortByAscString) - : [], - ), - ); - - const timelineActivitiesQueryVariables = makeTimelineActivitiesQueryVariables( - { - activityIds, - }, - ); - - const { records: activities, loading: loadingActivities } = - useFindManyRecords({ - skip: loadingActivityTargets || !isNonEmptyArray(activityTargets), - objectNameSingular: CoreObjectNameSingular.Activity, - filter: timelineActivitiesQueryVariables.filter, - orderBy: timelineActivitiesQueryVariables.orderBy, - onCompleted: useRecoilCallback( - ({ set }) => - (activities) => { - for (const activity of activities) { - set(recordStoreFamilyState(activity.id), activity); - } - }, - [], - ), - }); - - const loading = loadingActivities || loadingActivityTargets; - - return { - activities, - loading, - }; -}; diff --git a/packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesFamilyState.ts b/packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesFamilyState.ts deleted file mode 100644 index 88903b6c8..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesFamilyState.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Activity } from '@/activities/types/Activity'; -import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState'; - -export const timelineActivitiesFamilyState = createFamilyState< - Activity | null, - string ->({ - key: 'timelineActivitiesFamilyState', - defaultValue: null, -}); diff --git a/packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesForGroupState.ts b/packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesForGroupState.ts deleted file mode 100644 index 450dc5bc7..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/states/timelineActivitiesForGroupState.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createState } from 'twenty-ui'; - -import { ActivityForActivityGroup } from '@/activities/timeline/utils/groupActivitiesByMonth'; - -export const timelineActivitiesForGroupState = createState< - ActivityForActivityGroup[] ->({ - key: 'timelineActivitiesForGroupState', - defaultValue: [], -}); diff --git a/packages/twenty-front/src/modules/activities/timeline/states/timelineActivityWithoutTargetsFamilyState.ts b/packages/twenty-front/src/modules/activities/timeline/states/timelineActivityWithoutTargetsFamilyState.ts deleted file mode 100644 index ac8c0f208..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/states/timelineActivityWithoutTargetsFamilyState.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Activity } from '@/activities/types/Activity'; -import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState'; - -export const timelineActivityWithoutTargetsFamilyState = createFamilyState< - Pick | null, - string ->({ - key: 'timelineActivityWithoutTargetsFamilyState', - defaultValue: null, -}); diff --git a/packages/twenty-front/src/modules/activities/timeline/utils/__tests__/groupActivitiesByMonth.test.ts b/packages/twenty-front/src/modules/activities/timeline/utils/__tests__/groupActivitiesByMonth.test.ts deleted file mode 100644 index 3be8f3dd7..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/utils/__tests__/groupActivitiesByMonth.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ActivityForDrawer } from '@/activities/types/ActivityForDrawer'; -import { mockedActivities } from '~/testing/mock-data/activities'; - -import { groupActivitiesByMonth } from '../groupActivitiesByMonth'; - -describe('groupActivitiesByMonth', () => { - it('should group activities by month', () => { - const grouped = groupActivitiesByMonth( - mockedActivities as unknown as ActivityForDrawer[], - ); - - expect(grouped).toHaveLength(2); - expect(grouped[0].items).toHaveLength(1); - expect(grouped[1].items).toHaveLength(1); - - expect(grouped[0].year).toBe(new Date().getFullYear()); - expect(grouped[1].year).toBe(2023); - - expect(grouped[0].month).toBe(new Date().getMonth()); - expect(grouped[1].month).toBe(3); - }); -}); diff --git a/packages/twenty-front/src/modules/activities/timeline/utils/groupActivitiesByMonth.ts b/packages/twenty-front/src/modules/activities/timeline/utils/groupActivitiesByMonth.ts deleted file mode 100644 index 5764e6ee1..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/utils/groupActivitiesByMonth.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Activity } from '@/activities/types/Activity'; -import { isDefined } from '~/utils/isDefined'; - -export type ActivityForActivityGroup = Pick< - Activity, - 'id' | 'createdAt' | '__typename' ->; - -export type ActivityGroup = { - month: number; - year: number; - items: ActivityForActivityGroup[]; -}; - -export const groupActivitiesByMonth = ( - activities: ActivityForActivityGroup[], -) => { - const acitivityGroups: ActivityGroup[] = []; - - for (const activity of activities) { - const d = new Date(activity.createdAt); - const month = d.getMonth(); - const year = d.getFullYear(); - - const matchingGroup = acitivityGroups.find( - (x) => x.year === year && x.month === month, - ); - if (isDefined(matchingGroup)) { - matchingGroup.items.push(activity); - } else { - acitivityGroups.push({ - year, - month, - items: [activity], - }); - } - } - - return acitivityGroups.sort((a, b) => b.year - a.year || b.month - a.month); -}; diff --git a/packages/twenty-front/src/modules/activities/timeline/utils/makeTimelineActivitiesQueryVariables.ts b/packages/twenty-front/src/modules/activities/timeline/utils/makeTimelineActivitiesQueryVariables.ts deleted file mode 100644 index 4a9c67f5b..000000000 --- a/packages/twenty-front/src/modules/activities/timeline/utils/makeTimelineActivitiesQueryVariables.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { RecordGqlOperationVariables } from '@/object-record/graphql/types/RecordGqlOperationVariables'; -import { sortByAscString } from '~/utils/array/sortByAscString'; - -// Todo: this should be replace by the operationSignatureFactory pattern -export const makeTimelineActivitiesQueryVariables = ({ - activityIds, -}: { - activityIds: string[]; -}): RecordGqlOperationVariables => { - return { - filter: { - id: { - in: [...activityIds].sort(sortByAscString), - }, - }, - orderBy: [ - { - createdAt: 'DescNullsFirst', - }, - ], - }; -}; diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/components/EventRow.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/components/EventRow.tsx index 050b5c1b3..902a7b728 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/components/EventRow.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/components/EventRow.tsx @@ -1,9 +1,9 @@ -import { useContext } from 'react'; import styled from '@emotion/styled'; +import { useContext } from 'react'; import { useRecoilValue } from 'recoil'; -import { useLinkedObject } from '@/activities/timeline/hooks/useLinkedObject'; import { TimelineActivityContext } from '@/activities/timelineActivities/contexts/TimelineActivityContext'; +import { useLinkedObject } from '@/activities/timelineActivities/hooks/useLinkedObject'; import { EventIconDynamicComponent } from '@/activities/timelineActivities/rows/components/EventIconDynamicComponent'; import { EventRowDynamicComponent } from '@/activities/timelineActivities/rows/components/EventRowDynamicComponent'; import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity'; diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivities.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivities.tsx index f24972e95..b94921254 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivities.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivities.tsx @@ -2,8 +2,8 @@ import styled from '@emotion/styled'; import { CustomResolverFetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader'; import { SkeletonLoader } from '@/activities/components/SkeletonLoader'; -import { TimelineCreateButtonGroup } from '@/activities/timeline/components/TimelineCreateButtonGroup'; import { EventList } from '@/activities/timelineActivities/components/EventList'; +import { TimelineCreateButtonGroup } from '@/activities/timelineActivities/components/TimelineCreateButtonGroup'; import { useTimelineActivities } from '@/activities/timelineActivities/hooks/useTimelineActivities'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder'; @@ -35,8 +35,10 @@ const StyledMainContainer = styled.div` export const TimelineActivities = ({ targetableObject, + isInRightDrawer = false, }: { targetableObject: ActivityTargetableObject; + isInRightDrawer?: boolean; }) => { const { timelineActivities, loading, fetchMoreRecords } = useTimelineActivities(targetableObject); @@ -63,7 +65,7 @@ export const TimelineActivities = ({ There are no activities associated with this record.{' '} - + ); } diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivitiesQueryEffect.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivitiesQueryEffect.tsx index ef455eca9..485c41406 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivitiesQueryEffect.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineActivitiesQueryEffect.tsx @@ -1,6 +1,7 @@ import { useActivities } from '@/activities/hooks/useActivities'; -import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FindManyTimelineActivitiesOrderBy'; +import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timelineActivities/constants/FindManyTimelineActivitiesOrderBy'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { isDefined } from '~/utils/isDefined'; export const TimelineActivitiesQueryEffect = ({ @@ -9,6 +10,8 @@ export const TimelineActivitiesQueryEffect = ({ targetableObject: ActivityTargetableObject; }) => { useActivities({ + objectNameSingular: + targetableObject.targetObjectNameSingular as CoreObjectNameSingular, targetableObjects: [targetableObject], activitiesFilters: {}, activitiesOrderByVariables: FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY, diff --git a/packages/twenty-front/src/modules/activities/timeline/components/TimelineCreateButtonGroup.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineCreateButtonGroup.tsx similarity index 81% rename from packages/twenty-front/src/modules/activities/timeline/components/TimelineCreateButtonGroup.tsx rename to packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineCreateButtonGroup.tsx index a4ca49149..2889dfc77 100644 --- a/packages/twenty-front/src/modules/activities/timeline/components/TimelineCreateButtonGroup.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/components/TimelineCreateButtonGroup.tsx @@ -6,8 +6,14 @@ import { ButtonGroup } from '@/ui/input/button/components/ButtonGroup'; import { TAB_LIST_COMPONENT_ID } from '@/ui/layout/show-page/components/ShowPageRightContainer'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; -export const TimelineCreateButtonGroup = () => { - const { activeTabIdState } = useTabList(TAB_LIST_COMPONENT_ID); +export const TimelineCreateButtonGroup = ({ + isInRightDrawer = false, +}: { + isInRightDrawer?: boolean; +}) => { + const { activeTabIdState } = useTabList( + `${TAB_LIST_COMPONENT_ID}-${isInRightDrawer}`, + ); const setActiveTabId = useSetRecoilState(activeTabIdState); return ( diff --git a/packages/twenty-front/src/modules/activities/timeline/constants/FindManyTimelineActivitiesOrderBy.ts b/packages/twenty-front/src/modules/activities/timelineActivities/constants/FindManyTimelineActivitiesOrderBy.ts similarity index 100% rename from packages/twenty-front/src/modules/activities/timeline/constants/FindManyTimelineActivitiesOrderBy.ts rename to packages/twenty-front/src/modules/activities/timelineActivities/constants/FindManyTimelineActivitiesOrderBy.ts diff --git a/packages/twenty-front/src/modules/activities/timeline/hooks/useLinkedObject.ts b/packages/twenty-front/src/modules/activities/timelineActivities/hooks/useLinkedObject.ts similarity index 100% rename from packages/twenty-front/src/modules/activities/timeline/hooks/useLinkedObject.ts rename to packages/twenty-front/src/modules/activities/timelineActivities/hooks/useLinkedObject.ts diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/hooks/useTimelineActivities.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/hooks/useTimelineActivities.tsx index e18dff4be..843586660 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/hooks/useTimelineActivities.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/hooks/useTimelineActivities.tsx @@ -1,7 +1,9 @@ import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getActivityTargetObjectFieldIdName'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; // do we need to test this? @@ -12,6 +14,10 @@ export const useTimelineActivities = ( nameSingular: targetableObject.targetObjectNameSingular, }); + const { objectMetadataItem } = useObjectMetadataItem({ + objectNameSingular: CoreObjectNameSingular.TimelineActivity, + }); + const { records: TimelineActivities, loading, @@ -28,18 +34,7 @@ export const useTimelineActivities = ( createdAt: 'DescNullsFirst', }, ], - recordGqlFields: { - id: true, - createdAt: true, - linkedObjectMetadataId: true, - linkedRecordCachedName: true, - linkedRecordId: true, - name: true, - properties: true, - happensAt: true, - workspaceMember: true, - person: true, - }, + recordGqlFields: generateDepthOneRecordGqlFields({ objectMetadataItem }), fetchPolicy: 'cache-and-network', }); diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/rows/activity/components/EventRowActivity.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/rows/activity/components/EventRowActivity.tsx index dbf363f53..ffb341b03 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/rows/activity/components/EventRowActivity.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/rows/activity/components/EventRowActivity.tsx @@ -7,6 +7,7 @@ import { StyledEventRowItemAction, StyledEventRowItemColumn, } from '@/activities/timelineActivities/rows/components/EventRowDynamicComponent'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; type EventRowActivityProps = EventRowDynamicComponentProps; @@ -19,11 +20,10 @@ const StyledLinkedActivity = styled.span` export const EventRowActivity = ({ event, authorFullName, -}: EventRowActivityProps) => { + objectNameSingular, +}: EventRowActivityProps & { objectNameSingular: CoreObjectNameSingular }) => { const [, eventAction] = event.name.split('.'); - const openActivityRightDrawer = useOpenActivityRightDrawer(); - if (!event.linkedRecordId) { throw new Error('Could not find linked record id for event'); } @@ -32,6 +32,10 @@ export const EventRowActivity = ({ recordStoreFamilyState(event.linkedRecordId), ); + const openActivityRightDrawer = useOpenActivityRightDrawer({ + objectNameSingular, + }); + return ( <> {authorFullName} diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/rows/components/EventRowDynamicComponent.tsx b/packages/twenty-front/src/modules/activities/timelineActivities/rows/components/EventRowDynamicComponent.tsx index 955450d67..e5542cd35 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/rows/components/EventRowDynamicComponent.tsx +++ b/packages/twenty-front/src/modules/activities/timelineActivities/rows/components/EventRowDynamicComponent.tsx @@ -5,6 +5,7 @@ import { EventRowCalendarEvent } from '@/activities/timelineActivities/rows/cale import { EventRowMainObject } from '@/activities/timelineActivities/rows/main-object/components/EventRowMainObject'; import { EventRowMessage } from '@/activities/timelineActivities/rows/message/components/EventRowMessage'; import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; export interface EventRowDynamicComponentProps { @@ -57,8 +58,7 @@ export const EventRowDynamicComponent = ({ authorFullName={authorFullName} /> ); - case 'task': - case 'note': + case 'linked-task': return ( + ); + case 'linked-note': + return ( + ); case mainObjectMetadataItem?.nameSingular: diff --git a/packages/twenty-front/src/modules/activities/timeline/states/objectShowPageTargetableObjectIdState.ts b/packages/twenty-front/src/modules/activities/timelineActivities/states/objectShowPageTargetableObjectIdState.ts similarity index 100% rename from packages/twenty-front/src/modules/activities/timeline/states/objectShowPageTargetableObjectIdState.ts rename to packages/twenty-front/src/modules/activities/timelineActivities/states/objectShowPageTargetableObjectIdState.ts diff --git a/packages/twenty-front/src/modules/activities/timelineActivities/types/TimelineActivity.ts b/packages/twenty-front/src/modules/activities/timelineActivities/types/TimelineActivity.ts index 5c7a2df20..b3afecd68 100644 --- a/packages/twenty-front/src/modules/activities/timelineActivities/types/TimelineActivity.ts +++ b/packages/twenty-front/src/modules/activities/timelineActivities/types/TimelineActivity.ts @@ -13,4 +13,4 @@ export type TimelineActivity = { linkedRecordId: string; linkedObjectMetadataId: string; __typename: 'TimelineActivity'; -}; +} & Record; diff --git a/packages/twenty-front/src/modules/activities/types/Activity.ts b/packages/twenty-front/src/modules/activities/types/Activity.ts index 6e58e0750..b54fd02a2 100644 --- a/packages/twenty-front/src/modules/activities/types/Activity.ts +++ b/packages/twenty-front/src/modules/activities/types/Activity.ts @@ -1,24 +1,7 @@ -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { Comment } from '@/activities/types/Comment'; -import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; - -export type ActivityType = 'Task' | 'Note'; - export type Activity = { - __typename: 'Activity'; id: string; createdAt: string; updatedAt: string; - completedAt: string | null; - reminderAt: string | null; - dueAt: string | null; - activityTargets: ActivityTarget[]; - type: ActivityType; title: string; - body: string; - author: Pick; - authorId: string; - assignee: Pick | null; - assigneeId: string | null; - comments: Comment[]; + body: string | null; }; diff --git a/packages/twenty-front/src/modules/activities/types/ActivityForDrawer.ts b/packages/twenty-front/src/modules/activities/types/ActivityForDrawer.ts deleted file mode 100644 index 9bd8acb82..000000000 --- a/packages/twenty-front/src/modules/activities/types/ActivityForDrawer.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Activity } from '@/activities/types/Activity'; - -export type ActivityForDrawer = Activity; diff --git a/packages/twenty-front/src/modules/activities/types/ActivityForEditor.ts b/packages/twenty-front/src/modules/activities/types/ActivityForEditor.ts index b31c7e5d2..90ef78b0a 100644 --- a/packages/twenty-front/src/modules/activities/types/ActivityForEditor.ts +++ b/packages/twenty-front/src/modules/activities/types/ActivityForEditor.ts @@ -1,27 +1,6 @@ -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { Comment } from '@/activities/types/Comment'; -import { WorkspaceMember } from '~/generated-metadata/graphql'; +import { Note } from '@/activities/types/Note'; +import { Task } from '@/activities/types/Task'; -export type ActivityForEditor = Pick< - Activity, - | 'id' - | 'title' - | 'body' - | 'type' - | 'completedAt' - | 'dueAt' - | 'updatedAt' - | '__typename' -> & { - comments?: Comment[]; -} & { - assignee?: Pick | null; -} & { - activityTargets?: Array< - Pick< - ActivityTarget, - 'id' | 'companyId' | 'personId' | 'createdAt' | 'updatedAt' | 'activity' - > - >; -}; +export type ActivityForEditor = Partial & + Partial> & + Partial>; diff --git a/packages/twenty-front/src/modules/activities/types/ActivityTargetObject.ts b/packages/twenty-front/src/modules/activities/types/ActivityTargetObject.ts index 382ce817e..31c691a6f 100644 --- a/packages/twenty-front/src/modules/activities/types/ActivityTargetObject.ts +++ b/packages/twenty-front/src/modules/activities/types/ActivityTargetObject.ts @@ -1,9 +1,10 @@ -import { ActivityTarget } from '@/activities/types/ActivityTarget'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { TaskTarget } from '@/activities/types/TaskTarget'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; export type ActivityTargetWithTargetRecord = { targetObjectMetadataItem: ObjectMetadataItem; - activityTarget: ActivityTarget; + activityTarget: NoteTarget | TaskTarget; targetObject: ObjectRecord; }; diff --git a/packages/twenty-front/src/modules/activities/types/GraphQLActivity.ts b/packages/twenty-front/src/modules/activities/types/GraphQLActivity.ts deleted file mode 100644 index 84aa1425f..000000000 --- a/packages/twenty-front/src/modules/activities/types/GraphQLActivity.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { Comment } from '@/activities/types/Comment'; -import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; - -export type ActivityType = 'Task' | 'Note'; - -type ActivityTargetNode = { - node: ActivityTarget; -}; - -type CommentNode = { - node: Comment; -}; - -export type GraphQLActivity = { - __typename: 'Activity'; - id: string; - createdAt: string; - updatedAt: string; - completedAt: string | null; - dueAt: string | null; - activityTargets: { - edges: ActivityTargetNode[]; - }; - type: ActivityType; - title: string; - body: string; - author: Pick; - authorId: string; - assignee: Pick | null; - assigneeId: string | null; - comments: CommentNode[]; -}; diff --git a/packages/twenty-front/src/modules/activities/types/Note.ts b/packages/twenty-front/src/modules/activities/types/Note.ts index ac8abd514..9bdfe61ae 100644 --- a/packages/twenty-front/src/modules/activities/types/Note.ts +++ b/packages/twenty-front/src/modules/activities/types/Note.ts @@ -1,5 +1,7 @@ import { Activity } from '@/activities/types/Activity'; +import { NoteTarget } from '@/activities/types/NoteTarget'; export type Note = Activity & { - type: 'Note'; + noteTargets?: NoteTarget[]; + __typename: 'Note'; }; diff --git a/packages/twenty-front/src/modules/activities/types/ActivityTarget.ts b/packages/twenty-front/src/modules/activities/types/NoteTarget.ts similarity index 66% rename from packages/twenty-front/src/modules/activities/types/ActivityTarget.ts rename to packages/twenty-front/src/modules/activities/types/NoteTarget.ts index 686db05ff..ac35a7821 100644 --- a/packages/twenty-front/src/modules/activities/types/ActivityTarget.ts +++ b/packages/twenty-front/src/modules/activities/types/NoteTarget.ts @@ -1,16 +1,16 @@ -import { Activity } from '@/activities/types/Activity'; +import { Note } from '@/activities/types/Note'; import { Company } from '@/companies/types/Company'; import { Person } from '@/people/types/Person'; -export type ActivityTarget = { +export type NoteTarget = { id: string; createdAt: string; updatedAt: string; companyId?: string | null; personId?: string | null; - activity: Pick; + note: Pick; person?: Pick | null; company?: Pick | null; [key: string]: any; - __typename: 'ActivityTarget'; + __typename: 'NoteTarget'; }; diff --git a/packages/twenty-front/src/modules/activities/types/Task.ts b/packages/twenty-front/src/modules/activities/types/Task.ts index 277316e62..9a4f4be23 100644 --- a/packages/twenty-front/src/modules/activities/types/Task.ts +++ b/packages/twenty-front/src/modules/activities/types/Task.ts @@ -1,5 +1,17 @@ import { Activity } from '@/activities/types/Activity'; +import { TaskTarget } from '@/activities/types/TaskTarget'; +import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; + +type ActivityStatus = 'TODO' | 'IN_PROGRESS' | 'DONE'; export type Task = Activity & { - type: 'Task'; + assignee: Pick< + WorkspaceMember, + 'id' | 'name' | 'avatarUrl' | 'colorScheme' + > | null; + assigneeId: string | null; + status: ActivityStatus | null; + dueAt: string | null; + taskTargets: TaskTarget[]; + __typename: 'Task'; }; diff --git a/packages/twenty-front/src/modules/activities/types/TaskTarget.ts b/packages/twenty-front/src/modules/activities/types/TaskTarget.ts new file mode 100644 index 000000000..b37dedf59 --- /dev/null +++ b/packages/twenty-front/src/modules/activities/types/TaskTarget.ts @@ -0,0 +1,19 @@ +import { Task } from '@/activities/types/Task'; +import { Company } from '@/companies/types/Company'; +import { Person } from '@/people/types/Person'; +import { WorkspaceMember } from '~/generated-metadata/graphql'; + +export type TaskTarget = { + id: string; + createdAt: string; + updatedAt: string; + companyId?: string | null; + personId?: string | null; + taskId: string | null; + task: Pick; + person?: Pick | null; + company?: Pick | null; + assignee?: Partial; + [key: string]: any; + __typename: 'TaskTarget'; +}; diff --git a/packages/twenty-front/src/modules/activities/utils/getActivityPreview.ts b/packages/twenty-front/src/modules/activities/utils/getActivityPreview.ts index 5587a6680..0b171d245 100644 --- a/packages/twenty-front/src/modules/activities/utils/getActivityPreview.ts +++ b/packages/twenty-front/src/modules/activities/utils/getActivityPreview.ts @@ -1,4 +1,6 @@ -export const getActivityPreview = (activityBody: string) => { +// TODO: merge with getFirstNonEmptyLineOfRichText (and one duplicate I saw and also added a note on) + +export const getActivityPreview = (activityBody: string | null) => { const noteBody = activityBody ? JSON.parse(activityBody) : []; return noteBody.length diff --git a/packages/twenty-front/src/modules/activities/utils/getActivitySummary.ts b/packages/twenty-front/src/modules/activities/utils/getActivitySummary.ts index 157cf0e45..39567487e 100644 --- a/packages/twenty-front/src/modules/activities/utils/getActivitySummary.ts +++ b/packages/twenty-front/src/modules/activities/utils/getActivitySummary.ts @@ -1,6 +1,7 @@ import { isArray, isNonEmptyString } from '@sniptt/guards'; -export const getActivitySummary = (activityBody: string) => { +// TODO: merge with getFirstNonEmptyLineOfRichText +export const getActivitySummary = (activityBody: string | null) => { const noteBody = activityBody ? JSON.parse(activityBody) : []; if (!noteBody.length) { diff --git a/packages/twenty-front/src/modules/activities/utils/getActivityTargetsToCreateFromTargetableObjects.ts b/packages/twenty-front/src/modules/activities/utils/getActivityTargetsToCreateFromTargetableObjects.ts index dd20d678d..ec5a982b1 100644 --- a/packages/twenty-front/src/modules/activities/utils/getActivityTargetsToCreateFromTargetableObjects.ts +++ b/packages/twenty-front/src/modules/activities/utils/getActivityTargetsToCreateFromTargetableObjects.ts @@ -1,8 +1,10 @@ import { v4 } from 'uuid'; -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { Note } from '@/activities/types/Note'; +import { NoteTarget } from '@/activities/types/NoteTarget'; +import { Task } from '@/activities/types/Task'; +import { TaskTarget } from '@/activities/types/TaskTarget'; import { getActivityTargetObjectFieldIdName } from '@/activities/utils/getActivityTargetObjectFieldIdName'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; @@ -12,9 +14,9 @@ export const makeActivityTargetsToCreateFromTargetableObjects = ({ targetObjectRecords, }: { targetableObjects: ActivityTargetableObject[]; - activity: Activity; + activity: Task | Note; targetObjectRecords: ObjectRecord[]; -}): Partial[] => { +}): Partial[] => { const activityTargetsToCreate = targetableObjects.map((targetableObject) => { const targetableObjectFieldIdName = getActivityTargetObjectFieldIdName({ nameSingular: targetableObject.targetObjectNameSingular, @@ -32,7 +34,7 @@ export const makeActivityTargetsToCreateFromTargetableObjects = ({ id: v4(), updatedAt: new Date().toISOString(), createdAt: new Date().toISOString(), - } as Partial; + } as Partial; return activityTarget; }); diff --git a/packages/twenty-front/src/modules/activities/utils/getJoinObjectNameSingular.ts b/packages/twenty-front/src/modules/activities/utils/getJoinObjectNameSingular.ts new file mode 100644 index 000000000..fa0dca54b --- /dev/null +++ b/packages/twenty-front/src/modules/activities/utils/getJoinObjectNameSingular.ts @@ -0,0 +1,11 @@ +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; + +export const getJoinObjectNameSingular = ( + objectNameSingular: CoreObjectNameSingular, +) => { + return objectNameSingular === CoreObjectNameSingular.Note + ? CoreObjectNameSingular.NoteTarget + : objectNameSingular === CoreObjectNameSingular.Task + ? CoreObjectNameSingular.TaskTarget + : ''; +}; diff --git a/packages/twenty-front/src/modules/apollo/types/coreObjectNamesToDeleteOnRelationDetach.ts b/packages/twenty-front/src/modules/apollo/types/coreObjectNamesToDeleteOnRelationDetach.ts index 90e91f138..43da2774b 100644 --- a/packages/twenty-front/src/modules/apollo/types/coreObjectNamesToDeleteOnRelationDetach.ts +++ b/packages/twenty-front/src/modules/apollo/types/coreObjectNamesToDeleteOnRelationDetach.ts @@ -2,6 +2,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi export const CORE_OBJECT_NAMES_TO_DELETE_ON_TRIGGER_RELATION_DETACH = [ CoreObjectNameSingular.Favorite, - CoreObjectNameSingular.ActivityTarget, + CoreObjectNameSingular.NoteTarget, + CoreObjectNameSingular.TaskTarget, CoreObjectNameSingular.Comment, ]; diff --git a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts index 50a34ff1b..13bf37c5f 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts @@ -113,6 +113,7 @@ export const useAuth = () => { workspaceMember = { ...user.workspaceMember, colorScheme: user.workspaceMember?.colorScheme as ColorScheme, + locale: user.workspaceMember?.locale ?? 'en', }; setCurrentWorkspaceMember(workspaceMember); diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx index 39383072a..3594533cc 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenu.tsx @@ -1,21 +1,24 @@ import styled from '@emotion/styled'; -import { isNonEmptyString } from '@sniptt/guards'; -import { useMemo, useRef } from 'react'; -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; -import { Key } from 'ts-key-enum'; -import { Avatar, IconNotes, IconSparkles, IconX } from 'twenty-ui'; import { useOpenCopilotRightDrawer } from '@/activities/copilot/right-drawer/hooks/useOpenCopilotRightDrawer'; import { copilotQueryState } from '@/activities/copilot/right-drawer/states/copilotQueryState'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; -import { Activity } from '@/activities/types/Activity'; +import { Note } from '@/activities/types/Note'; +import { CommandGroup } from '@/command-menu/components/CommandGroup'; +import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem'; +import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; +import { commandMenuCommandsState } from '@/command-menu/states/commandMenuCommandsState'; import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState'; +import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState'; +import { Command, CommandType } from '@/command-menu/types/Command'; import { Company } from '@/companies/types/Company'; import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { getCompanyDomainName } from '@/object-metadata/utils/getCompanyDomainName'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { makeOrFilterVariables } from '@/object-record/utils/makeOrFilterVariables'; import { Person } from '@/people/types/Person'; +import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem'; import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; @@ -24,19 +27,13 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; +import { isNonEmptyString } from '@sniptt/guards'; +import { useMemo, useRef } from 'react'; +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { Key } from 'ts-key-enum'; +import { Avatar, IconNotes, IconSparkles, IconX, isDefined } from 'twenty-ui'; import { getLogoUrlFromDomainName } from '~/utils'; import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields'; -import { isDefined } from '~/utils/isDefined'; - -import { useCommandMenu } from '../hooks/useCommandMenu'; -import { commandMenuCommandsState } from '../states/commandMenuCommandsState'; -import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState'; -import { Command, CommandType } from '../types/Command'; - -import { getCompanyDomainName } from '@/object-metadata/utils/getCompanyDomainName'; -import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; -import { CommandGroup } from './CommandGroup'; -import { CommandMenuItem } from './CommandMenuItem'; const StyledCommandMenu = styled.div` background: ${({ theme }) => theme.background.secondary}; @@ -123,7 +120,9 @@ export const CommandMenu = () => { const { toggleCommandMenu, onItemClick, closeCommandMenu } = useCommandMenu(); const commandMenuRef = useRef(null); - const openActivityRightDrawer = useOpenActivityRightDrawer(); + const openActivityRightDrawer = useOpenActivityRightDrawer({ + objectNameSingular: CoreObjectNameSingular.Note, + }); const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); const [commandMenuSearch, setCommandMenuSearch] = useRecoilState( commandMenuSearchState, @@ -183,9 +182,9 @@ export const CommandMenu = () => { limit: 3, }); - const { records: activities } = useFindManyRecords({ + const { records: notes } = useFindManyRecords({ skip: !isCommandMenuOpened, - objectNameSingular: CoreObjectNameSingular.Activity, + objectNameSingular: CoreObjectNameSingular.Note, filter: commandMenuSearch ? makeOrFilterVariables([ { title: { ilike: `%${commandMenuSearch}%` } }, @@ -215,24 +214,24 @@ export const CommandMenu = () => { [companies], ); - const activityCommands = useMemo( + const noteCommands = useMemo( () => - activities.map((activity) => ({ - id: activity.id, - label: activity.title ?? '', + notes.map((note) => ({ + id: note.id, + label: note.title ?? '', to: '', - onCommandClick: () => openActivityRightDrawer(activity.id), + onCommandClick: () => openActivityRightDrawer(note.id), })), - [activities, openActivityRightDrawer], + [notes, openActivityRightDrawer], ); const otherCommands = useMemo(() => { return [ ...peopleCommands, ...companyCommands, - ...activityCommands, + ...noteCommands, ] as Command[]; - }, [peopleCommands, companyCommands, activityCommands]); + }, [peopleCommands, companyCommands, noteCommands]); const checkInShortcuts = (cmd: Command, search: string) => { return (cmd.firstHotKey + (cmd.secondHotKey ?? '')) @@ -292,7 +291,7 @@ export const CommandMenu = () => { .concat(matchingNavigateCommand.map((cmd) => cmd.id)) .concat(people.map((person) => person.id)) .concat(companies.map((company) => company.id)) - .concat(activities.map((activity) => activity.id)); + .concat(notes.map((note) => note.id)); return ( <> @@ -340,7 +339,7 @@ export const CommandMenu = () => { !matchingNavigateCommand.length && !people.length && !companies.length && - !activities.length && ( + !notes.length && ( No results found )} {isCopilotEnabled && ( @@ -439,14 +438,14 @@ export const CommandMenu = () => { ))} - {activities.map((activity) => ( - + {notes.map((note) => ( + openActivityRightDrawer(activity.id)} + key={note.id} + label={note.title ?? ''} + onClick={() => openActivityRightDrawer(note.id)} /> ))} diff --git a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx index 43d7b3da3..e28eb6bf8 100644 --- a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawerItems.tsx @@ -1,9 +1,7 @@ import { useLocation } from 'react-router-dom'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; -import { IconCheckbox, IconSearch, IconSettings } from 'twenty-ui'; +import { useSetRecoilState } from 'recoil'; +import { IconSearch, IconSettings } from 'twenty-ui'; -import { CurrentUserDueTaskCountEffect } from '@/activities/tasks/components/CurrentUserDueTaskCountEffect'; -import { currentUserDueTaskCountState } from '@/activities/tasks/states/currentUserTaskCountState'; import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; import { Favorites } from '@/favorites/components/Favorites'; import { ObjectMetadataNavItems } from '@/object-metadata/components/ObjectMetadataNavItems'; @@ -12,13 +10,9 @@ import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/compo import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; -import { useIsTasksPage } from '../hooks/useIsTasksPage'; - export const MainNavigationDrawerItems = () => { const isMobile = useIsMobile(); const { toggleCommandMenu } = useCommandMenu(); - const isTasksPage = useIsTasksPage(); - const currentUserDueTaskCount = useRecoilValue(currentUserDueTaskCountState); const location = useLocation(); const setNavigationMemorizedUrl = useSetRecoilState( navigationMemorizedUrlState, @@ -42,14 +36,6 @@ export const MainNavigationDrawerItems = () => { }} Icon={IconSettings} /> - - )} diff --git a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx index d546a1a4b..ed14eaf67 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { useLocation } from 'react-router-dom'; import { useRecoilValue } from 'recoil'; import { useIcons } from 'twenty-ui'; @@ -10,6 +12,7 @@ import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle'; +import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem'; import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection'; import { View } from '@/views/types/View'; import { getObjectMetadataItemViews } from '@/views/utils/getObjectMetadataItemViews'; @@ -25,6 +28,7 @@ export const ObjectMetadataNavItems = ({ isRemote }: { isRemote: boolean }) => { ); const { getIcon } = useIcons(); const currentPath = useLocation().pathname; + const currentPathWithSearch = currentPath + useLocation().search; const { records: views } = usePrefetchedData(PrefetchKey.AllViews); const loading = useIsPrefetchLoading(); @@ -84,16 +88,41 @@ export const ObjectMetadataNavItems = ({ isRemote }: { isRemote: boolean }) => { viewId ? `?view=${viewId}` : '' }`; + const shouldSubItemsBeDisplayed = + currentPath === `/objects/${objectMetadataItem.namePlural}` && + objectMetadataViews.length > 1; + return ( - + + + {shouldSubItemsBeDisplayed && + objectMetadataViews + .sort((viewA, viewB) => + viewA.key === 'INDEX' + ? -1 + : viewA.position - viewB.position, + ) + .map((view) => ( + + ))} + ); })} diff --git a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts index 5fafc5c64..1148c99dd 100644 --- a/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts +++ b/packages/twenty-front/src/modules/object-metadata/types/CoreObjectNameSingular.ts @@ -15,8 +15,12 @@ export enum CoreObjectNameSingular { MessageChannel = 'messageChannel', MessageParticipant = 'messageParticipant', MessageThread = 'messageThread', + Note = 'note', + NoteTarget = 'noteTarget', Opportunity = 'opportunity', Person = 'person', + Task = 'task', + TaskTarget = 'taskTarget', View = 'view', ViewField = 'viewField', ViewFilter = 'viewFilter', diff --git a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx index 1e40e9526..38ab9211e 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapFieldMetadataToGraphQLQuery.test.tsx @@ -1,11 +1,9 @@ import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock'; import { mapFieldMetadataToGraphQLQuery } from '@/object-metadata/utils/mapFieldMetadataToGraphQLQuery'; +import { normalizeGQLField } from '~/utils/normalizeGQLField'; const mockObjectMetadataItems = getObjectMetadataItemsMock(); -const formatGQLString = (inputString: string) => - inputString.replace(/^\s*[\r\n]/gm, ''); - const personObjectMetadataItem = mockObjectMetadataItems.find( (item) => item.nameSingular === 'person', ); @@ -22,7 +20,7 @@ describe('mapFieldMetadataToGraphQLQuery', () => { (field) => field.name === 'id', )!, }); - expect(formatGQLString(res)).toEqual('id'); + expect(normalizeGQLField(res)).toEqual(normalizeGQLField('id')); }); it('should return fieldName if composite', async () => { const res = mapFieldMetadataToGraphQLQuery({ @@ -31,11 +29,13 @@ describe('mapFieldMetadataToGraphQLQuery', () => { (field) => field.name === 'name', )!, }); - expect(formatGQLString(res)).toEqual(`name + expect(normalizeGQLField(res)).toEqual( + normalizeGQLField(`name { firstName lastName -}`); +}`), + ); }); it('should return non relation subFields if relation', async () => { @@ -45,7 +45,8 @@ describe('mapFieldMetadataToGraphQLQuery', () => { (field) => field.name === 'company', )!, }); - expect(formatGQLString(res)).toEqual(`company + expect(normalizeGQLField(res)).toEqual( + normalizeGQLField(`company { __typename xLink @@ -89,7 +90,8 @@ accountOwnerId employees id idealCustomerProfile -}`); +}`), + ); }); it('should return only return relation subFields that are in recordGqlFields', async () => { @@ -119,7 +121,8 @@ idealCustomerProfile (field) => field.name === 'company', )!, }); - expect(formatGQLString(res)).toEqual(`company + expect(normalizeGQLField(res)).toEqual( + normalizeGQLField(`company { __typename xLink @@ -207,6 +210,7 @@ accountOwnerId employees id idealCustomerProfile -}`); +}`), + ); }); }); diff --git a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx index 36b3d5f77..d1838963d 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx +++ b/packages/twenty-front/src/modules/object-metadata/utils/__tests__/mapObjectMetadataToGraphQLQuery.test.tsx @@ -1,11 +1,9 @@ import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock'; import { mapObjectMetadataToGraphQLQuery } from '@/object-metadata/utils/mapObjectMetadataToGraphQLQuery'; +import { normalizeGQLQuery } from '~/utils/normalizeGQLQuery'; const mockObjectMetadataItems = getObjectMetadataItemsMock(); -const formatGQLString = (inputString: string) => - inputString.replace(/^\s*[\r\n]/gm, ''); - const personObjectMetadataItem = mockObjectMetadataItems.find( (item) => item.nameSingular === 'person', ); @@ -35,80 +33,83 @@ describe('mapObjectMetadataToGraphQLQuery', () => { companyId: true, }, }); - expect(formatGQLString(res)).toEqual(`{ -__typename -xLink -{ - primaryLinkUrl - primaryLinkLabel - secondaryLinks -} -id -createdAt -company -{ -__typename -xLink -{ - primaryLinkUrl - primaryLinkLabel - secondaryLinks -} -linkedinLink -{ - primaryLinkUrl - primaryLinkLabel - secondaryLinks -} -domainName -{ - primaryLinkUrl - primaryLinkLabel - secondaryLinks -} -annualRecurringRevenue -{ - amountMicros - currencyCode -} -createdAt -address -{ - addressStreet1 - addressStreet2 - addressCity - addressState - addressCountry - addressPostcode - addressLat - addressLng -} -updatedAt -name -accountOwnerId -employees -id -idealCustomerProfile -} -city -email -jobTitle -name -{ - firstName - lastName -} -phone -linkedinLink -{ - primaryLinkUrl - primaryLinkLabel - secondaryLinks -} -updatedAt -avatarUrl -companyId -}`); + expect(normalizeGQLQuery(res)).toEqual( + normalizeGQLQuery(`{ + __typename + name + { + firstName + lastName + } + email + phone + createdAt + avatarUrl + jobTitle + city + id + xLink + { + primaryLinkUrl + primaryLinkLabel + secondaryLinks + } + company + { + __typename + idealCustomerProfile + id + xLink + { + primaryLinkUrl + primaryLinkLabel + secondaryLinks + } + annualRecurringRevenue + { + amountMicros + currencyCode + } + address + { + addressStreet1 + addressStreet2 + addressCity + addressState + addressCountry + addressPostcode + addressLat + addressLng + } + employees + position + name + linkedinLink + { + primaryLinkUrl + primaryLinkLabel + secondaryLinks + } + createdAt + accountOwnerId + domainName + { + primaryLinkUrl + primaryLinkLabel + secondaryLinks + } + updatedAt + } + updatedAt + companyId + linkedinLink + { + primaryLinkUrl + primaryLinkLabel + secondaryLinks + } + }`), + ); }); it('should load only specified operation fields nested', async () => { @@ -117,7 +118,8 @@ companyId objectMetadataItem: personObjectMetadataItem, recordGqlFields: { company: { id: true }, id: true, name: true }, }); - expect(formatGQLString(res)).toEqual(`{ + expect(normalizeGQLQuery(res)).toEqual( + normalizeGQLQuery(`{ __typename id company @@ -130,6 +132,7 @@ name firstName lastName } -}`); +}`), + ); }); }); diff --git a/packages/twenty-front/src/modules/object-metadata/utils/getLabelIdentifierFieldValue.ts b/packages/twenty-front/src/modules/object-metadata/utils/getLabelIdentifierFieldValue.ts index 001cf4ecb..d63ff4c20 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/getLabelIdentifierFieldValue.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/getLabelIdentifierFieldValue.ts @@ -16,6 +16,14 @@ export const getLabelIdentifierFieldValue = ( 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)) { return String(record[labelIdentifierFieldMetadataItem.name]); } diff --git a/packages/twenty-front/src/modules/object-metadata/utils/getLinkToShowPage.ts b/packages/twenty-front/src/modules/object-metadata/utils/getLinkToShowPage.ts index 4a6510dea..ca92855e8 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/getLinkToShowPage.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/getLinkToShowPage.ts @@ -4,7 +4,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord'; export const getLinkToShowPage = ( objectNameSingular: string, - record: Pick, + record: Partial, ) => { const basePathToShowPage = getBasePathToShowPage({ objectNameSingular, @@ -13,6 +13,22 @@ export const getLinkToShowPage = ( const isWorkspaceMemberObjectMetadata = objectNameSingular === CoreObjectNameSingular.WorkspaceMember; + if (objectNameSingular === CoreObjectNameSingular.NoteTarget) { + return ( + getBasePathToShowPage({ + objectNameSingular: CoreObjectNameSingular.Note, + }) + record.note?.id + ); + } + + if (objectNameSingular === CoreObjectNameSingular.TaskTarget) { + return ( + getBasePathToShowPage({ + objectNameSingular: CoreObjectNameSingular.Task, + }) + record.task?.id + ); + } + const linkToShowPage = isWorkspaceMemberObjectMetadata || !record.id ? '' diff --git a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts index eff84e050..bf102d994 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/getObjectMetadataItemsMock.ts @@ -1,3670 +1,14137 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; export const getObjectMetadataItemsMock = () => { - const mockArray = [ - { - __typename: 'object', - id: '20202020-ddee-40de-9c9b-5f82a3503360', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'webhook', - namePlural: 'webhooks', - labelSingular: 'Webhook', - labelPlural: 'Webhooks', - description: 'A webhook', - icon: 'IconRobot', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [], - }, - { - __typename: 'object', - id: '20202020-d8d0-4c2d-a370-5499b2181d02', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'apiKey', - namePlural: 'apiKeys', - labelSingular: 'Api Key', - labelPlural: 'Api Keys', - description: 'An api key', - icon: 'IconRobot', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-a092-41e2-940e-e17cd0403aa7', - type: 'DATE_TIME', - name: 'expiresAt', - label: 'Expiration date', - description: 'ApiKey expiration date', - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.251Z', - updatedAt: '2023-11-30T11:13:15.251Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-435c-4133-93c0-df5709d1694d', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.251Z', - updatedAt: '2023-11-30T11:13:15.251Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-ecd6-479f-8368-5032fdee43b3', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.251Z', - updatedAt: '2023-11-30T11:13:15.251Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7222-45ee-b5c4-c30eba68566f', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.251Z', - updatedAt: '2023-11-30T11:13:15.251Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-1dfa-4ef3-8d19-51e82c28677a', - type: 'TEXT', - name: 'name', - label: 'Name', - description: 'ApiKey name', - icon: 'IconLink', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.251Z', - updatedAt: '2023-11-30T11:13:15.251Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-da41-436e-8498-b1a99c23b275', - type: 'DATE_TIME', - name: 'revokedAt', - label: 'Revocation date', - description: 'ApiKey revocation date', - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.251Z', - updatedAt: '2023-11-30T11:13:15.251Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-cf28-41dd-b98b-d6e1f5b3a251', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'viewSort', - namePlural: 'viewSorts', - labelSingular: 'View Sort', - labelPlural: 'View Sorts', - description: '(System) View Sorts', - icon: 'IconArrowsSort', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-077e-4451-b1d8-e602c956ebd2', - type: 'TEXT', - name: 'direction', - label: 'Direction', - description: 'View Sort direction', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.361Z', - updatedAt: '2023-11-30T11:13:15.361Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-cb2c-4c8f-a289-c9851b23d064', - type: 'UUID', - name: 'fieldMetadataId', - label: 'Field Metadata Id', - description: 'View Sort target field', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.361Z', - updatedAt: '2023-11-30T11:13:15.361Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-5870-4665-92a6-a39b7f53352d', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.361Z', - updatedAt: '2023-11-30T11:13:15.361Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7677-4955-8ffe-06481534d12c', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.361Z', - updatedAt: '2023-11-30T11:13:15.361Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-16ec-4074-a54b-c8f7f1178cf6', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.361Z', - updatedAt: '2023-11-30T11:13:15.361Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-f5d0-467f-a3d8-395ba16b8ebf', - type: 'UUID', - name: 'viewId', - label: 'View Id', - description: 'View Sort related view', - icon: 'IconLayoutCollage', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.361Z', - updatedAt: '2023-11-30T11:13:15.361Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '89f2d604-2372-41ac-b822-8feae0ea31ee', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-767f-473f-8fd0-6cdbefbf8dbe', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'view', - namePlural: 'views', - }, - fromFieldMetadataId: '20202020-3011-4d5c-8133-c01134e733df', - }, - }, - ], - }, - { - __typename: 'object', - id: '20202020-ddee-40de-9c9b-5f82a3503361', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'calendarEvent', - namePlural: 'calendarEvents', - labelSingular: 'Calendar Event', - labelPlural: 'Calendar Events', - description: 'A calendar event', - icon: 'IconCalendarEvent', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [], - }, - { - __typename: 'object', - id: '3aac4582-f677-4d7d-acd5-3e33a039acdd', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'connectedAccount', - namePlural: 'connectedAccounts', - labelSingular: 'Connected Account', - labelPlural: 'Connected Accounts', - description: 'A connected account', - icon: 'IconAt', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2024-06-01T14:55:04.039Z', - updatedAt: '2024-06-01T14:55:04.039Z', - labelIdentifierFieldMetadataId: null, - imageIdentifierFieldMetadataId: null, - fields: [], - }, - { - __typename: 'object', - id: '3aac4582-f677-4d7d-acd5-3e33a039acde', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'messageChannel', - namePlural: 'messageChannels', - labelSingular: 'Message Channel', - labelPlural: 'Message Channels', - description: 'A message channel', - icon: 'IconAt', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2024-06-01T14:55:04.039Z', - updatedAt: '2024-06-01T14:55:04.039Z', - labelIdentifierFieldMetadataId: null, - imageIdentifierFieldMetadataId: null, - fields: [], - }, - { - __typename: 'object', - id: '3aac4582-f677-4d7d-acd5-3e33a039acdf', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'calendarChannel', - namePlural: 'calendarChannels', - labelSingular: 'Calendar Channel', - labelPlural: 'Calendar Channels', - description: 'A calendar channel', - icon: 'IconAt', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2024-06-01T14:55:04.039Z', - updatedAt: '2024-06-01T14:55:04.039Z', - labelIdentifierFieldMetadataId: null, - imageIdentifierFieldMetadataId: null, - fields: [], - }, - { - __typename: 'object', - id: '20202020-cae9-4ff4-9579-f7d9fe44c937', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'opportunity', - namePlural: 'opportunities', - labelSingular: 'Opportunity', - labelPlural: 'Opportunities', - description: 'An opportunity', - icon: 'IconTargetArrow', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: false, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-0655-41df-b938-15d71e589d3e', - type: 'UUID', - name: 'personId', - label: 'Person ID (foreign key)', - description: 'Foreign key for person', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-618e-42da-b3c3-bcd7af76e4c2', - type: 'UUID', - name: 'pointOfContactId', - label: 'Point of Contact ID (foreign key)', - description: 'Foreign key for point of contact', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-437b-4fd7-98bd-00cb91204329', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-31d5-4af5-b016-c61c1c265706', - type: 'RELATION', - name: 'company', - label: 'Company', - description: 'Opportunity company', - icon: 'IconBuildingSkyscraper', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '34b27cf4-b706-4466-824b-bdd1745cf04d', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-480c-434e-b4c7-e22408b97047', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'company', - namePlural: 'companies', - }, - fromFieldMetadataId: '20202020-e3fc-46ff-b552-3e757843f06e', - }, - }, - { - __typename: 'field', - id: '20202020-31d5-4af5-b016-c61c1c2657b9', - type: 'UUID', - name: 'companyId', - label: 'Company ID (foreign key)', - description: 'Foreign key for company', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - id: '20202020-46cc-42bb-90d5-c724921a012d', - type: 'SELECT', - name: 'stage', - label: 'Stage', - description: 'Opportunity stage', - icon: 'IconProgressCheck', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2024-03-21T16:48:40.384Z', - updatedAt: '2024-03-21T16:48:40.384Z', - defaultValue: { - value: 'NEW', - }, - options: [ - { - id: '20202020-aa3b-4c0b-bd90-9d071e3b9bf2', - color: 'red', - label: 'New', - value: 'NEW', - position: 0, - }, - { - id: '20202020-8f9b-4bc3-b0a0-ce6a5085c1cf', - color: 'purple', - label: 'Screening', - value: 'SCREENING', - position: 1, - }, - { - id: '20202020-9797-448d-81e4-49b055a1d19b', - color: 'sky', - label: 'Meeting', - value: 'MEETING', - position: 2, - }, - { - id: '20202020-d542-479c-bc88-3c6d4ee78d09', - color: 'turquoise', - label: 'Proposal', - value: 'PROPOSAL', - position: 3, - }, - { - id: '20202020-b69a-4c9c-ac16-adcba0ec972d', - color: 'yellow', - label: 'Customer', - value: 'CUSTOMER', - position: 4, - }, - ], - fromRelationMetadata: null, - toRelationMetadata: null, - }, - }, - { - __typename: 'field', - id: '20202020-de52-4e7b-a298-db7a7553500f', - type: 'DATE_TIME', - name: 'closeDate', - label: 'Close date', - description: 'Opportunity close date', - icon: 'IconCalendarEvent', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-8c1f-4c83-9a89-7843e586564d', - type: 'CURRENCY', - name: 'amount', - label: 'Amount', - description: 'Opportunity amount', - icon: 'IconCurrencyDollar', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-16ef-476c-8eac-d439b84024cb', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-a39d-4ea9-994f-28d1ebd15904', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-618e-42da-b3c3-bcd7af76e355', - type: 'RELATION', - name: 'pointOfContact', - label: 'Point of Contact', - description: 'Opportunity point of contact', - icon: 'IconUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '5e4c2e1a-ee54-4987-917a-d79142d69bd3', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-c64b-44bc-bd2c-502c99f49dca', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'person', - namePlural: 'people', - }, - fromFieldMetadataId: '20202020-2c2e-418e-ba2d-d28434ff02a6', - }, - }, - { - __typename: 'field', - id: '20202020-0655-41df-b938-15d71e589307', - type: 'RELATION', - name: 'person', - label: 'Person', - description: 'Opportunity person', - icon: 'IconUser', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.308Z', - updatedAt: '2023-11-30T11:13:15.308Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: 'e7c6b729-3f52-422c-8452-aedea5753c96', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-c64b-44bc-bd2c-502c99f49dca', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'person', - namePlural: 'people', - }, - fromFieldMetadataId: '20202020-6bc4-4905-a9d3-4f8d616a19e1', - }, - }, - ], - }, - { - __typename: 'object', - id: '20202020-c64b-44bc-bd2c-502c99f49dca', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'person', - namePlural: 'people', - labelSingular: 'Person', - labelPlural: 'People', - description: 'A person', - icon: 'IconUser', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: false, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-6bc4-4905-a9d3-4f8d616a19e1', - type: 'RELATION', - name: 'opportunities', - label: 'Opportunities', - description: 'Opportunities linked to the contact.', - icon: 'IconTargetArrow', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: { - __typename: 'relation', - id: 'e7c6b729-3f52-422c-8452-aedea5753c96', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-cae9-4ff4-9579-f7d9fe44c937', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'opportunity', - namePlural: 'opportunities', - }, - toFieldMetadataId: '20202020-0655-41df-b938-15d71e589307', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-a3a7-4f63-9303-10226f6055be', - type: 'LINKS', - name: 'xLink', - label: 'X', - description: 'Contact’s X/Twitter account', - icon: 'IconBrandX', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-03cd-4cd0-9afc-92077b69f24f', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2c2e-418e-ba2d-d28434ff02a6', - type: 'RELATION', - name: 'pointOfContactForOpportunities', - label: 'POC for Opportunities', - description: 'Point of Contact for Opportuniites', - icon: 'IconTargetArrow', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: { - __typename: 'relation', - id: '5e4c2e1a-ee54-4987-917a-d79142d69bd3', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-cae9-4ff4-9579-f7d9fe44c937', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'opportunity', - namePlural: 'opportunities', - }, - toFieldMetadataId: '20202020-618e-42da-b3c3-bcd7af76e355', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-bec0-4cf0-bf1c-8b2ed21f027a', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-64e1-4080-b6ad-db03c3809885', - type: 'RELATION', - name: 'company', - label: 'Company', - description: 'Contact’s company', - icon: 'IconBuildingSkyscraper', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '8bb4535e-fd80-4ad8-af6d-06b02b83da32', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-480c-434e-b4c7-e22408b97047', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'company', - namePlural: 'companies', - }, - fromFieldMetadataId: '20202020-68b4-4c8e-af19-738eba2a42a5', - }, - }, - { - __typename: 'field', - id: '20202020-78f8-4b4c-90ff-86adf77590f5', - type: 'TEXT', - name: 'city', - label: 'City', - description: 'Contact’s city', - icon: 'IconMap', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-8a96-4e4b-86fd-ea126530e0c1', - type: 'EMAIL', - name: 'email', - label: 'Email', - description: 'Contact’s Email', - icon: 'IconMail', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-f285-4115-a46c-116522986b29', - type: 'RELATION', - name: 'activityTargets', - label: 'Activities', - description: 'Activities tied to the contact', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: { - __typename: 'relation', - id: '1c515eae-14e8-4042-9af4-50ee725b6de5', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-439a-4a41-83a3-3cda03d01d38', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activityTarget', - namePlural: 'activityTargets', - }, - toFieldMetadataId: '20202020-e56c-43e6-8fce-5619d8c2293a', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-3b86-413e-ab56-0ebd1a583ff3', - type: 'TEXT', - name: 'jobTitle', - label: 'Job Title', - description: 'Contact’s job title', - icon: 'IconBriefcase', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-6268-4165-8774-9aaf45db2b25', - type: 'RELATION', - name: 'favorites', - label: 'Favorites', - description: 'Favorites linked to the contact', - icon: 'IconHeart', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: { - __typename: 'relation', - id: '175b312c-956c-47c4-95f9-1aa0289ba794', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-90e4-4701-a350-8ab75e23e3b8', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'favorite', - namePlural: 'favorites', - }, - toFieldMetadataId: '20202020-0876-4735-8974-ff4d51aafa07', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-5883-4bb3-a308-65271901a1d4', - type: 'RELATION', - name: 'attachments', - label: 'Attachments', - description: 'Attachments linked to the contact.', - icon: 'IconFileImport', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: { - __typename: 'relation', - id: '264dce1c-24da-444c-af1f-4e0b90d06b0b', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-5f98-4317-915d-3779bb821be2', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'attachment', - namePlural: 'attachments', - }, - toFieldMetadataId: '20202020-f67c-4cc5-893c-c6b615527473', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-9b56-4888-bfe3-f6f59aa999e3', - type: 'FULL_NAME', - name: 'name', - label: 'Name', - description: 'Contact’s name', - icon: 'IconUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-486f-45f9-bbdf-aac18b1831c0', - type: 'TEXT', - name: 'phone', - label: 'Phone', - description: 'Contact’s phone number', - icon: 'IconPhone', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-dcf6-445a-b543-37e55de43c25', - type: 'LINKS', - name: 'linkedinLink', - label: 'Linkedin', - description: 'Contact’s Linkedin account', - icon: 'IconBrandLinkedin', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2bf4-42b8-8718-a3e852bfa6a6', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-bb05-45cb-aa2a-71b58d49dd23', - type: 'TEXT', - name: 'avatarUrl', - label: 'Avatar', - description: 'Contact’s avatar', - icon: 'IconFileUpload', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-64e1-4080-b6ad-db03c3809f8b', - type: 'UUID', - name: 'companyId', - label: 'Company ID (foreign key)', - description: 'Foreign key for company', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.331Z', - updatedAt: '2023-11-30T11:13:15.331Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-b550-40bb-a96b-9ab54b664753', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'workspaceMember', - namePlural: 'workspaceMembers', - labelSingular: 'Workspace Member', - labelPlural: 'Workspace Members', - description: 'A workspace member', - icon: 'IconUserCircle', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-83f2-4c5f-96b0-0c51ecc160e3', - type: 'TEXT', - name: 'colorScheme', - label: 'Color Scheme', - description: 'Preferred color scheme', - icon: 'IconColorSwatch', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-8c37-4163-ba06-1dada334ce3e', - type: 'FULL_NAME', - name: 'name', - label: 'Name', - description: 'Workspace member name', - icon: 'IconCircleUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-10f6-4df9-8d6f-a760b65bd800', - type: 'TEXT', - name: 'locale', - label: 'Language', - description: 'Preferred language', - icon: 'IconLanguage', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-f2c1-4ca1-9ca5-7b9d5cc87eb0', - type: 'UUID', - name: 'userId', - label: 'User Id', - description: 'Associated User Id', - icon: 'IconCircleUsers', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-5ecb-405b-8712-171bb8916b96', - type: 'RELATION', - name: 'favorites', - label: 'Favorites', - description: 'Favorites linked to the workspace member', - icon: 'IconHeart', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: { - __typename: 'relation', - id: '71f35744-ab2e-4311-922e-0488aa55b3c5', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-90e4-4701-a350-8ab75e23e3b8', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'favorite', - namePlural: 'favorites', - }, - toFieldMetadataId: '20202020-1138-4e93-bbff-917a68161abf', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7ba6-40d5-934b-17146183a212', - type: 'TEXT', - name: 'avatarUrl', - label: 'Avatar Url', - description: 'Workspace member avatar', - icon: 'IconFileUpload', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-37a0-4db4-9c9f-fd3e3f4e47fc', - type: 'RELATION', - name: 'authoredActivities', - label: 'Authored activities', - description: 'Activities created by the workspace member', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: { - __typename: 'relation', - id: 'fa043ecd-792d-4ece-bc98-24c81fd8daf7', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-8ee3-4f67-84ab-1b7a6eb5a448', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activity', - namePlural: 'activities', - }, - toFieldMetadataId: '20202020-3acb-46bb-b993-0dc49fa2a48c', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-1cbf-4b32-8c33-fbfedcd9afa8', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7238-4e2a-9ccf-d2c8f604933a', - type: 'RELATION', - name: 'authoredComments', - label: 'Authored comments', - description: 'Authored comments', - icon: 'IconComment', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: { - __typename: 'relation', - id: 'f7ebb0a5-c9d6-4d53-9a70-1d736000468a', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-4de3-4e65-ac60-b40b8e08d7d6', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'comment', - namePlural: 'comments', - }, - toFieldMetadataId: '20202020-2c70-40c2-bba6-893780b25d41', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-1ba3-4c24-b2cd-b0789633e8d4', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-678e-4702-a535-2549ef07f1ca', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-ac05-44b9-9526-764dd5ce14e2', - type: 'RELATION', - name: 'assignedActivities', - label: 'Assigned activities', - description: 'Activities assigned to the workspace member', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: { - __typename: 'relation', - id: '5fd21f44-4025-4574-8f58-fed08a4c04f1', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-8ee3-4f67-84ab-1b7a6eb5a448', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activity', - namePlural: 'activities', - }, - toFieldMetadataId: '20202020-4694-4ec6-9084-8d932ebb3065', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7e0c-4dc4-be49-37de4396349e', - type: 'RELATION', - name: 'authoredAttachments', - label: 'Authored attachments', - description: 'Attachments created by the workspace member', - icon: 'IconFileImport', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: { - __typename: 'relation', - id: '4b113dcf-d33b-408b-ae1a-3db7a928ce5f', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-5f98-4317-915d-3779bb821be2', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'attachment', - namePlural: 'attachments', - }, - toFieldMetadataId: '20202020-7831-43c2-827f-bc78289b7398', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-41bb-4c17-8979-40fa915df9e1', - type: 'RELATION', - name: 'accountOwnerForCompanies', - label: 'Account Owner For Companies', - description: 'Account owner for companies', - icon: 'IconBriefcase', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.392Z', - updatedAt: '2023-11-30T11:13:15.392Z', - fromRelationMetadata: { - __typename: 'relation', - id: '35e9f9d0-07ee-4ef9-9ec2-3059b3e76df5', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-480c-434e-b4c7-e22408b97047', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'company', - namePlural: 'companies', - }, - toFieldMetadataId: '20202020-0739-495d-8e70-c0807f6b2268', - }, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-90e4-4701-a350-8ab75e23e3b8', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'favorite', - namePlural: 'favorites', - labelSingular: 'Favorite', - labelPlural: 'Favorites', - description: 'A favorite', - icon: 'IconHeart', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-7d1d-46c7-8c09-8e8c73e30042', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-09e1-4384-ae3e-45e79563d528', - type: 'UUID', - name: 'companyId', - label: 'Company ID (foreign key)', - description: 'Foreign key for company', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-a0f4-443c-a63d-2776a842d024', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-0876-4735-9473-ff4d51aa4e7b', - type: 'UUID', - name: 'personId', - label: 'Person ID (foreign key)', - description: 'Foreign key for person', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-0876-4735-8974-ff4d51aafa07', - type: 'RELATION', - name: 'person', - label: 'Person', - description: 'Favorite person', - icon: 'IconUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '175b312c-956c-47c4-95f9-1aa0289ba794', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-c64b-44bc-bd2c-502c99f49dca', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'person', - namePlural: 'people', - }, - fromFieldMetadataId: '20202020-6268-4165-8774-9aaf45db2b25', - }, - }, - { - __typename: 'field', - id: '20202020-dd6d-4f67-94aa-22cc83eb0a2e', - type: 'NUMBER', - name: 'position', - label: 'Position', - description: 'Favorite position', - icon: 'IconList', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-0f4c-4b9a-9b9a-917a68161a4f', - type: 'UUID', - name: 'workspaceMemberId', - label: 'Workspace Member ID (foreign key)', - description: 'Foreign key for workspace member', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-1138-4e93-bbff-917a68161abf', - type: 'RELATION', - name: 'workspaceMember', - label: 'Workspace Member', - description: 'Favorite workspace member', - icon: 'IconCircleUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '71f35744-ab2e-4311-922e-0488aa55b3c5', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-b550-40bb-a96b-9ab54b664753', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'workspaceMember', - namePlural: 'workspaceMembers', - }, - fromFieldMetadataId: '20202020-5ecb-405b-8712-171bb8916b96', - }, - }, - { - __typename: 'field', - id: '20202020-09e1-4384-ae3e-39e7956396ff', - type: 'RELATION', - name: 'company', - label: 'Company', - description: 'Favorite company', - icon: 'IconBuildingSkyscraper', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '88dd058c-a955-4de9-a41d-f870ef072360', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-480c-434e-b4c7-e22408b97047', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'company', - namePlural: 'companies', - }, - fromFieldMetadataId: '20202020-e7c8-4771-8cc4-ce0e8c36a3c0', - }, - }, - { - __typename: 'field', - id: '20202020-273a-41bc-babf-f58f0b2ba2ec', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.300Z', - updatedAt: '2023-11-30T11:13:15.300Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-8ee3-4f67-84ab-1b7a6eb5a448', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activity', - namePlural: 'activities', - labelSingular: 'Activity', - labelPlural: 'Activities', - description: 'An activity', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-65a2-4d9c-b640-bac54007a14d', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-cd46-44f4-bf22-b0aa20d009da', - type: 'DATE_TIME', - name: 'reminderAt', - label: 'Reminder Date', - description: 'Activity reminder date', - icon: 'IconCalendarEvent', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-3acb-46bb-b993-0dc49fa2a48d', - type: 'UUID', - name: 'authorId', - label: 'Author id (foreign key)', - description: 'Activity author id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-4694-4ec6-9084-8d932ebb3065', - type: 'RELATION', - name: 'assignee', - label: 'Assignee', - description: - 'Acitivity assignee. This is the workspace member assigned to the activity ', - icon: 'IconUserCircle', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '5fd21f44-4025-4574-8f58-fed08a4c04f1', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-b550-40bb-a96b-9ab54b664753', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'workspaceMember', - namePlural: 'workspaceMembers', - }, - fromFieldMetadataId: '20202020-ac05-44b9-9526-764dd5ce14e2', - }, - }, - { - __typename: 'field', - id: '20202020-ec1d-4ffe-8bd2-a85c23ae0037', - type: 'RELATION', - name: 'activityTargets', - label: 'Targets', - description: 'Activity targets', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: { - __typename: 'relation', - id: '04eb67c8-3525-436f-b26b-c08acf48d12e', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-439a-4a41-83a3-3cda03d01d38', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activityTarget', - namePlural: 'activityTargets', - }, - toFieldMetadataId: '20202020-cb21-42c9-bba8-347f7cb02b84', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2584-4797-95a8-5cc90d48c040', - type: 'TEXT', - name: 'title', - label: 'Title', - description: 'Activity title', - icon: 'IconNotes', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-0924-48f0-a8c2-d2dd4e2098e2', - type: 'DATE_TIME', - name: 'completedAt', - label: 'Completion Date', - description: 'Activity completion date', - icon: 'IconCheck', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-3acb-46bb-b993-0dc49fa2a48c', - type: 'RELATION', - name: 'author', - label: 'Author', - description: - 'Activity author. This is the person who created the activity', - icon: 'IconUserCircle', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: 'fa043ecd-792d-4ece-bc98-24c81fd8daf7', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-b550-40bb-a96b-9ab54b664753', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'workspaceMember', - namePlural: 'workspaceMembers', - }, - fromFieldMetadataId: '20202020-37a0-4db4-9c9f-fd3e3f4e47fc', - }, - }, - { - __typename: 'field', - id: '20202020-88df-4202-bf82-6a06c6963280', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-9755-43a8-b621-f94df0f6b839', - type: 'RELATION', - name: 'attachments', - label: 'Attachments', - description: 'Activity attachments', - icon: 'IconFileImport', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: { - __typename: 'relation', - id: '18560266-e8d2-4306-8182-87da1c7c5fee', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-5f98-4317-915d-3779bb821be2', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'attachment', - namePlural: 'attachments', - }, - toFieldMetadataId: '20202020-f5a9-46ec-b39a-eda906f00804', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-aff0-4961-be8a-0e5c2598b9a6', - type: 'TEXT', - name: 'body', - label: 'Body', - description: 'Activity body', - icon: 'IconList', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-c85c-47f2-bbe4-6b36c26f9247', - type: 'RELATION', - name: 'comments', - label: 'Comments', - description: 'Activity comments', - icon: 'IconComment', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: { - __typename: 'relation', - id: '3970abf3-c0bf-4a3a-a02a-81aac69a4073', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-4de3-4e65-ac60-b40b8e08d7d6', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'comment', - namePlural: 'comments', - }, - toFieldMetadataId: '20202020-a9ac-4294-9462-db0f690da906', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-20e1-4366-b386-750bdca2dfe3', - type: 'DATE_TIME', - name: 'dueAt', - label: 'Due Date', - description: 'Activity due date', - icon: 'IconCalendarEvent', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-a243-4b94-a4b4-25705af86be2', - type: 'TEXT', - name: 'type', - label: 'Type', - description: 'Activity type', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-f695-419c-b928-c488323d6df3', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-4694-4ec6-9084-8d932ebb3066', - type: 'UUID', - name: 'assigneeId', - label: 'Assignee id (foreign key)', - description: 'Acitivity assignee id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.244Z', - updatedAt: '2023-11-30T11:13:15.244Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-767f-473f-8fd0-6cdbefbf8dbe', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'view', - namePlural: 'views', - labelSingular: 'View', - labelPlural: 'Views', - description: '(System) Views', - icon: 'IconLayoutCollage', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-2957-4431-b3b5-879b5e687c6e', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2c69-46f0-9cf2-1a4f9869d560', - type: 'UUID', - name: 'objectMetadataId', - label: 'Object Metadata Id', - description: 'View target object', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-3011-4d5c-8133-c01134e733df', - type: 'RELATION', - name: 'viewSorts', - label: 'View Sorts', - description: 'View Sorts', - icon: 'IconArrowsSort', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: { - __typename: 'relation', - id: '89f2d604-2372-41ac-b822-8feae0ea31ee', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-cf28-41dd-b98b-d6e1f5b3a251', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'viewSort', - namePlural: 'viewSorts', - }, - toFieldMetadataId: '20202020-f5d0-467f-a3d8-395ba16b8ebf', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2c70-46f0-9cf2-1a4f9869d591', - type: 'TEXT', - name: 'type', - label: 'Type', - description: 'View type', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-ad91-42b0-b654-cbd981ddb5bf', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-afe8-40bc-9a81-9b33e45131d9', - type: 'RELATION', - name: 'viewFilters', - label: 'View Filters', - description: 'View Filters', - icon: 'IconFilterBolt', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: { - __typename: 'relation', - id: '962649c6-745a-476a-a4c8-de7794e9a04e', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-4461-4e2d-bf9e-9b47e68846d3', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'viewFilter', - namePlural: 'viewFilters', - }, - toFieldMetadataId: '20202020-65e5-4082-829d-8c634c20e7b5', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-e10e-4346-8690-b2e582ebc03c', - type: 'TEXT', - name: 'name', - label: 'Name', - description: 'View name', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-d288-4df4-9548-7b5c5747f623', - type: 'RELATION', - name: 'viewFields', - label: 'View Fields', - description: 'View Fields', - icon: 'IconTag', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: { - __typename: 'relation', - id: 'fd72ef3b-fdf6-4d2a-8735-4a996f214f5a', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-485c-4c48-a22e-0d9a164f9647', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'viewField', - namePlural: 'viewFields', - }, - toFieldMetadataId: '20202020-8788-4508-b771-719807b60e61', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-b4e6-4044-8f6e-886c6eb2a67c', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.343Z', - updatedAt: '2023-11-30T11:13:15.343Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-5f98-4317-915d-3779bb821be2', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'attachment', - namePlural: 'attachments', - labelSingular: 'Attachment', - labelPlural: 'Attachments', - description: 'An attachment', - icon: 'IconFileImport', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-f67c-4cc5-893c-c6b615527473', - type: 'RELATION', - name: 'person', - label: 'Person', - description: 'Attachment person', - icon: 'IconUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '264dce1c-24da-444c-af1f-4e0b90d06b0b', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-c64b-44bc-bd2c-502c99f49dca', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'person', - namePlural: 'people', - }, - fromFieldMetadataId: '20202020-5883-4bb3-a308-65271901a1d4', - }, - }, - { - __typename: 'field', - id: '20202020-7831-43c2-827f-bc78289b7398', - type: 'RELATION', - name: 'author', - label: 'Author', - description: 'Attachment author', - icon: 'IconCircleUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '4b113dcf-d33b-408b-ae1a-3db7a928ce5f', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-b550-40bb-a96b-9ab54b664753', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'workspaceMember', - namePlural: 'workspaceMembers', - }, - fromFieldMetadataId: '20202020-7e0c-4dc4-be49-37de4396349e', - }, - }, - { - __typename: 'field', - id: '20202020-7f29-490d-a3e1-9c3015524057', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-5463-4d03-9124-1775b9b7f955', - type: 'RELATION', - name: 'company', - label: 'Company', - description: 'Attachment company', - icon: 'IconBuildingSkyscraper', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: 'de5f7a45-b00b-47a1-8ebc-2beca661a410', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-480c-434e-b4c7-e22408b97047', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'company', - namePlural: 'companies', - }, - fromFieldMetadataId: '20202020-61af-4ffd-b79b-baed6db8ad11', - }, - }, - { - __typename: 'field', - id: '20202020-839b-4cbb-a1be-1a0cb85524a4', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-5683-4c80-8590-255321ece692', - type: 'TEXT', - name: 'name', - label: 'Name', - description: 'Attachment name', - icon: 'IconFileUpload', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-f67c-4cc5-893c-c6b615527474', - type: 'UUID', - name: 'personId', - label: 'Person id (foreign key)', - description: 'Attachment person id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-f5a9-46ec-b39a-eda906f00805', - type: 'UUID', - name: 'activityId', - label: 'Activity id (foreign key)', - description: 'Attachment activity id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-f5a9-46ec-b39a-eda906f00804', - type: 'RELATION', - name: 'activity', - label: 'Activity', - description: 'Attachment activity', - icon: 'IconNotes', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '18560266-e8d2-4306-8182-87da1c7c5fee', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-8ee3-4f67-84ab-1b7a6eb5a448', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activity', - namePlural: 'activities', - }, - fromFieldMetadataId: '20202020-9755-43a8-b621-f94df0f6b839', - }, - }, - { - __typename: 'field', - id: '20202020-5463-4d03-9124-1775b9b7f956', - type: 'UUID', - name: 'companyId', - label: 'Company id (foreign key)', - description: 'Attachment company id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-0544-432b-8f96-84c4d6a94d50', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7831-43c2-827f-bc78289b7399', - type: 'UUID', - name: 'authorId', - label: 'Author id (foreign key)', - description: 'Attachment author id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-8dfa-492f-92d1-56d5fb18cbb7', - type: 'TEXT', - name: 'type', - label: 'Type', - description: 'Attachment type', - icon: 'IconList', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-bb72-4644-b255-afb4ebb83b66', - type: 'TEXT', - name: 'fullPath', - label: 'Full path', - description: 'Attachment full path', - icon: 'IconLink', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.261Z', - updatedAt: '2023-11-30T11:13:15.261Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-4de3-4e65-ac60-b40b8e08d7d6', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'comment', - namePlural: 'comments', - labelSingular: 'Comment', - labelPlural: 'Comments', - description: 'A comment', - icon: 'IconMessageCircle', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202021-a9ac-4294-9462-db0f690da907', - type: 'UUID', - name: 'activityId', - label: 'Activity id (foreign key)', - description: 'Activity id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-a9ac-4294-9462-db0f690da906', - type: 'RELATION', - name: 'activity', - label: 'Activity', - description: 'Comment activity', - icon: 'IconNotes', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '3970abf3-c0bf-4a3a-a02a-81aac69a4073', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-8ee3-4f67-84ab-1b7a6eb5a448', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activity', - namePlural: 'activities', - }, - fromFieldMetadataId: '20202020-c85c-47f2-bbe4-6b36c26f9247', - }, - }, - { - __typename: 'field', - id: '20202020-2899-42fa-ba07-1f4dad7ae28f', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-354b-4f10-9425-fa3eb8fddc51', - type: 'TEXT', - name: 'body', - label: 'Body', - description: 'Comment body', - icon: 'IconLink', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-63dd-4426-abad-9973fece49ed', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-88fd-4db2-9fcb-b5f4f5955cf2', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2c70-40c2-bba6-893780b25d41', - type: 'RELATION', - name: 'author', - label: 'Author', - description: 'Comment author', - icon: 'IconCircleUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: 'f7ebb0a5-c9d6-4d53-9a70-1d736000468a', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-b550-40bb-a96b-9ab54b664753', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'workspaceMember', - namePlural: 'workspaceMembers', - }, - fromFieldMetadataId: '20202020-7238-4e2a-9ccf-d2c8f604933a', - }, - }, - { - __typename: 'field', - id: '20202021-2c70-40c2-bba6-893780b25d42', - type: 'UUID', - name: 'authorId', - label: 'Author id (foreign key)', - description: 'Comment author id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.281Z', - updatedAt: '2023-11-30T11:13:15.281Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-485c-4c48-a22e-0d9a164f9647', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'viewField', - namePlural: 'viewFields', - labelSingular: 'View Field', - labelPlural: 'View Fields', - description: '(System) View Fields', - icon: 'IconTag', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-8788-4508-b771-719807b60e61', - type: 'RELATION', - name: 'view', - label: 'View Id', - description: 'View Field related view', - icon: 'IconLayoutCollage', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: 'fd72ef3b-fdf6-4d2a-8735-4a996f214f5a', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-767f-473f-8fd0-6cdbefbf8dbe', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'view', - namePlural: 'views', - }, - fromFieldMetadataId: '20202020-d288-4df4-9548-7b5c5747f623', - }, - }, - { - __typename: 'field', - id: '20202020-a4bb-440a-add2-81dbd9a74517', - type: 'NUMBER', - name: 'position', - label: 'Position', - description: 'View Field position', - icon: 'IconList', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-3aa9-42db-a74d-0fd6b7cb7c4a', - type: 'BOOLEAN', - name: 'isVisible', - label: 'Visible', - description: 'View Field visibility', - icon: 'IconEye', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-1a5e-4ac1-9530-c7fff8481b79', - type: 'UUID', - name: 'fieldMetadataId', - label: 'Field Metadata Id', - description: 'View Field target field', - icon: 'IconTag', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-c852-4c28-b13a-07788c845d6a', - type: 'UUID', - name: 'viewId', - label: 'View ID (foreign key)', - description: 'Foreign key for view', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-64f2-4ecf-b4c5-45daf154756a', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-b9a1-4c2e-a5af-3a6b4fef4af6', - type: 'NUMBER', - name: 'size', - label: 'Size', - description: 'View Field size', - icon: 'IconEye', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-e137-4e59-b417-a134c050936c', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-17ff-4585-9f3b-cd9ee9523448', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.349Z', - updatedAt: '2023-11-30T11:13:15.349Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-480c-434e-b4c7-e22408b97047', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'company', - namePlural: 'companies', - labelSingular: 'Company', - labelPlural: 'Companies', - description: 'A company', - icon: 'IconBuildingSkyscraper', - isCustom: false, - isActive: true, - isSystem: false, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-46e3-479a-b8f4-77137c74daa6', - type: 'LINKS', - name: 'xLink', - label: 'X', - description: 'The company Twitter/X account', - icon: 'IconBrandX', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-0739-495d-8e70-c0807f6b2268', - type: 'RELATION', - name: 'accountOwner', - label: 'Account Owner', - description: - 'Your team member responsible for managing the company account', - icon: 'IconUserCircle', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '35e9f9d0-07ee-4ef9-9ec2-3059b3e76df5', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-b550-40bb-a96b-9ab54b664753', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'workspaceMember', - namePlural: 'workspaceMembers', - }, - fromFieldMetadataId: '20202020-41bb-4c17-8979-40fa915df9e1', - }, - }, - { - __typename: 'field', - id: '20202020-a61d-4b78-b998-3fd88b4f73a1', - type: 'LINKS', - name: 'linkedinLink', - label: 'Linkedin', - description: 'The company Linkedin account', - icon: 'IconBrandLinkedin', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-61af-4ffd-b79b-baed6db8ad11', - type: 'RELATION', - name: 'attachments', - label: 'Attachments', - description: 'Attachments linked to the company.', - icon: 'IconFileImport', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: { - __typename: 'relation', - id: 'de5f7a45-b00b-47a1-8ebc-2beca661a410', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-5f98-4317-915d-3779bb821be2', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'attachment', - namePlural: 'attachments', - }, - toFieldMetadataId: '20202020-5463-4d03-9124-1775b9b7f955', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-5e4e-4007-a630-8a2617914889', - type: 'LINKS', - name: 'domainName', - label: 'Domain Name', - description: - 'The company website URL. We use this url to fetch the company icon', - icon: 'IconLink', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-e3fc-46ff-b552-3e757843f06e', - type: 'RELATION', - name: 'opportunities', - label: 'Opportunities', - description: 'Opportunities linked to the company.', - icon: 'IconTargetArrow', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: { - __typename: 'relation', - id: '34b27cf4-b706-4466-824b-bdd1745cf04d', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-cae9-4ff4-9579-f7d9fe44c937', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'opportunity', - namePlural: 'opportunities', - }, - toFieldMetadataId: '20202020-31d5-4af5-b016-c61c1c265706', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-4a5a-466f-92d9-c3870d9502a9', - type: 'CURRENCY', - name: 'annualRecurringRevenue', - label: 'ARR', - description: - 'Annual Recurring Revenue: The actual or estimated annual revenue of the company', - icon: 'IconMoneybag', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-4dc2-47c9-bb15-6e6f19ba9e46', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-ad10-4117-a039-3f04b7a5f939', - type: 'ADDRESS', - name: 'address', - label: 'Address', - description: 'The company address', - icon: 'IconMap', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-64b8-41bf-a01c-be6a806e8b70', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-4a2e-4b41-8562-279963e8947e', - type: 'RELATION', - name: 'activityTargets', - label: 'Activities', - description: 'Activities tied to the company', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: { - __typename: 'relation', - id: '311bf27d-3710-4776-8b8d-b4cfba8c0ae8', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-439a-4a41-83a3-3cda03d01d38', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activityTarget', - namePlural: 'activityTargets', - }, - toFieldMetadataId: '20202020-9408-4cc0-9fe1-51467edb530b', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-e7c8-4771-8cc4-ce0e8c36a3c0', - type: 'RELATION', - name: 'favorites', - label: 'Favorites', - description: 'Favorites linked to the company', - icon: 'IconHeart', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: { - __typename: 'relation', - id: '88dd058c-a955-4de9-a41d-f870ef072360', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-90e4-4701-a350-8ab75e23e3b8', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'favorite', - namePlural: 'favorites', - }, - toFieldMetadataId: '20202020-09e1-4384-ae3e-39e7956396ff', - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-68b4-4c8e-af19-738eba2a42a5', - type: 'RELATION', - name: 'people', - label: 'People', - description: 'People linked to the company.', - icon: 'IconUsers', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: { - __typename: 'relation', - id: '8bb4535e-fd80-4ad8-af6d-06b02b83da32', - relationType: 'ONE_TO_MANY', - toObjectMetadata: { - __typename: 'object', - id: '20202020-c64b-44bc-bd2c-502c99f49dca', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'person', - namePlural: 'people', - }, - toFieldMetadataId: '20202020-64e1-4080-b6ad-db03c3809885', - }, - relationDefinition: { - targetObjectMetadata: { - nameSingular: 'person', - }, - targetFieldMetadata: { - name: 'company', - }, - }, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-6d30-4111-9f40-b4301906fd3c', - type: 'TEXT', - name: 'name', - label: 'Name', - description: 'The company name', - icon: 'IconBuildingSkyscraper', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-0b9e-4b9e-8b0a-5b0b5b0b5b0b', - type: 'UUID', - name: 'accountOwnerId', - label: 'Account Owner ID (foreign key)', - description: 'Foreign key for account owner', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7fbd-41ad-b64d-25a15ff62f04', - type: 'NUMBER', - name: 'employees', - label: 'Employees', - description: 'Number of employees in the company', - icon: 'IconUsers', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-8169-44a3-9e0b-6bad1ac50f87', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-9e9f-4235-98b2-c76f3e2d281e', - type: 'BOOLEAN', - name: 'idealCustomerProfile', - label: 'ICP', - description: - 'Ideal Customer Profile: Indicates whether the company is the most suitable and valuable customer for you', - icon: 'IconTarget', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.292Z', - updatedAt: '2023-11-30T11:13:15.292Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-4461-4e2d-bf9e-9b47e68846d3', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'viewFilter', - namePlural: 'viewFilters', - labelSingular: 'View Filter', - labelPlural: 'View Filters', - description: '(System) View Filters', - icon: 'IconFilterBolt', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-da57-452d-9671-ab3ccac2a9da', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-96c9-4cf1-87b4-8a009c591a16', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-1d12-465d-ab2c-8af008182730', - type: 'TEXT', - name: 'operand', - label: 'Operand', - description: 'View Filter operand', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-ed89-4892-83fa-d2b2929c6d52', - type: 'TEXT', - name: 'displayValue', - label: 'Display Value', - description: 'View Filter Display Value', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-65e5-4082-829d-8c634c20e7b5', - type: 'UUID', - name: 'viewId', - label: 'View Id', - description: 'View Filter related view', - icon: 'IconLayoutCollage', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '962649c6-745a-476a-a4c8-de7794e9a04e', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-767f-473f-8fd0-6cdbefbf8dbe', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'view', - namePlural: 'views', - }, - fromFieldMetadataId: '20202020-afe8-40bc-9a81-9b33e45131d9', - }, - }, - { - __typename: 'field', - id: '20202020-78bb-4f2b-a052-260bc8efd694', - type: 'UUID', - name: 'fieldMetadataId', - label: 'Field Metadata Id', - description: 'View Filter target field', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-8b37-46ae-86b8-14287ec06802', - type: 'TEXT', - name: 'value', - label: 'Value', - description: 'View Filter value', - icon: null, - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-353c-4fb0-9011-1ad8e1dd67f9', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.355Z', - updatedAt: '2023-11-30T11:13:15.355Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - ], - }, - { - __typename: 'object', - id: '20202020-439a-4a41-83a3-3cda03d01d38', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activityTarget', - namePlural: 'activityTargets', - labelSingular: 'Activity Target', - labelPlural: 'Activity Targets', - description: 'An activity target', - icon: 'IconCheckbox', - isCustom: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [ - { - __typename: 'field', - id: '20202020-4cf0-4478-8c68-62a855622a99', - type: 'DATE_TIME', - name: 'updatedAt', - label: 'Update date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-585f-48fa-a4b6-97cf7f86315e', - type: 'DATE_TIME', - name: 'createdAt', - label: 'Creation date', - description: null, - icon: 'IconCalendar', - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-9408-4cc0-9fe1-51467edb530b', - type: 'RELATION', - name: 'company', - label: 'Company', - description: 'ActivityTarget company', - icon: 'IconBuildingSkyscraper', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '311bf27d-3710-4776-8b8d-b4cfba8c0ae8', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-480c-434e-b4c7-e22408b97047', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'company', - namePlural: 'companies', - }, - fromFieldMetadataId: '20202020-4a2e-4b41-8562-279963e8947e', - }, - }, - { - __typename: 'field', - id: '20202020-4c5d-4b5e-8d6e-3b2a4d5f6a7b', - type: 'UUID', - name: 'personId', - label: 'Person id (foreign key)', - description: 'ActivityTarget person id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-2b1a-4c6a-9c0a-1b9f5b7c9b1a', - type: 'UUID', - name: 'activityId', - label: 'Activity id (foreign key)', - description: 'ActivityTarget activity id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-9408-4cc0-9fe1-51467edb530c', - type: 'UUID', - name: 'companyId', - label: 'Company id (foreign key)', - description: 'ActivityTarget company id foreign key', - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: true, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-7db7-4dac-8093-ea0a12e9466f', - type: 'UUID', - name: 'id', - label: 'Id', - description: null, - icon: null, - isCustom: false, - isActive: true, - isSystem: true, - isNullable: false, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: null, - }, - { - __typename: 'field', - id: '20202020-cb21-42c9-bba8-347f7cb02b84', - type: 'RELATION', - name: 'activity', - label: 'Activity', - description: 'ActivityTarget activity', - icon: 'IconNotes', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '04eb67c8-3525-436f-b26b-c08acf48d12e', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-8ee3-4f67-84ab-1b7a6eb5a448', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'activity', - namePlural: 'activities', - }, - fromFieldMetadataId: '20202020-ec1d-4ffe-8bd2-a85c23ae0037', - }, - }, - { - __typename: 'field', - id: '20202020-e56c-43e6-8fce-5619d8c2293a', - type: 'RELATION', - name: 'person', - label: 'Person', - description: 'ActivityTarget person', - icon: 'IconUser', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: true, - createdAt: '2023-11-30T11:13:15.231Z', - updatedAt: '2023-11-30T11:13:15.231Z', - fromRelationMetadata: null, - toRelationMetadata: { - __typename: 'relation', - id: '1c515eae-14e8-4042-9af4-50ee725b6de5', - relationType: 'ONE_TO_MANY', - fromObjectMetadata: { - __typename: 'object', - id: '20202020-c64b-44bc-bd2c-502c99f49dca', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'person', - namePlural: 'people', - }, - fromFieldMetadataId: '20202020-f285-4115-a46c-116522986b29', - }, - }, - ], - }, - { - __typename: 'object', - id: '20202020-049d-4d0c-9e7c-e74fee3f88b2', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'messageThread', - namePlural: 'messageThreads', - labelSingular: 'Message Thread', - labelPlural: 'Message Threads', - description: 'A webhook', - icon: 'IconMessage', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [], - }, - { - __typename: 'object', - id: '20202020-6736-4337-b5c4-8b39fae325a5', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'timelineActivity', - namePlural: 'timelineActivities', - labelSingular: 'Timeline Activitiy', - labelPlural: 'Timeline Activities', - description: 'A webhook', - icon: 'IconIconTimelineEvent', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [], - }, - { - __typename: 'object', - id: '20202020-3f6b-4425-80ab-e468899ab4b2', - dataSourceId: '20202020-7f63-47a9-b1b3-6c7290ca9fb1', - nameSingular: 'message', - namePlural: 'messages', - labelSingular: 'Message', - labelPlural: 'Messages', - description: 'A message', - icon: 'IconMessage', - isCustom: false, - isRemote: false, - isActive: true, - isSystem: true, - createdAt: '2023-11-30T11:13:15.206Z', - updatedAt: '2023-11-30T11:13:15.206Z', - fields: [], - }, - ]; - - // Todo fix typing here (the backend is not in sync with the frontend) - return mockArray as ObjectMetadataItem[]; + const mockArray = [ + { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "labelSingular": "Workspace Member", + "labelPlural": "Workspace Members", + "description": "A workspace member", + "icon": "IconUserCircle", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "6ee54bad-526d-41a9-89f1-a2e7891a9a3e", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "191bd5e9-d118-4982-b118-28e72020b24f", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "437235b8-29cd-4f66-928f-576399e4ef5c", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a5041a8c-4c22-4a16-bbed-923acbdfdfec", + "type": "TEXT", + "name": "userEmail", + "label": "User Email", + "description": "Related user email address", + "icon": "IconMail", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9b1f6625-c23d-4c0c-a647-37d130cb3582", + "type": "TEXT", + "name": "colorScheme", + "label": "Color Scheme", + "description": "Preferred color scheme", + "icon": "IconColorSwatch", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'Light'", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0d3f0eb2-c112-497d-b68f-aceab6c81eb6", + "type": "RELATION", + "name": "assignedTasks", + "label": "Assigned tasks", + "description": "Tasks assigned to the workspace member", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "6d8f43e5-07f4-4f8c-bbfe-5b25b8a36442", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "task", + "namePlural": "tasks", + "isSystem": false, + "isRemote": false + }, + "toFieldMetadataId": "31988450-eef5-4668-9def-626c889c6485" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6d8f43e5-07f4-4f8c-bbfe-5b25b8a36442", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "0d3f0eb2-c112-497d-b68f-aceab6c81eb6", + "name": "assignedTasks" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "31988450-eef5-4668-9def-626c889c6485", + "name": "assignee" + } + } + }, + { + "__typename": "field", + "id": "d3af1c02-3c4b-40f3-acdc-6e8f1749637f", + "type": "TEXT", + "name": "timeZone", + "label": "Time zone", + "description": "User time zone", + "icon": "IconTimezone", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'system'", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e5e3fb6d-b04c-43be-b3d0-dad2aabaf6fb", + "type": "RELATION", + "name": "authoredAttachments", + "label": "Authored attachments", + "description": "Attachments created by the workspace member", + "icon": "IconFileImport", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "a5a4f416-659d-42e0-b10d-34e3f8b5b170", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "de7e9513-657a-4f0a-a1d5-3d5357520696" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "a5a4f416-659d-42e0-b10d-34e3f8b5b170", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "e5e3fb6d-b04c-43be-b3d0-dad2aabaf6fb", + "name": "authoredAttachments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "de7e9513-657a-4f0a-a1d5-3d5357520696", + "name": "author" + } + } + }, + { + "__typename": "field", + "id": "630a1217-4a9c-471e-aae0-565b9868e7a5", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "622fcdaa-c673-43a5-805b-6509a4cef638", + "type": "RELATION", + "name": "authoredComments", + "label": "Authored comments", + "description": "Authored comments", + "icon": "IconComment", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "d1a28400-34f8-4b0c-9924-22f2683fc106", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "6a0f0bac-17de-4e89-85f6-2affb52707b8", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "comment", + "namePlural": "comments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "4317a97d-5245-4364-a5a4-3cce09610598" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d1a28400-34f8-4b0c-9924-22f2683fc106", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "622fcdaa-c673-43a5-805b-6509a4cef638", + "name": "authoredComments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "6a0f0bac-17de-4e89-85f6-2affb52707b8", + "nameSingular": "comment", + "namePlural": "comments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "4317a97d-5245-4364-a5a4-3cce09610598", + "name": "author" + } + } + }, + { + "__typename": "field", + "id": "1b04ecbc-b41d-49f9-bf1f-32d7b4e8cf02", + "type": "SELECT", + "name": "dateFormat", + "label": "Date format", + "description": "User's preferred date format", + "icon": "IconCalendarEvent", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'SYSTEM'", + "options": [ + { + "id": "5d8af010-803b-4035-bb8f-0a0774ab6a5b", + "color": "turquoise", + "label": "System", + "value": "SYSTEM", + "position": 0 + }, + { + "id": "74103b0a-e1a2-48f6-abd2-fd815734935b", + "color": "red", + "label": "Month First", + "value": "MONTH_FIRST", + "position": 1 + }, + { + "id": "059b8026-8a3f-492c-9645-f5d5d0fce5c8", + "color": "purple", + "label": "Day First", + "value": "DAY_FIRST", + "position": 2 + }, + { + "id": "4d3219d5-8ef3-45a7-a385-622d094c91de", + "color": "sky", + "label": "Year First", + "value": "YEAR_FIRST", + "position": 3 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6ee54bad-526d-41a9-89f1-a2e7891a9a3e", + "type": "FULL_NAME", + "name": "name", + "label": "Name", + "description": "Workspace member name", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "lastName": "''", + "firstName": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "03a320f7-8e16-4022-a775-7eba320fd390", + "type": "RELATION", + "name": "assignedActivities", + "label": "Assigned activities", + "description": "Activities assigned to the workspace member", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "4f98e753-db02-48e6-927e-05bbf397cc5b", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activity", + "namePlural": "activities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "1e468dd4-1d02-4410-8fdb-9af627b70081" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "4f98e753-db02-48e6-927e-05bbf397cc5b", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "03a320f7-8e16-4022-a775-7eba320fd390", + "name": "assignedActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "1e468dd4-1d02-4410-8fdb-9af627b70081", + "name": "assignee" + } + } + }, + { + "__typename": "field", + "id": "cafc1fef-9ebd-43e7-8cb5-26a66a3248b5", + "type": "UUID", + "name": "userId", + "label": "User Id", + "description": "Associated User Id", + "icon": "IconCircleUsers", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "22de0aa3-0b2a-4189-9726-0f5029166ade", + "type": "SELECT", + "name": "timeFormat", + "label": "Time format", + "description": "User's preferred time format", + "icon": "IconClock2", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'SYSTEM'", + "options": [ + { + "id": "7c9b6ae3-2d76-497b-82fb-a06a85631b26", + "color": "sky", + "label": "System", + "value": "SYSTEM", + "position": 0 + }, + { + "id": "edaf897d-b6ee-4421-aedf-063b3e2dbb9e", + "color": "red", + "label": "24HRS", + "value": "HOUR_24", + "position": 1 + }, + { + "id": "a6dfb28c-8068-444e-a13b-8cbad5d46a11", + "color": "purple", + "label": "12HRS", + "value": "HOUR_12", + "position": 2 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0c66c2ce-6037-4306-8e82-dbb50f53516f", + "type": "RELATION", + "name": "favorites", + "label": "Favorites", + "description": "Favorites linked to the workspace member", + "icon": "IconHeart", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "ecdb31ed-50d7-4b0a-bbdc-d9929e76ae10", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "favorite", + "namePlural": "favorites", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "1ff0961a-3f5e-4060-9000-8ff853c527d2" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "ecdb31ed-50d7-4b0a-bbdc-d9929e76ae10", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "0c66c2ce-6037-4306-8e82-dbb50f53516f", + "name": "favorites" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "1ff0961a-3f5e-4060-9000-8ff853c527d2", + "name": "workspaceMember" + } + } + }, + { + "__typename": "field", + "id": "1eacd841-ab52-4f4a-98d8-67306a756046", + "type": "RELATION", + "name": "messageParticipants", + "label": "Message Participants", + "description": "Message Participants", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "065fd1c6-b214-482d-b409-68d0c3e65453", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "b62df27d-9cff-4675-b314-4cc498f3a7a5" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "065fd1c6-b214-482d-b409-68d0c3e65453", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "1eacd841-ab52-4f4a-98d8-67306a756046", + "name": "messageParticipants" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "b62df27d-9cff-4675-b314-4cc498f3a7a5", + "name": "workspaceMember" + } + } + }, + { + "__typename": "field", + "id": "f3bf80ff-ffd8-452f-a1b9-e0deccec3598", + "type": "TEXT", + "name": "locale", + "label": "Language", + "description": "Preferred language", + "icon": "IconLanguage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'en'", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "2c0eee09-af7a-429e-a97e-c562ae174fba", + "type": "RELATION", + "name": "authoredActivities", + "label": "Authored activities", + "description": "Activities created by the workspace member", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "d216ba7e-befb-48d9-b484-1a5b25298ec4", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activity", + "namePlural": "activities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "fafe1848-c261-45cf-b857-ba4e519453ad" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d216ba7e-befb-48d9-b484-1a5b25298ec4", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "2c0eee09-af7a-429e-a97e-c562ae174fba", + "name": "authoredActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "fafe1848-c261-45cf-b857-ba4e519453ad", + "name": "author" + } + } + }, + { + "__typename": "field", + "id": "1378a582-7a0b-4ee3-a11a-0cb19897e504", + "type": "TEXT", + "name": "avatarUrl", + "label": "Avatar Url", + "description": "Workspace member avatar", + "icon": "IconFileUpload", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "36029525-7e87-426f-b809-2b44b2a0e707", + "type": "RELATION", + "name": "calendarEventParticipants", + "label": "Calendar Event Participants", + "description": "Calendar Event Participants", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "41502f94-3354-4a6f-95a3-0029ecc1f765", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "3e2d6542-c27a-46dd-8093-6ef5ab6e58c0" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "41502f94-3354-4a6f-95a3-0029ecc1f765", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "36029525-7e87-426f-b809-2b44b2a0e707", + "name": "calendarEventParticipants" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "3e2d6542-c27a-46dd-8093-6ef5ab6e58c0", + "name": "workspaceMember" + } + } + }, + { + "__typename": "field", + "id": "cbfe556c-acc4-47d0-a506-9b1aabdf509a", + "type": "RELATION", + "name": "timelineActivities", + "label": "Events", + "description": "Events linked to the workspace member", + "icon": "IconTimelineEvent", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "24b2942b-88b5-4191-a55f-1c24bb19b3f8", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "6d737cbd-f56f-4efb-9a85-085f83486e13" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "24b2942b-88b5-4191-a55f-1c24bb19b3f8", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "cbfe556c-acc4-47d0-a506-9b1aabdf509a", + "name": "timelineActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "6d737cbd-f56f-4efb-9a85-085f83486e13", + "name": "workspaceMember" + } + } + }, + { + "__typename": "field", + "id": "9b9c9ab0-bc48-45d5-a800-028a13651aa8", + "type": "RELATION", + "name": "accountOwnerForCompanies", + "label": "Account Owner For Companies", + "description": "Account owner for companies", + "icon": "IconBriefcase", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "91f808d4-cddb-4621-bf89-c27c713f6a62", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "toFieldMetadataId": "f261e7bf-9700-4915-8881-9e3b2f2a81f5" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "91f808d4-cddb-4621-bf89-c27c713f6a62", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "9b9c9ab0-bc48-45d5-a800-028a13651aa8", + "name": "accountOwnerForCompanies" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "f261e7bf-9700-4915-8881-9e3b2f2a81f5", + "name": "accountOwner" + } + } + }, + { + "__typename": "field", + "id": "bd7607b2-e92f-4179-ab1b-af4013e6a6f1", + "type": "RELATION", + "name": "connectedAccounts", + "label": "Connected accounts", + "description": "Connected accounts", + "icon": "IconAt", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "08199572-bc4c-4516-9fc3-354e118b1e38", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "4b1a8d45-8338-4f36-8495-bd230335ddf9" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "08199572-bc4c-4516-9fc3-354e118b1e38", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "bd7607b2-e92f-4179-ab1b-af4013e6a6f1", + "name": "connectedAccounts" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "4b1a8d45-8338-4f36-8495-bd230335ddf9", + "name": "accountOwner" + } + } + }, + { + "__typename": "field", + "id": "d099d12e-79bd-4787-a5d6-fdef989237be", + "type": "RELATION", + "name": "blocklist", + "label": "Blocklist", + "description": "Blocklisted handles", + "icon": "IconForbid2", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "efb75db1-7707-4a21-a97b-8e9490ab4378", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "4ddc69a0-8643-41a8-bba6-aa561723d3af", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "blocklist", + "namePlural": "blocklists", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "e3759ebe-8877-4991-b62e-a497e18cbd62" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "efb75db1-7707-4a21-a97b-8e9490ab4378", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "d099d12e-79bd-4787-a5d6-fdef989237be", + "name": "blocklist" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "4ddc69a0-8643-41a8-bba6-aa561723d3af", + "nameSingular": "blocklist", + "namePlural": "blocklists" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "e3759ebe-8877-4991-b62e-a497e18cbd62", + "name": "workspaceMember" + } + } + }, + { + "__typename": "field", + "id": "375850ab-423a-456d-8474-cbc3ec41cce9", + "type": "RELATION", + "name": "auditLogs", + "label": "Audit Logs", + "description": "Audit Logs linked to the workspace member", + "icon": "IconTimelineEvent", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "567b7eea-73fc-4b29-899c-0be663704d4a", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "4b55fcfc-2caf-4c79-a814-0103a0456896", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "auditLog", + "namePlural": "auditLogs", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "16eb4366-d53d-4ff7-a6de-8ba29bf6ea00" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "567b7eea-73fc-4b29-899c-0be663704d4a", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "375850ab-423a-456d-8474-cbc3ec41cce9", + "name": "auditLogs" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "4b55fcfc-2caf-4c79-a814-0103a0456896", + "nameSingular": "auditLog", + "namePlural": "auditLogs" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "16eb4366-d53d-4ff7-a6de-8ba29bf6ea00", + "name": "workspaceMember" + } + } + } + ] + }, + { + "__typename": "object", + "id": "f0f91da6-93c0-4dbf-993f-5ecadde0ec82", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarChannel", + "namePlural": "calendarChannels", + "labelSingular": "Calendar Channel", + "labelPlural": "Calendar Channels", + "description": "Calendar Channels", + "icon": "IconCalendar", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "4f5a3377-f4b0-4dde-8e4d-52b13ae688ce", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "f0884f1a-b4bc-4d37-812e-1ffe1611b4e7", + "type": "UUID", + "name": "connectedAccountId", + "label": "Connected Account id (foreign key)", + "description": "Connected Account id foreign key", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "fab75252-38ec-4331-80c7-75245ab71950", + "type": "TEXT", + "name": "syncCursor", + "label": "Sync Cursor", + "description": "Sync Cursor. Used for syncing events from the calendar provider", + "icon": "IconReload", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "76291abb-9de0-4f6e-8ea8-84d3085fd811", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e4cad90a-5f83-4591-a371-6f65a74531b5", + "type": "RELATION", + "name": "connectedAccount", + "label": "Connected Account", + "description": "Connected Account", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "6f69497c-d0e7-47f7-b271-12904c0f6b59", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "fc97ddc4-f4ff-4e54-84e6-7ccc4bd8772e" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6f69497c-d0e7-47f7-b271-12904c0f6b59", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "f0f91da6-93c0-4dbf-993f-5ecadde0ec82", + "nameSingular": "calendarChannel", + "namePlural": "calendarChannels" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "e4cad90a-5f83-4591-a371-6f65a74531b5", + "name": "connectedAccount" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "fc97ddc4-f4ff-4e54-84e6-7ccc4bd8772e", + "name": "calendarChannels" + } + } + }, + { + "__typename": "field", + "id": "4941e4d8-bfa4-420b-acee-9eef9e5432dd", + "type": "SELECT", + "name": "contactAutoCreationPolicy", + "label": "Contact auto creation policy", + "description": "Automatically create records for people you participated with in an event.", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'AS_PARTICIPANT_AND_ORGANIZER'", + "options": [ + { + "id": "6bb7011a-6057-4f17-be5f-9598b7dc9cc1", + "color": "green", + "label": "As Participant and Organizer", + "value": "AS_PARTICIPANT_AND_ORGANIZER", + "position": 0 + }, + { + "id": "0b024c52-d79f-4eeb-ad0f-f0a215f870ee", + "color": "orange", + "label": "As Participant", + "value": "AS_PARTICIPANT", + "position": 1 + }, + { + "id": "58e4961c-2286-4c95-8ebe-4f6f51f15590", + "color": "blue", + "label": "As Organizer", + "value": "AS_ORGANIZER", + "position": 2 + }, + { + "id": "45b245c3-ff32-4b91-b676-a84210814878", + "color": "red", + "label": "None", + "value": "NONE", + "position": 3 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "f43faac4-7e54-4f79-8ba1-8647ba44b99f", + "type": "BOOLEAN", + "name": "isSyncEnabled", + "label": "Is Sync Enabled", + "description": "Is Sync Enabled", + "icon": "IconRefresh", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": true, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "f3152264-99ad-4c5f-b506-ede7db938278", + "type": "NUMBER", + "name": "throttleFailureCount", + "label": "Throttle Failure Count", + "description": "Throttle Failure Count", + "icon": "IconX", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": 0, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "d12c96ce-b888-4c9b-833f-ee66a5c9a893", + "type": "BOOLEAN", + "name": "isContactAutoCreationEnabled", + "label": "Is Contact Auto Creation Enabled", + "description": "Is Contact Auto Creation Enabled", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": true, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4f5a3377-f4b0-4dde-8e4d-52b13ae688ce", + "type": "TEXT", + "name": "handle", + "label": "Handle", + "description": "Handle", + "icon": "IconAt", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "bbd0996e-1798-47c9-9568-4cdd3efa6698", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8afb0237-ed43-4926-93ef-218c045714f0", + "type": "SELECT", + "name": "syncStatus", + "label": "Sync status", + "description": "Sync status", + "icon": "IconStatusChange", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": [ + { + "id": "0d54a181-9738-4ffc-8e50-2e46bed3febc", + "color": "yellow", + "label": "Ongoing", + "value": "ONGOING", + "position": 1 + }, + { + "id": "b3c0fee7-71ee-4c81-909f-aa814e977543", + "color": "blue", + "label": "Not Synced", + "value": "NOT_SYNCED", + "position": 2 + }, + { + "id": "877ac592-a088-4dce-a7cf-066ff4b4b33d", + "color": "green", + "label": "Active", + "value": "ACTIVE", + "position": 3 + }, + { + "id": "e35d48ce-4e4a-4267-a2e4-997d51cff5ca", + "color": "red", + "label": "Failed Insufficient Permissions", + "value": "FAILED_INSUFFICIENT_PERMISSIONS", + "position": 4 + }, + { + "id": "77dfa556-0a19-40c1-a552-0e02d5fbaa5b", + "color": "red", + "label": "Failed Unknown", + "value": "FAILED_UNKNOWN", + "position": 5 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "44bb04a5-7bc7-40b3-b82c-3b092dfff51c", + "type": "SELECT", + "name": "syncStage", + "label": "Sync stage", + "description": "Sync stage", + "icon": "IconStatusChange", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'FULL_CALENDAR_EVENT_LIST_FETCH_PENDING'", + "options": [ + { + "id": "35bc27cb-f4e7-42bb-99a0-94fac98de7ad", + "color": "blue", + "label": "Full calendar event list fetch pending", + "value": "FULL_CALENDAR_EVENT_LIST_FETCH_PENDING", + "position": 0 + }, + { + "id": "01fe1a82-ccc3-45f4-95d4-d16035c80e36", + "color": "blue", + "label": "Partial calendar event list fetch pending", + "value": "PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING", + "position": 1 + }, + { + "id": "e108a78e-09bf-4941-8549-3378794d8983", + "color": "orange", + "label": "Calendar event list fetch ongoing", + "value": "CALENDAR_EVENT_LIST_FETCH_ONGOING", + "position": 2 + }, + { + "id": "cb20dca0-2bf5-44c7-84ca-cf2fe15ff3ad", + "color": "blue", + "label": "Calendar events import pending", + "value": "CALENDAR_EVENTS_IMPORT_PENDING", + "position": 3 + }, + { + "id": "6242af28-ea3b-47c8-8863-add84003e047", + "color": "orange", + "label": "Calendar events import ongoing", + "value": "CALENDAR_EVENTS_IMPORT_ONGOING", + "position": 4 + }, + { + "id": "e4b33641-8f6f-4bfa-8edd-c5e1dd3c94b6", + "color": "red", + "label": "Failed", + "value": "FAILED", + "position": 5 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9870a357-92f1-4476-b156-2d85cc31a520", + "type": "DATE_TIME", + "name": "syncStageStartedAt", + "label": "Sync stage started at", + "description": "Sync stage started at", + "icon": "IconHistory", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "21aa10ec-b7f2-4380-a344-2f74c24f6aaf", + "type": "SELECT", + "name": "visibility", + "label": "Visibility", + "description": "Visibility", + "icon": "IconEyeglass", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'SHARE_EVERYTHING'", + "options": [ + { + "id": "565bf2b2-85c3-4fd7-9f48-ada4d069b390", + "color": "green", + "label": "Metadata", + "value": "METADATA", + "position": 0 + }, + { + "id": "b94ce9bd-1700-4f70-9892-10313749a06b", + "color": "orange", + "label": "Share Everything", + "value": "SHARE_EVERYTHING", + "position": 1 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cce21aeb-36eb-4563-92ea-a66f09244ec2", + "type": "RELATION", + "name": "calendarChannelEventAssociations", + "label": "Calendar Channel Event Associations", + "description": "Calendar Channel Event Associations", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "85465a13-1cd4-4048-9e57-6fa9cba0328e", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "c59e5489-0712-48d7-9fb1-1a9220523d0a", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarChannelEventAssociation", + "namePlural": "calendarChannelEventAssociations", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "0950a79b-39b4-449f-9108-f980c52a038c" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "85465a13-1cd4-4048-9e57-6fa9cba0328e", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "f0f91da6-93c0-4dbf-993f-5ecadde0ec82", + "nameSingular": "calendarChannel", + "namePlural": "calendarChannels" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "cce21aeb-36eb-4563-92ea-a66f09244ec2", + "name": "calendarChannelEventAssociations" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "c59e5489-0712-48d7-9fb1-1a9220523d0a", + "nameSingular": "calendarChannelEventAssociation", + "namePlural": "calendarChannelEventAssociations" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "0950a79b-39b4-449f-9108-f980c52a038c", + "name": "calendarChannel" + } + } + }, + { + "__typename": "field", + "id": "725fae1d-0be5-48bb-a0d6-6ba28055b0be", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "labelSingular": "Company", + "labelPlural": "Companies", + "description": "A company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "39403bee-314b-4f14-bc91-70d500397517", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "b47684bd-40d6-4210-b450-553f3b488d1b", + "type": "BOOLEAN", + "name": "idealCustomerProfile", + "label": "ICP", + "description": "Ideal Customer Profile: Indicates whether the company is the most suitable and valuable customer for you", + "icon": "IconTarget", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": false, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6051c09b-973f-40be-94c6-53598d7c9d5b", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9c158d10-30ad-42a9-9303-d7284f91a02b", + "type": "LINKS", + "name": "xLink", + "label": "X", + "description": "The company Twitter/X account", + "icon": "IconBrandX", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "primaryLinkUrl": "''", + "secondaryLinks": null, + "primaryLinkLabel": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1a1285b4-8e39-4748-9405-02335e9ab3be", + "type": "RELATION", + "name": "activityTargets", + "label": "Activities", + "description": "Activities tied to the company", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "d5afdcb3-debf-42f8-b360-0a4e6ab63a36", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activityTarget", + "namePlural": "activityTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "7ff327f2-24c2-4cd7-b723-5463147226fd" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d5afdcb3-debf-42f8-b360-0a4e6ab63a36", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "1a1285b4-8e39-4748-9405-02335e9ab3be", + "name": "activityTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "7ff327f2-24c2-4cd7-b723-5463147226fd", + "name": "company" + } + } + }, + { + "__typename": "field", + "id": "64a7efdd-8456-43ba-83b5-541d8c0d9a34", + "type": "RELATION", + "name": "people", + "label": "People", + "description": "People linked to the company.", + "icon": "IconUsers", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "62c395a8-de62-4433-ab42-e56d2c877f2d", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "toFieldMetadataId": "4c6aa448-8f01-4039-b085-20951e2847d3" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "62c395a8-de62-4433-ab42-e56d2c877f2d", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "64a7efdd-8456-43ba-83b5-541d8c0d9a34", + "name": "people" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "4c6aa448-8f01-4039-b085-20951e2847d3", + "name": "company" + } + } + }, + { + "__typename": "field", + "id": "33f11889-6139-477d-9b41-a062cd36aa52", + "type": "CURRENCY", + "name": "annualRecurringRevenue", + "label": "ARR", + "description": "Annual Recurring Revenue: The actual or estimated annual revenue of the company", + "icon": "IconMoneybag", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "amountMicros": null, + "currencyCode": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "d0bdf640-3fcb-46b5-8761-3ebdb016f3b4", + "type": "RELATION", + "name": "timelineActivities", + "label": "Timeline Activities", + "description": "Timeline Activities linked to the company", + "icon": "IconIconTimelineEvent", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "ca5cbff9-b55a-4972-a6e1-eca6e3b43da7", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "521201aa-0596-4c0e-a0da-da7d5551591f" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "ca5cbff9-b55a-4972-a6e1-eca6e3b43da7", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "d0bdf640-3fcb-46b5-8761-3ebdb016f3b4", + "name": "timelineActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "521201aa-0596-4c0e-a0da-da7d5551591f", + "name": "company" + } + } + }, + { + "__typename": "field", + "id": "c75ba8e9-8371-499c-a6c0-366e85230cd9", + "type": "ADDRESS", + "name": "address", + "label": "Address", + "description": "Address of the company", + "icon": "IconMap", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "addressLat": null, + "addressLng": null, + "addressCity": "''", + "addressState": "''", + "addressCountry": "''", + "addressStreet1": "''", + "addressStreet2": "''", + "addressPostcode": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "54e7231c-86a2-4453-abaa-13448ea23629", + "type": "RELATION", + "name": "noteTargets", + "label": "Notes", + "description": "Notes tied to the company", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "6819eb45-5c67-484f-ba4d-c35fe72cb256", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "noteTarget", + "namePlural": "noteTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "03bd3366-2dec-4169-b502-893c591b6794" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6819eb45-5c67-484f-ba4d-c35fe72cb256", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "54e7231c-86a2-4453-abaa-13448ea23629", + "name": "noteTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "03bd3366-2dec-4169-b502-893c591b6794", + "name": "company" + } + } + }, + { + "__typename": "field", + "id": "64568426-52c2-42c9-9e5b-cb8259048b39", + "type": "NUMBER", + "name": "employees", + "label": "Employees", + "description": "Number of employees in the company", + "icon": "IconUsers", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "aff246a7-7e60-49d9-aaf3-4b2dad05c862", + "type": "RELATION", + "name": "attachments", + "label": "Attachments", + "description": "Attachments linked to the company", + "icon": "IconFileImport", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "b97472b9-8873-4b5c-a400-82a6075c8a98", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "92198599-f3ba-4f21-9e9b-e71766ba8289" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "b97472b9-8873-4b5c-a400-82a6075c8a98", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "aff246a7-7e60-49d9-aaf3-4b2dad05c862", + "name": "attachments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "92198599-f3ba-4f21-9e9b-e71766ba8289", + "name": "company" + } + } + }, + { + "__typename": "field", + "id": "d29556d3-966d-46e5-9c60-246d124ea2d7", + "type": "POSITION", + "name": "position", + "label": "Position", + "description": "Company record position", + "icon": "IconHierarchy2", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "39403bee-314b-4f14-bc91-70d500397517", + "type": "TEXT", + "name": "name", + "label": "Name", + "description": "The company name", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "f261e7bf-9700-4915-8881-9e3b2f2a81f5", + "type": "RELATION", + "name": "accountOwner", + "label": "Account Owner", + "description": "Your team member responsible for managing the company account", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "91f808d4-cddb-4621-bf89-c27c713f6a62", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "9b9c9ab0-bc48-45d5-a800-028a13651aa8" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "91f808d4-cddb-4621-bf89-c27c713f6a62", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "f261e7bf-9700-4915-8881-9e3b2f2a81f5", + "name": "accountOwner" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "9b9c9ab0-bc48-45d5-a800-028a13651aa8", + "name": "accountOwnerForCompanies" + } + } + }, + { + "__typename": "field", + "id": "21596676-4dd1-4159-9ec5-d5bfab2e5d45", + "type": "RELATION", + "name": "opportunities", + "label": "Opportunities", + "description": "Opportunities linked to the company.", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "aa62c2e3-48d4-4e2f-b08d-ebe66ece3c3b", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "toFieldMetadataId": "31bbc743-3b92-40bf-b2cd-e94e6dee9160" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "aa62c2e3-48d4-4e2f-b08d-ebe66ece3c3b", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "21596676-4dd1-4159-9ec5-d5bfab2e5d45", + "name": "opportunities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "31bbc743-3b92-40bf-b2cd-e94e6dee9160", + "name": "company" + } + } + }, + { + "__typename": "field", + "id": "e2fd6936-c1e7-4e51-b052-b7b2b45c4f76", + "type": "LINKS", + "name": "linkedinLink", + "label": "Linkedin", + "description": "The company Linkedin account", + "icon": "IconBrandLinkedin", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "primaryLinkUrl": "''", + "secondaryLinks": null, + "primaryLinkLabel": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "19056164-79e9-4fdf-86e3-c8a707bbecca", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "06fc5ce9-6dfa-46b8-8cbe-1f7852cb70f5", + "type": "UUID", + "name": "accountOwnerId", + "label": "Account Owner id (foreign key)", + "description": "Your team member responsible for managing the company account id foreign key", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "06a124d7-212b-4928-970a-ce02227f0df3", + "type": "LINKS", + "name": "domainName", + "label": "Domain Name", + "description": "The company website URL. We use this url to fetch the company icon", + "icon": "IconLink", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "primaryLinkUrl": "''", + "secondaryLinks": null, + "primaryLinkLabel": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6aadfd7b-33b8-4481-baf7-3b63c055716d", + "type": "RELATION", + "name": "taskTargets", + "label": "Tasks", + "description": "Tasks tied to the company", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "ac4e31f0-3daa-4fe8-b1ff-6d1abc0d684e", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "taskTarget", + "namePlural": "taskTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "bb743bd2-1452-4053-94fb-2bb8b7c7fccd" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "ac4e31f0-3daa-4fe8-b1ff-6d1abc0d684e", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "6aadfd7b-33b8-4481-baf7-3b63c055716d", + "name": "taskTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "bb743bd2-1452-4053-94fb-2bb8b7c7fccd", + "name": "company" + } + } + }, + { + "__typename": "field", + "id": "b6f1c28f-cc57-4b71-8e74-fb1a25944b36", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8fc67f91-0bea-4a96-889f-80c9a0d464f1", + "type": "RELATION", + "name": "favorites", + "label": "Favorites", + "description": "Favorites linked to the company", + "icon": "IconHeart", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "79195013-edb9-45da-b0ba-6f42a4671bb7", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "favorite", + "namePlural": "favorites", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "c1c3e041-1f41-4da9-99ed-a579eaa3c871" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "79195013-edb9-45da-b0ba-6f42a4671bb7", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "8fc67f91-0bea-4a96-889f-80c9a0d464f1", + "name": "favorites" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "c1c3e041-1f41-4da9-99ed-a579eaa3c871", + "name": "company" + } + } + } + ] + }, + { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations", + "labelSingular": "Message Channel Message Association", + "labelPlural": "Message Channel Message Associations", + "description": "Message Synced with a Message Channel", + "icon": "IconMessage", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "0d0ea193-0847-4ba4-9e1e-e7fc5f94e969", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "dcbe8980-a80d-4145-b96e-3fdc3edf0cba", + "type": "UUID", + "name": "messageThreadId", + "label": "Message Thread Id id (foreign key)", + "description": "Message Thread Id id foreign key", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "39606dd5-d094-4749-aac8-a1a1ae9c8b92", + "type": "TEXT", + "name": "messageExternalId", + "label": "Message External Id", + "description": "Message id from the messaging provider", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cc892247-0c9b-450b-9bac-7cf4e86eb770", + "type": "RELATION", + "name": "messageThread", + "label": "Message Thread Id", + "description": "Message Thread Id", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "6470760e-b463-4566-b75b-9147f27905f5", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "565bef4e-4f25-45c0-a1c7-090a1f09d0cd", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageThread", + "namePlural": "messageThreads", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "59008d72-f1fd-4c74-b19d-d9430bc67528" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6470760e-b463-4566-b75b-9147f27905f5", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "cc892247-0c9b-450b-9bac-7cf4e86eb770", + "name": "messageThread" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "565bef4e-4f25-45c0-a1c7-090a1f09d0cd", + "nameSingular": "messageThread", + "namePlural": "messageThreads" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "59008d72-f1fd-4c74-b19d-d9430bc67528", + "name": "messageChannelMessageAssociations" + } + } + }, + { + "__typename": "field", + "id": "0d0ea193-0847-4ba4-9e1e-e7fc5f94e969", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "927eb9ef-c1a8-4453-8a8a-2273ebff07d9", + "type": "RELATION", + "name": "messageChannel", + "label": "Message Channel Id", + "description": "Message Channel Id", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "3033b53c-97c6-44af-9696-de653a17b513", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "10593c25-7116-4ee2-a448-60272e867704", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageChannel", + "namePlural": "messageChannels", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "375af514-e4c5-4fbd-b386-8f2f288999da" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "3033b53c-97c6-44af-9696-de653a17b513", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "927eb9ef-c1a8-4453-8a8a-2273ebff07d9", + "name": "messageChannel" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "10593c25-7116-4ee2-a448-60272e867704", + "nameSingular": "messageChannel", + "namePlural": "messageChannels" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "375af514-e4c5-4fbd-b386-8f2f288999da", + "name": "messageChannelMessageAssociations" + } + } + }, + { + "__typename": "field", + "id": "baca6fdd-07ef-469c-8b9d-364d2c22eb34", + "type": "RELATION", + "name": "message", + "label": "Message Id", + "description": "Message Id", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "d3122ddd-2967-4198-b1a2-2821b2cf62ee", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "message", + "namePlural": "messages", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "2f04de1f-1bd3-4115-b40b-993e9fdaa6e7" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d3122ddd-2967-4198-b1a2-2821b2cf62ee", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "baca6fdd-07ef-469c-8b9d-364d2c22eb34", + "name": "message" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "nameSingular": "message", + "namePlural": "messages" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "2f04de1f-1bd3-4115-b40b-993e9fdaa6e7", + "name": "messageChannelMessageAssociations" + } + } + }, + { + "__typename": "field", + "id": "11ea504d-f0b1-4fc6-a4e3-a8a38d8f79b4", + "type": "UUID", + "name": "messageId", + "label": "Message Id id (foreign key)", + "description": "Message Id id foreign key", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b77bdfc4-325f-45a4-8bad-64ae555b18dc", + "type": "TEXT", + "name": "messageThreadExternalId", + "label": "Thread External Id", + "description": "Thread id from the messaging provider", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0eb0cbbd-8f3b-4a1f-a1c9-783fb20bf798", + "type": "UUID", + "name": "messageChannelId", + "label": "Message Channel Id id (foreign key)", + "description": "Message Channel Id id foreign key", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a6799379-5728-47a7-b330-701dfd3960c1", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "619b1266-4315-44b6-9758-e2e56b704fee", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activity", + "namePlural": "activities", + "labelSingular": "Activity", + "labelPlural": "Activities", + "description": "An activity", + "icon": "IconCheckbox", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "d9d137bd-1c40-415a-99c1-467f4bf74e5e", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "b5dd8ddb-5a7b-496c-8d8a-d1cb25621784", + "type": "DATE_TIME", + "name": "reminderAt", + "label": "Reminder Date", + "description": "Activity reminder date", + "icon": "IconCalendarEvent", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "31ee098d-4830-4cb2-a5e2-e72949e29398", + "type": "TEXT", + "name": "body", + "label": "Body", + "description": "Activity body", + "icon": "IconList", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "946f6fa9-0237-4bb4-b550-3d00478361a3", + "type": "UUID", + "name": "authorId", + "label": "Author id (foreign key)", + "description": "Activity author id foreign key", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "2a1ef6db-713d-48c2-9190-288547eebc82", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "fe710da5-e394-464f-a30d-bad600469eeb", + "type": "UUID", + "name": "assigneeId", + "label": "Assignee id (foreign key)", + "description": "Activity assignee id foreign key", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9d7d47c9-1840-4de5-8c31-b719e1925e34", + "type": "DATE_TIME", + "name": "dueAt", + "label": "Due Date", + "description": "Activity due date", + "icon": "IconCalendarEvent", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1e468dd4-1d02-4410-8fdb-9af627b70081", + "type": "RELATION", + "name": "assignee", + "label": "Assignee", + "description": "Activity assignee", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "4f98e753-db02-48e6-927e-05bbf397cc5b", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "03a320f7-8e16-4022-a775-7eba320fd390" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "4f98e753-db02-48e6-927e-05bbf397cc5b", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "1e468dd4-1d02-4410-8fdb-9af627b70081", + "name": "assignee" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "03a320f7-8e16-4022-a775-7eba320fd390", + "name": "assignedActivities" + } + } + }, + { + "__typename": "field", + "id": "f6db6bfe-fbdf-4900-9b11-3d54ca1d9fef", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "fafe1848-c261-45cf-b857-ba4e519453ad", + "type": "RELATION", + "name": "author", + "label": "Author", + "description": "Activity author", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "d216ba7e-befb-48d9-b484-1a5b25298ec4", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "2c0eee09-af7a-429e-a97e-c562ae174fba" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d216ba7e-befb-48d9-b484-1a5b25298ec4", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "fafe1848-c261-45cf-b857-ba4e519453ad", + "name": "author" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "2c0eee09-af7a-429e-a97e-c562ae174fba", + "name": "authoredActivities" + } + } + }, + { + "__typename": "field", + "id": "d9d137bd-1c40-415a-99c1-467f4bf74e5e", + "type": "TEXT", + "name": "title", + "label": "Title", + "description": "Activity title", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "32cfb011-1dc8-48d6-a90d-92019d3dc140", + "type": "DATE_TIME", + "name": "completedAt", + "label": "Completion Date", + "description": "Activity completion date", + "icon": "IconCheck", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "85fdf3d5-72d4-4cab-80de-d226086d4f69", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6d9c5f2a-c590-441a-b1f6-946ec2f1976d", + "type": "TEXT", + "name": "type", + "label": "Type", + "description": "Activity type", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'Note'", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "dc07c3da-fa53-4a1c-8fb6-619673a1c928", + "type": "RELATION", + "name": "attachments", + "label": "Attachments", + "description": "Activity attachments", + "icon": "IconFileImport", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "b693b22a-26d0-4965-b796-515133751128", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "83f7ed8c-0132-43d8-80d5-829c4d02368f" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "b693b22a-26d0-4965-b796-515133751128", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "dc07c3da-fa53-4a1c-8fb6-619673a1c928", + "name": "attachments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "83f7ed8c-0132-43d8-80d5-829c4d02368f", + "name": "activity" + } + } + }, + { + "__typename": "field", + "id": "70146bf7-008a-457c-a3eb-c1febb307eac", + "type": "RELATION", + "name": "activityTargets", + "label": "Targets", + "description": "Activity targets", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "6a74e2a1-54a1-47d0-b56e-2f0a30e748ac", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activityTarget", + "namePlural": "activityTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "350b1f58-1a4e-4759-ac3d-2cff5fc0bf59" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6a74e2a1-54a1-47d0-b56e-2f0a30e748ac", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "70146bf7-008a-457c-a3eb-c1febb307eac", + "name": "activityTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "350b1f58-1a4e-4759-ac3d-2cff5fc0bf59", + "name": "activity" + } + } + }, + { + "__typename": "field", + "id": "c2ec3dfc-3dbb-4afc-bc3d-9b997d87f5c6", + "type": "RELATION", + "name": "comments", + "label": "Comments", + "description": "Activity comments", + "icon": "IconComment", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "809b3b44-0197-4f92-8db1-dfbc50758fed", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "6a0f0bac-17de-4e89-85f6-2affb52707b8", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "comment", + "namePlural": "comments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "bf18155c-f3d9-4619-a69e-142fb49220b0" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "809b3b44-0197-4f92-8db1-dfbc50758fed", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "c2ec3dfc-3dbb-4afc-bc3d-9b997d87f5c6", + "name": "comments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "6a0f0bac-17de-4e89-85f6-2affb52707b8", + "nameSingular": "comment", + "namePlural": "comments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "bf18155c-f3d9-4619-a69e-142fb49220b0", + "name": "activity" + } + } + } + ] + }, + { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "note", + "namePlural": "notes", + "labelSingular": "Note", + "labelPlural": "Notes", + "description": "A note", + "icon": "IconNotes", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "a9e2751e-edee-4a32-8c60-cfc46005ecba", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "2a485f0e-8538-4753-98bf-4419cb4f405c", + "type": "RELATION", + "name": "attachments", + "label": "Attachments", + "description": "Note attachments", + "icon": "IconFileImport", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "c69cedf9-6a42-4c2c-b7a4-d882cb3e8951", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "dd8e7902-d8a5-4644-a1eb-ac107c160467" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c69cedf9-6a42-4c2c-b7a4-d882cb3e8951", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "nameSingular": "note", + "namePlural": "notes" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "2a485f0e-8538-4753-98bf-4419cb4f405c", + "name": "attachments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "dd8e7902-d8a5-4644-a1eb-ac107c160467", + "name": "note" + } + } + }, + { + "__typename": "field", + "id": "82754ec0-393a-4bf0-ac9a-8cb48bb97ae4", + "type": "RICH_TEXT", + "name": "body", + "label": "Body", + "description": "Note body", + "icon": "IconFilePencil", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "42f1d0ca-ed5a-487c-b29a-ec43dbeff2cd", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "efc4d769-6cc7-46c8-b188-48c3de641bd9", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6b08967c-2aa2-4bd0-a570-3f89cea19bed", + "type": "RELATION", + "name": "timelineActivities", + "label": "Timeline Activities", + "description": "Timeline Activities linked to the note.", + "icon": "IconTimelineEvent", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "c88cd230-983b-418c-8b06-ca8334bce78d", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "923d8ce7-f0d9-4f77-ae0d-aa59d67ec4d5" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c88cd230-983b-418c-8b06-ca8334bce78d", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "nameSingular": "note", + "namePlural": "notes" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "6b08967c-2aa2-4bd0-a570-3f89cea19bed", + "name": "timelineActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "923d8ce7-f0d9-4f77-ae0d-aa59d67ec4d5", + "name": "note" + } + } + }, + { + "__typename": "field", + "id": "0c38129b-28e2-4869-b912-c7f867b2998c", + "type": "POSITION", + "name": "position", + "label": "Position", + "description": "Note record position", + "icon": "IconHierarchy2", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a9e2751e-edee-4a32-8c60-cfc46005ecba", + "type": "TEXT", + "name": "title", + "label": "Title", + "description": "Note title", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cd95c7e6-9bb8-49d2-80c6-0429e1e4d839", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b8d27dfc-7028-4c5d-baab-0d961899922b", + "type": "RELATION", + "name": "noteTargets", + "label": "Targets", + "description": "Note targets", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "4849ded7-c0d5-4e32-8e11-fdf57f7d224b", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "noteTarget", + "namePlural": "noteTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "53cbaa8c-aeef-4f36-96c0-28a674086f7e" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "4849ded7-c0d5-4e32-8e11-fdf57f7d224b", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "nameSingular": "note", + "namePlural": "notes" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "b8d27dfc-7028-4c5d-baab-0d961899922b", + "name": "noteTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "53cbaa8c-aeef-4f36-96c0-28a674086f7e", + "name": "note" + } + } + } + ] + }, + { + "__typename": "object", + "id": "d83798f4-7caf-4369-9fb7-c589acc729fa", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "apiKey", + "namePlural": "apiKeys", + "labelSingular": "Api Key", + "labelPlural": "Api Keys", + "description": "An api key", + "icon": "IconRobot", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "23a0e28c-0070-4058-bb72-287f80cbbcb1", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "23a0e28c-0070-4058-bb72-287f80cbbcb1", + "type": "TEXT", + "name": "name", + "label": "Name", + "description": "ApiKey name", + "icon": "IconLink", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7e7d3bd6-c8d1-4f00-b7e6-5638ff2d2ea0", + "type": "DATE_TIME", + "name": "revokedAt", + "label": "Revocation date", + "description": "ApiKey revocation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c69762b7-9024-461f-a172-e43bc2118a8d", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "44500d1e-f620-4be0-87e0-afdd119880ce", + "type": "DATE_TIME", + "name": "expiresAt", + "label": "Expiration date", + "description": "ApiKey expiration date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "56c4c27a-7c6e-47b4-9453-10ccb57f2282", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0c7e8e67-c057-4206-87fd-789d3233fb71", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "c59e5489-0712-48d7-9fb1-1a9220523d0a", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarChannelEventAssociation", + "namePlural": "calendarChannelEventAssociations", + "labelSingular": "Calendar Channel Event Association", + "labelPlural": "Calendar Channel Event Associations", + "description": "Calendar Channel Event Associations", + "icon": "IconCalendar", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "3629c1eb-2202-4ed0-9fa7-3316bd7af303", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "3e061933-70aa-4753-bfa8-e483e2f73a7b", + "type": "RELATION", + "name": "calendarEvent", + "label": "Event ID", + "description": "Event ID", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "f3e235b0-74c1-4059-9075-ddb6aa98acf7", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "be1e7136-6dbe-4cd8-9c39-48b567eb927b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarEvent", + "namePlural": "calendarEvents", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "b90c9b2a-efc7-409c-910e-6c9cb9b77323" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "f3e235b0-74c1-4059-9075-ddb6aa98acf7", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "c59e5489-0712-48d7-9fb1-1a9220523d0a", + "nameSingular": "calendarChannelEventAssociation", + "namePlural": "calendarChannelEventAssociations" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "3e061933-70aa-4753-bfa8-e483e2f73a7b", + "name": "calendarEvent" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "be1e7136-6dbe-4cd8-9c39-48b567eb927b", + "nameSingular": "calendarEvent", + "namePlural": "calendarEvents" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "b90c9b2a-efc7-409c-910e-6c9cb9b77323", + "name": "calendarChannelEventAssociations" + } + } + }, + { + "__typename": "field", + "id": "3629c1eb-2202-4ed0-9fa7-3316bd7af303", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9265a2fe-7b06-41be-8b3e-b76712d32710", + "type": "TEXT", + "name": "eventExternalId", + "label": "Event external ID", + "description": "Event external ID", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c5330bab-0627-4059-8b06-3d113622104f", + "type": "UUID", + "name": "calendarChannelId", + "label": "Channel ID id (foreign key)", + "description": "Channel ID id foreign key", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "57247416-0da9-42b3-be40-741eb9439afc", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e25f7315-aaea-4d8a-aaf0-3d7f551d738f", + "type": "UUID", + "name": "calendarEventId", + "label": "Event ID id (foreign key)", + "description": "Event ID id foreign key", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b1aae268-1f9b-482b-81bb-353276339b50", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0950a79b-39b4-449f-9108-f980c52a038c", + "type": "RELATION", + "name": "calendarChannel", + "label": "Channel ID", + "description": "Channel ID", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "85465a13-1cd4-4048-9e57-6fa9cba0328e", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "f0f91da6-93c0-4dbf-993f-5ecadde0ec82", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarChannel", + "namePlural": "calendarChannels", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "cce21aeb-36eb-4563-92ea-a66f09244ec2" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "85465a13-1cd4-4048-9e57-6fa9cba0328e", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "c59e5489-0712-48d7-9fb1-1a9220523d0a", + "nameSingular": "calendarChannelEventAssociation", + "namePlural": "calendarChannelEventAssociations" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "0950a79b-39b4-449f-9108-f980c52a038c", + "name": "calendarChannel" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "f0f91da6-93c0-4dbf-993f-5ecadde0ec82", + "nameSingular": "calendarChannel", + "namePlural": "calendarChannels" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "cce21aeb-36eb-4563-92ea-a66f09244ec2", + "name": "calendarChannelEventAssociations" + } + } + } + ] + }, + { + "__typename": "object", + "id": "be1e7136-6dbe-4cd8-9c39-48b567eb927b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarEvent", + "namePlural": "calendarEvents", + "labelSingular": "Calendar event", + "labelPlural": "Calendar events", + "description": "Calendar events", + "icon": "IconCalendar", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "0f94a071-2619-4816-a02b-638a9f0111db", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "cfb0fb68-ebd1-4667-bca3-f2410057dc53", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "07c6cded-2b0d-4768-9439-eb1fc3a4ac22", + "type": "DATE_TIME", + "name": "externalUpdatedAt", + "label": "Update DateTime", + "description": "Update DateTime", + "icon": "IconCalendarCog", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "054977a4-1f5d-48e1-a650-a3457fbd419e", + "type": "LINKS", + "name": "conferenceLink", + "label": "Meet Link", + "description": "Meet Link", + "icon": "IconLink", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "primaryLinkUrl": "''", + "secondaryLinks": null, + "primaryLinkLabel": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0f94a071-2619-4816-a02b-638a9f0111db", + "type": "TEXT", + "name": "title", + "label": "Title", + "description": "Title", + "icon": "IconH1", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9114732a-5f28-4a95-a792-a2d9fed8bc66", + "type": "TEXT", + "name": "location", + "label": "Location", + "description": "Location", + "icon": "IconMapPin", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "2ea66e90-a913-4ffa-9ae5-647bc854be00", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "70f89256-4138-4c20-acb3-1a3233c3f45c", + "type": "DATE_TIME", + "name": "endsAt", + "label": "End Date", + "description": "End Date", + "icon": "IconCalendarClock", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c9c82a8f-9188-4b14-b5c4-a9739da9f531", + "type": "DATE_TIME", + "name": "startsAt", + "label": "Start Date", + "description": "Start Date", + "icon": "IconCalendarClock", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0604704a-4826-49f2-aaec-dd2140aac12f", + "type": "TEXT", + "name": "iCalUID", + "label": "iCal UID", + "description": "iCal UID", + "icon": "IconKey", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b90c9b2a-efc7-409c-910e-6c9cb9b77323", + "type": "RELATION", + "name": "calendarChannelEventAssociations", + "label": "Calendar Channel Event Associations", + "description": "Calendar Channel Event Associations", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "f3e235b0-74c1-4059-9075-ddb6aa98acf7", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "c59e5489-0712-48d7-9fb1-1a9220523d0a", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarChannelEventAssociation", + "namePlural": "calendarChannelEventAssociations", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "3e061933-70aa-4753-bfa8-e483e2f73a7b" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "f3e235b0-74c1-4059-9075-ddb6aa98acf7", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "be1e7136-6dbe-4cd8-9c39-48b567eb927b", + "nameSingular": "calendarEvent", + "namePlural": "calendarEvents" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "b90c9b2a-efc7-409c-910e-6c9cb9b77323", + "name": "calendarChannelEventAssociations" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "c59e5489-0712-48d7-9fb1-1a9220523d0a", + "nameSingular": "calendarChannelEventAssociation", + "namePlural": "calendarChannelEventAssociations" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "3e061933-70aa-4753-bfa8-e483e2f73a7b", + "name": "calendarEvent" + } + } + }, + { + "__typename": "field", + "id": "f753bebd-3b01-4d00-b01b-b8f89189c1a5", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "50097d6c-e6f7-41bb-9fc7-2e51984871b1", + "type": "BOOLEAN", + "name": "isCanceled", + "label": "Is canceled", + "description": "Is canceled", + "icon": "IconCalendarCancel", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": false, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3191b8f6-9018-4170-b18f-8937d815df9c", + "type": "TEXT", + "name": "conferenceSolution", + "label": "Conference Solution", + "description": "Conference Solution", + "icon": "IconScreenShare", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4a66544b-9e04-4de5-96d7-db59e46266cd", + "type": "RELATION", + "name": "calendarEventParticipants", + "label": "Event Participants", + "description": "Event Participants", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "14d1a448-3743-45c4-a8bb-944d1fd6a7e9", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "6cdc8d2b-243e-4dd4-b95a-4560a2876b30" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "14d1a448-3743-45c4-a8bb-944d1fd6a7e9", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "be1e7136-6dbe-4cd8-9c39-48b567eb927b", + "nameSingular": "calendarEvent", + "namePlural": "calendarEvents" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "4a66544b-9e04-4de5-96d7-db59e46266cd", + "name": "calendarEventParticipants" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "6cdc8d2b-243e-4dd4-b95a-4560a2876b30", + "name": "calendarEvent" + } + } + }, + { + "__typename": "field", + "id": "024a3ae6-22d8-47ff-b8f6-f700cbca7400", + "type": "DATE_TIME", + "name": "externalCreatedAt", + "label": "Creation DateTime", + "description": "Creation DateTime", + "icon": "IconCalendarPlus", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a604fcde-38b4-45bf-bac5-23049c730f4e", + "type": "TEXT", + "name": "recurringEventExternalId", + "label": "Recurring Event ID", + "description": "Recurring Event ID", + "icon": "IconHistory", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "599de76a-04dc-4924-862a-4654ebf45d6b", + "type": "BOOLEAN", + "name": "isFullDay", + "label": "Is Full Day", + "description": "Is Full Day", + "icon": "Icon24Hours", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": false, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3684f8bc-70cd-4680-87ac-ba27caf14508", + "type": "TEXT", + "name": "description", + "label": "Description", + "description": "Description", + "icon": "IconFileDescription", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "bbb291c8-1cb9-41e8-b1e0-ba4c07368ffc", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "viewFilter", + "namePlural": "viewFilters", + "labelSingular": "View Filter", + "labelPlural": "View Filters", + "description": "(System) View Filters", + "icon": "IconFilterBolt", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "8a26a310-ae2f-491f-8392-5c1b845822e9", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "436a9691-54d6-418e-92b9-88803cb3b49f", + "type": "UUID", + "name": "fieldMetadataId", + "label": "Field Metadata Id", + "description": "View Filter target field", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "03d34a15-8f41-496b-855b-af1eb70a9808", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cb38b434-b0ae-4bb5-b424-b5eaf0624c9c", + "type": "TEXT", + "name": "displayValue", + "label": "Display Value", + "description": "View Filter Display Value", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e0b3a971-9f05-4f4c-bad8-ce8da1b90a9f", + "type": "TEXT", + "name": "value", + "label": "Value", + "description": "View Filter value", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7d4cdc48-0603-402d-ac28-41c8d1f816f5", + "type": "TEXT", + "name": "operand", + "label": "Operand", + "description": "View Filter operand", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'Contains'", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9324fb02-189c-40af-bd50-cb9403c278ae", + "type": "UUID", + "name": "viewId", + "label": "View id (foreign key)", + "description": "View Filter related view id foreign key", + "icon": "IconLayoutCollage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8a26a310-ae2f-491f-8392-5c1b845822e9", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "54224f38-4757-4410-9d8d-bf678ca9f67b", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c2cd3386-204f-4132-9d60-65a5750cd56d", + "type": "RELATION", + "name": "view", + "label": "View", + "description": "View Filter related view", + "icon": "IconLayoutCollage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "f187e908-2fc5-4fc3-939b-5d9c9b2e206d", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "view", + "namePlural": "views", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "92693629-e829-4237-b29c-0e8200c1b19d" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "f187e908-2fc5-4fc3-939b-5d9c9b2e206d", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "bbb291c8-1cb9-41e8-b1e0-ba4c07368ffc", + "nameSingular": "viewFilter", + "namePlural": "viewFilters" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "c2cd3386-204f-4132-9d60-65a5750cd56d", + "name": "view" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "nameSingular": "view", + "namePlural": "views" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "92693629-e829-4237-b29c-0e8200c1b19d", + "name": "viewFilters" + } + } + } + ] + }, + { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants", + "labelSingular": "Message Participant", + "labelPlural": "Message Participants", + "description": "Message Participants", + "icon": "IconUserCircle", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "abd43d09-0839-4ca6-b8d8-b8481aacae67", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "abd43d09-0839-4ca6-b8d8-b8481aacae67", + "type": "TEXT", + "name": "handle", + "label": "Handle", + "description": "Handle", + "icon": "IconAt", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c3a8d72a-8715-4d77-a86d-10a14eb63bbe", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "31d4978e-a12d-4819-9f10-1f28692b89b9", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "Person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "dbb65ba0-a947-4d78-bf59-62f5fcabaa23", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "b7d8feef-0553-4b39-a860-ef60b928a038" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "dbb65ba0-a947-4d78-bf59-62f5fcabaa23", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "31d4978e-a12d-4819-9f10-1f28692b89b9", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "b7d8feef-0553-4b39-a860-ef60b928a038", + "name": "messageParticipants" + } + } + }, + { + "__typename": "field", + "id": "080e3d11-b135-4601-a634-2c64a20a337f", + "type": "UUID", + "name": "workspaceMemberId", + "label": "Workspace Member id (foreign key)", + "description": "Workspace member id foreign key", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3574f0f2-b6e4-434d-8ecc-4d680f818e22", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b21800b9-ef68-45ad-b2bb-72fa1c603561", + "type": "SELECT", + "name": "role", + "label": "Role", + "description": "Role", + "icon": "IconAt", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'from'", + "options": [ + { + "id": "8e8aa19c-58f6-4be5-9f1c-e3dc3ccf486a", + "color": "green", + "label": "From", + "value": "from", + "position": 0 + }, + { + "id": "4f1300c7-9d2a-44aa-9701-b9c5fcf9e76c", + "color": "blue", + "label": "To", + "value": "to", + "position": 1 + }, + { + "id": "f5f45bda-3637-4dfa-9f1f-f9d07c8a15e6", + "color": "orange", + "label": "Cc", + "value": "cc", + "position": 2 + }, + { + "id": "c3812815-5b2f-4f1f-beba-7f58bead8374", + "color": "red", + "label": "Bcc", + "value": "bcc", + "position": 3 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a890fd3d-9f6c-4c6b-9ff2-72493c000c98", + "type": "RELATION", + "name": "message", + "label": "Message", + "description": "Message", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "85b24729-a5bb-48bb-88cd-0cdb39f14033", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "message", + "namePlural": "messages", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "62492454-1575-4137-ab32-860c6970b29d" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "85b24729-a5bb-48bb-88cd-0cdb39f14033", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "a890fd3d-9f6c-4c6b-9ff2-72493c000c98", + "name": "message" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "nameSingular": "message", + "namePlural": "messages" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "62492454-1575-4137-ab32-860c6970b29d", + "name": "messageParticipants" + } + } + }, + { + "__typename": "field", + "id": "b62df27d-9cff-4675-b314-4cc498f3a7a5", + "type": "RELATION", + "name": "workspaceMember", + "label": "Workspace Member", + "description": "Workspace member", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "065fd1c6-b214-482d-b409-68d0c3e65453", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "1eacd841-ab52-4f4a-98d8-67306a756046" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "065fd1c6-b214-482d-b409-68d0c3e65453", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "b62df27d-9cff-4675-b314-4cc498f3a7a5", + "name": "workspaceMember" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "1eacd841-ab52-4f4a-98d8-67306a756046", + "name": "messageParticipants" + } + } + }, + { + "__typename": "field", + "id": "8675f5ea-be0b-4e3a-9f87-dd586b8249d1", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "Person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0a790ad2-f3b0-494d-b462-a316d12f082a", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "d967b8e9-d2b0-480e-94e2-ecf47afe2fe2", + "type": "TEXT", + "name": "displayName", + "label": "Display Name", + "description": "Display Name", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e3a5dcca-b315-4cf4-9878-5220243a660f", + "type": "UUID", + "name": "messageId", + "label": "Message id (foreign key)", + "description": "Message id foreign key", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "view", + "namePlural": "views", + "labelSingular": "View", + "labelPlural": "Views", + "description": "(System) Views", + "icon": "IconLayoutCollage", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "ba3b08bc-37c1-4426-83fb-46dc61d83901", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "ba3b08bc-37c1-4426-83fb-46dc61d83901", + "type": "TEXT", + "name": "name", + "label": "Name", + "description": "View name", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7e89979b-8f90-4a72-8923-0c5905c6d074", + "type": "TEXT", + "name": "type", + "label": "Type", + "description": "View type", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'table'", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "fed43a8c-5ff3-4e61-adba-589c3db889c9", + "type": "RELATION", + "name": "viewFields", + "label": "View Fields", + "description": "View Fields", + "icon": "IconTag", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "6f866652-086e-4927-b158-c9d4b833fb5d", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "9e1e6e1e-3cb5-4f57-9ffc-412a6fdb6ddf", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "viewField", + "namePlural": "viewFields", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "4dcb9bd1-9112-4561-96c4-5aed4c482ad3" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6f866652-086e-4927-b158-c9d4b833fb5d", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "nameSingular": "view", + "namePlural": "views" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "fed43a8c-5ff3-4e61-adba-589c3db889c9", + "name": "viewFields" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "9e1e6e1e-3cb5-4f57-9ffc-412a6fdb6ddf", + "nameSingular": "viewField", + "namePlural": "viewFields" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "4dcb9bd1-9112-4561-96c4-5aed4c482ad3", + "name": "view" + } + } + }, + { + "__typename": "field", + "id": "f8c98d6e-829e-4448-a82c-39faad422d98", + "type": "SELECT", + "name": "key", + "label": "Key", + "description": "View key", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'INDEX'", + "options": [ + { + "id": "6eafa356-f2ee-4fc7-8332-6e8350dc53a0", + "color": "red", + "label": "Index", + "value": "INDEX", + "position": 0 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1d5919e7-07dc-4303-bec5-b512126ede6e", + "type": "BOOLEAN", + "name": "isCompact", + "label": "Compact View", + "description": "Describes if the view is in compact mode", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": false, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "5c6af6b3-c0eb-4bf9-b1df-1a2d8ef2b438", + "type": "TEXT", + "name": "kanbanFieldMetadataId", + "label": "kanbanfieldMetadataId", + "description": "View Kanban column field", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "ea94fd27-8cbc-4dc9-8a99-1227f8363073", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b3f199c8-b6af-466b-ba77-8f7369a6aba6", + "type": "UUID", + "name": "objectMetadataId", + "label": "Object Metadata Id", + "description": "View target object", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "85d7f8a1-3bfd-4202-819a-ffbd225712e4", + "type": "TEXT", + "name": "icon", + "label": "Icon", + "description": "View icon", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c4dde80e-9e1d-4ef0-ae9e-0138beec5da1", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "92693629-e829-4237-b29c-0e8200c1b19d", + "type": "RELATION", + "name": "viewFilters", + "label": "View Filters", + "description": "View Filters", + "icon": "IconFilterBolt", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "f187e908-2fc5-4fc3-939b-5d9c9b2e206d", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "bbb291c8-1cb9-41e8-b1e0-ba4c07368ffc", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "viewFilter", + "namePlural": "viewFilters", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "c2cd3386-204f-4132-9d60-65a5750cd56d" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "f187e908-2fc5-4fc3-939b-5d9c9b2e206d", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "nameSingular": "view", + "namePlural": "views" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "92693629-e829-4237-b29c-0e8200c1b19d", + "name": "viewFilters" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "bbb291c8-1cb9-41e8-b1e0-ba4c07368ffc", + "nameSingular": "viewFilter", + "namePlural": "viewFilters" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "c2cd3386-204f-4132-9d60-65a5750cd56d", + "name": "view" + } + } + }, + { + "__typename": "field", + "id": "590d3fe4-50dd-4056-8732-85b512a9351d", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9e47a3a1-219c-47d3-8cc1-d9f73b21c36e", + "type": "RELATION", + "name": "viewSorts", + "label": "View Sorts", + "description": "View Sorts", + "icon": "IconArrowsSort", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "92560ff2-bdf7-4780-a604-d2a8a219bbb7", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2ef99ca9-5081-4828-8abc-3d77462ba153", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "viewSort", + "namePlural": "viewSorts", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "60f8182b-9a55-4ba9-b7c2-b92979914cc5" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "92560ff2-bdf7-4780-a604-d2a8a219bbb7", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "nameSingular": "view", + "namePlural": "views" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "9e47a3a1-219c-47d3-8cc1-d9f73b21c36e", + "name": "viewSorts" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2ef99ca9-5081-4828-8abc-3d77462ba153", + "nameSingular": "viewSort", + "namePlural": "viewSorts" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "60f8182b-9a55-4ba9-b7c2-b92979914cc5", + "name": "view" + } + } + }, + { + "__typename": "field", + "id": "9c5ddca8-709b-4ed3-94fc-39b6c9a107bb", + "type": "POSITION", + "name": "position", + "label": "Position", + "description": "View position", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "9e1e6e1e-3cb5-4f57-9ffc-412a6fdb6ddf", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "viewField", + "namePlural": "viewFields", + "labelSingular": "View Field", + "labelPlural": "View Fields", + "description": "(System) View Fields", + "icon": "IconTag", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "bf7e7d59-00df-4c0c-b5f3-d0f886d700b1", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "eda3efdc-a0df-47bc-83c8-cdac71978cf7", + "type": "UUID", + "name": "viewId", + "label": "View id (foreign key)", + "description": "View Field related view id foreign key", + "icon": "IconLayoutCollage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "d5d1d238-4750-4806-b16c-527c70dd7d54", + "type": "NUMBER", + "name": "size", + "label": "Size", + "description": "View Field size", + "icon": "IconEye", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": 0, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9a8a984c-344f-455d-bf20-4b07b0bcdbe6", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "bf7e7d59-00df-4c0c-b5f3-d0f886d700b1", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4dcb9bd1-9112-4561-96c4-5aed4c482ad3", + "type": "RELATION", + "name": "view", + "label": "View", + "description": "View Field related view", + "icon": "IconLayoutCollage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "6f866652-086e-4927-b158-c9d4b833fb5d", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "view", + "namePlural": "views", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "fed43a8c-5ff3-4e61-adba-589c3db889c9" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6f866652-086e-4927-b158-c9d4b833fb5d", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "9e1e6e1e-3cb5-4f57-9ffc-412a6fdb6ddf", + "nameSingular": "viewField", + "namePlural": "viewFields" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "4dcb9bd1-9112-4561-96c4-5aed4c482ad3", + "name": "view" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "nameSingular": "view", + "namePlural": "views" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "fed43a8c-5ff3-4e61-adba-589c3db889c9", + "name": "viewFields" + } + } + }, + { + "__typename": "field", + "id": "0cf9ebe5-7ed9-44b2-94d1-8d823f9746e4", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "18cb6aaa-4c2d-42ab-bdd1-5bce80ff37c4", + "type": "NUMBER", + "name": "position", + "label": "Position", + "description": "View Field position", + "icon": "IconList", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": 0, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "674b2259-a100-48f2-8716-04814a44ffbb", + "type": "BOOLEAN", + "name": "isVisible", + "label": "Visible", + "description": "View Field visibility", + "icon": "IconEye", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": true, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "15812392-74a4-4a6e-b633-5f8107477ad0", + "type": "UUID", + "name": "fieldMetadataId", + "label": "Field Metadata Id", + "description": "View Field target field", + "icon": "IconTag", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "noteTarget", + "namePlural": "noteTargets", + "labelSingular": "Note Target", + "labelPlural": "Note Targets", + "description": "A note target", + "icon": "IconCheckbox", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "913b3bdc-6ec3-43e6-a31d-997f04d78fd7", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "28699259-a9cb-4e5c-a41b-fcc90fb75161", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b9ca58e2-71fa-4c4a-822d-89d00d490e95", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "NoteTarget company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6b0ee6d8-5a4f-4529-8a51-0006e04dbd77", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "NoteTarget person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "a1e94373-f576-4b1b-a4bc-edb561c96739", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "9b7d57f3-51ef-4cb2-b359-e888216590e8" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "a1e94373-f576-4b1b-a4bc-edb561c96739", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "6b0ee6d8-5a4f-4529-8a51-0006e04dbd77", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "9b7d57f3-51ef-4cb2-b359-e888216590e8", + "name": "noteTargets" + } + } + }, + { + "__typename": "field", + "id": "5236db98-2a29-4643-90c4-a061a78284c9", + "type": "RELATION", + "name": "opportunity", + "label": "Opportunity", + "description": "NoteTarget opportunity", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "4765887f-b385-4514-9552-5ed4bd471a52", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "26b60af3-55a1-4483-aff7-46d43a558846" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "4765887f-b385-4514-9552-5ed4bd471a52", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "5236db98-2a29-4643-90c4-a061a78284c9", + "name": "opportunity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "26b60af3-55a1-4483-aff7-46d43a558846", + "name": "noteTargets" + } + } + }, + { + "__typename": "field", + "id": "d9396e8e-febe-4955-b56b-c4259050a676", + "type": "UUID", + "name": "noteId", + "label": "Note id (foreign key)", + "description": "NoteTarget note id foreign key", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "53cbaa8c-aeef-4f36-96c0-28a674086f7e", + "type": "RELATION", + "name": "note", + "label": "Note", + "description": "NoteTarget note", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "4849ded7-c0d5-4e32-8e11-fdf57f7d224b", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "note", + "namePlural": "notes", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "b8d27dfc-7028-4c5d-baab-0d961899922b" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "4849ded7-c0d5-4e32-8e11-fdf57f7d224b", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "53cbaa8c-aeef-4f36-96c0-28a674086f7e", + "name": "note" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "nameSingular": "note", + "namePlural": "notes" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "b8d27dfc-7028-4c5d-baab-0d961899922b", + "name": "noteTargets" + } + } + }, + { + "__typename": "field", + "id": "03bd3366-2dec-4169-b502-893c591b6794", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "NoteTarget company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "6819eb45-5c67-484f-ba4d-c35fe72cb256", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "54e7231c-86a2-4453-abaa-13448ea23629" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6819eb45-5c67-484f-ba4d-c35fe72cb256", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "03bd3366-2dec-4169-b502-893c591b6794", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "54e7231c-86a2-4453-abaa-13448ea23629", + "name": "noteTargets" + } + } + }, + { + "__typename": "field", + "id": "0a673a2e-8480-4044-882b-9d05993dfcd9", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b14f9edc-0c7e-4eef-bd57-bd1d76fff530", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "NoteTarget person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "913b3bdc-6ec3-43e6-a31d-997f04d78fd7", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e65e86f4-aa4b-4e79-bed7-9aec450ad788", + "type": "UUID", + "name": "opportunityId", + "label": "Opportunity id (foreign key)", + "description": "NoteTarget opportunity id foreign key", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "labelSingular": "Person", + "labelPlural": "People", + "description": "A person", + "icon": "IconUser", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "131cca56-44ae-4005-9c54-70cc9dc8263d", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "131cca56-44ae-4005-9c54-70cc9dc8263d", + "type": "FULL_NAME", + "name": "name", + "label": "Name", + "description": "Contact’s name", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "lastName": "''", + "firstName": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "97ceb237-a8a5-48a7-bfeb-dab65b29214f", + "type": "RELATION", + "name": "taskTargets", + "label": "Tasks", + "description": "Tasks tied to the contact", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "bd1aae4b-996d-4419-8870-90364605fb4a", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "taskTarget", + "namePlural": "taskTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "ccb227ee-30e7-4c31-bc23-ef7f0e5fc708" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "bd1aae4b-996d-4419-8870-90364605fb4a", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "97ceb237-a8a5-48a7-bfeb-dab65b29214f", + "name": "taskTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "ccb227ee-30e7-4c31-bc23-ef7f0e5fc708", + "name": "person" + } + } + }, + { + "__typename": "field", + "id": "d052cd42-e48f-4323-8487-50eee4d86deb", + "type": "RELATION", + "name": "attachments", + "label": "Attachments", + "description": "Attachments linked to the contact.", + "icon": "IconFileImport", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "c4c8361f-f03f-43c6-b63c-c578f8781912", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "9e4e615f-9e7b-474c-b3eb-ca65c05dad8e" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c4c8361f-f03f-43c6-b63c-c578f8781912", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "d052cd42-e48f-4323-8487-50eee4d86deb", + "name": "attachments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "9e4e615f-9e7b-474c-b3eb-ca65c05dad8e", + "name": "person" + } + } + }, + { + "__typename": "field", + "id": "9b772256-2793-4b19-ab86-43d692ba6174", + "type": "EMAIL", + "name": "email", + "label": "Email", + "description": "Contact’s Email", + "icon": "IconMail", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "92e107be-ec6d-401f-8c20-ee1a628ae57c", + "type": "RELATION", + "name": "favorites", + "label": "Favorites", + "description": "Favorites linked to the contact", + "icon": "IconHeart", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "c4d7c4df-c9c2-4919-97da-21fa03fac8bb", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "favorite", + "namePlural": "favorites", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "2389c7c9-c4d0-48d2-8444-59b0ca85c1be" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c4d7c4df-c9c2-4919-97da-21fa03fac8bb", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "92e107be-ec6d-401f-8c20-ee1a628ae57c", + "name": "favorites" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "2389c7c9-c4d0-48d2-8444-59b0ca85c1be", + "name": "person" + } + } + }, + { + "__typename": "field", + "id": "4e5ae7da-4e6e-4009-895b-ef70d770a4e1", + "type": "TEXT", + "name": "phone", + "label": "Phone", + "description": "Contact’s phone number", + "icon": "IconPhone", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7d9a0385-f3f9-45bf-8ca2-c7a5d42b34c9", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cb5d7245-2f48-45bc-b879-db5424150f5d", + "type": "TEXT", + "name": "avatarUrl", + "label": "Avatar", + "description": "Contact’s avatar", + "icon": "IconFileUpload", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "261bebf3-ff59-461e-bfa8-8dda5633f128", + "type": "TEXT", + "name": "jobTitle", + "label": "Job Title", + "description": "Contact’s job title", + "icon": "IconBriefcase", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9d4f3a24-7d93-4ee5-aa45-9bad22e1f327", + "type": "POSITION", + "name": "position", + "label": "Position", + "description": "Person record Position", + "icon": "IconHierarchy2", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e0158d3b-2ccf-4d97-a467-7a1d055b49e7", + "type": "RELATION", + "name": "timelineActivities", + "label": "Events", + "description": "Events linked to the person", + "icon": "IconTimelineEvent", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "631d4fb4-82b7-46af-be99-39f115256634", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "07909ab0-cc9a-4a4d-ab31-d7426728c60c" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "631d4fb4-82b7-46af-be99-39f115256634", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "e0158d3b-2ccf-4d97-a467-7a1d055b49e7", + "name": "timelineActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "07909ab0-cc9a-4a4d-ab31-d7426728c60c", + "name": "person" + } + } + }, + { + "__typename": "field", + "id": "4b9729f5-c820-4b2c-854a-e463cf9df0b9", + "type": "RELATION", + "name": "calendarEventParticipants", + "label": "Calendar Event Participants", + "description": "Calendar Event Participants", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "70fa8b61-e6cf-4df4-bafc-a56d5e95aa47", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "2b8670a5-31da-46e1-83d3-81f0656bd00f" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "70fa8b61-e6cf-4df4-bafc-a56d5e95aa47", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "4b9729f5-c820-4b2c-854a-e463cf9df0b9", + "name": "calendarEventParticipants" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "2b8670a5-31da-46e1-83d3-81f0656bd00f", + "name": "person" + } + } + }, + { + "__typename": "field", + "id": "cb0b3caa-69f5-46c0-bbda-830fbe628397", + "type": "TEXT", + "name": "city", + "label": "City", + "description": "Contact’s city", + "icon": "IconMap", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "55bda917-709a-47b6-aa4e-643319a4d780", + "type": "RELATION", + "name": "pointOfContactForOpportunities", + "label": "POC for Opportunities", + "description": "Point of Contact for Opportunities", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "6ba5719c-8612-436c-95d7-0b7674ccfdce", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "toFieldMetadataId": "8128ca8b-7a70-4c33-bb38-0322bd1b96a1" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6ba5719c-8612-436c-95d7-0b7674ccfdce", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "55bda917-709a-47b6-aa4e-643319a4d780", + "name": "pointOfContactForOpportunities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "8128ca8b-7a70-4c33-bb38-0322bd1b96a1", + "name": "pointOfContact" + } + } + }, + { + "__typename": "field", + "id": "d55b9c01-5709-469c-acfb-d2f5b8eac069", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c3613943-b1d2-4600-a72c-16db022f0b1f", + "type": "LINKS", + "name": "xLink", + "label": "X", + "description": "Contact’s X/Twitter account", + "icon": "IconBrandX", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "primaryLinkUrl": "''", + "secondaryLinks": null, + "primaryLinkLabel": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b7d8feef-0553-4b39-a860-ef60b928a038", + "type": "RELATION", + "name": "messageParticipants", + "label": "Message Participants", + "description": "Message Participants", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "dbb65ba0-a947-4d78-bf59-62f5fcabaa23", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "31d4978e-a12d-4819-9f10-1f28692b89b9" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "dbb65ba0-a947-4d78-bf59-62f5fcabaa23", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "b7d8feef-0553-4b39-a860-ef60b928a038", + "name": "messageParticipants" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "31d4978e-a12d-4819-9f10-1f28692b89b9", + "name": "person" + } + } + }, + { + "__typename": "field", + "id": "4c6aa448-8f01-4039-b085-20951e2847d3", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "Contact’s company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "62c395a8-de62-4433-ab42-e56d2c877f2d", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "64a7efdd-8456-43ba-83b5-541d8c0d9a34" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "62c395a8-de62-4433-ab42-e56d2c877f2d", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "4c6aa448-8f01-4039-b085-20951e2847d3", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "64a7efdd-8456-43ba-83b5-541d8c0d9a34", + "name": "people" + } + } + }, + { + "__typename": "field", + "id": "e1abc35e-308a-442d-82e7-239cfa160872", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a655af2e-d8ed-4333-91c4-91c875712e67", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "Contact’s company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9b7d57f3-51ef-4cb2-b359-e888216590e8", + "type": "RELATION", + "name": "noteTargets", + "label": "Notes", + "description": "Notes tied to the contact", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "a1e94373-f576-4b1b-a4bc-edb561c96739", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "noteTarget", + "namePlural": "noteTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "6b0ee6d8-5a4f-4529-8a51-0006e04dbd77" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "a1e94373-f576-4b1b-a4bc-edb561c96739", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "9b7d57f3-51ef-4cb2-b359-e888216590e8", + "name": "noteTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "6b0ee6d8-5a4f-4529-8a51-0006e04dbd77", + "name": "person" + } + } + }, + { + "__typename": "field", + "id": "fe223e69-bb46-4ebf-8716-ccff2b0a73f7", + "type": "LINKS", + "name": "linkedinLink", + "label": "Linkedin", + "description": "Contact’s Linkedin account", + "icon": "IconBrandLinkedin", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "primaryLinkUrl": "''", + "secondaryLinks": null, + "primaryLinkLabel": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "76fdf9b8-8486-4b4d-a283-41f062e92fc9", + "type": "RELATION", + "name": "activityTargets", + "label": "Activities", + "description": "Activities tied to the contact", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "2399c22c-66a7-4f99-8e13-4a2972d42419", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activityTarget", + "namePlural": "activityTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "e9ee5ea2-da60-45e0-9ed8-0e6a2f7b9c0f" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "2399c22c-66a7-4f99-8e13-4a2972d42419", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "76fdf9b8-8486-4b4d-a283-41f062e92fc9", + "name": "activityTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "e9ee5ea2-da60-45e0-9ed8-0e6a2f7b9c0f", + "name": "person" + } + } + } + ] + }, + { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activityTarget", + "namePlural": "activityTargets", + "labelSingular": "Activity Target", + "labelPlural": "Activity Targets", + "description": "An activity target", + "icon": "IconCheckbox", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "96253d1c-f674-4fd2-ac83-bd8cb495cf0f", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "e585fffb-01d9-4a26-833b-85b877259eaf", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "ActivityTarget company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "43f39b88-1e36-4532-98e2-a60338814482", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7ff327f2-24c2-4cd7-b723-5463147226fd", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "ActivityTarget company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "d5afdcb3-debf-42f8-b360-0a4e6ab63a36", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "1a1285b4-8e39-4748-9405-02335e9ab3be" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d5afdcb3-debf-42f8-b360-0a4e6ab63a36", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "7ff327f2-24c2-4cd7-b723-5463147226fd", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "1a1285b4-8e39-4748-9405-02335e9ab3be", + "name": "activityTargets" + } + } + }, + { + "__typename": "field", + "id": "e9ee5ea2-da60-45e0-9ed8-0e6a2f7b9c0f", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "ActivityTarget person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "2399c22c-66a7-4f99-8e13-4a2972d42419", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "76fdf9b8-8486-4b4d-a283-41f062e92fc9" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "2399c22c-66a7-4f99-8e13-4a2972d42419", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "e9ee5ea2-da60-45e0-9ed8-0e6a2f7b9c0f", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "76fdf9b8-8486-4b4d-a283-41f062e92fc9", + "name": "activityTargets" + } + } + }, + { + "__typename": "field", + "id": "2f8f925f-cdac-47d3-b421-3a12c5314b17", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "ActivityTarget person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b116bcff-3be7-4beb-bdda-f015ca72e9bb", + "type": "UUID", + "name": "activityId", + "label": "Activity id (foreign key)", + "description": "ActivityTarget activity id foreign key", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "ed60b546-5eef-4aa4-bec2-9af50de21c2c", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8e54b513-194b-4c27-9cb1-8c2a868b1566", + "type": "RELATION", + "name": "opportunity", + "label": "Opportunity", + "description": "ActivityTarget opportunity", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "354082a1-2eb2-4d4c-974c-765b2901c797", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "878e56e8-4f19-4180-aff5-7212b6f03fe6" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "354082a1-2eb2-4d4c-974c-765b2901c797", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "8e54b513-194b-4c27-9cb1-8c2a868b1566", + "name": "opportunity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "878e56e8-4f19-4180-aff5-7212b6f03fe6", + "name": "activityTargets" + } + } + }, + { + "__typename": "field", + "id": "3ee5a520-a7ef-464e-b4d4-5d2f8bc6b06f", + "type": "UUID", + "name": "opportunityId", + "label": "Opportunity id (foreign key)", + "description": "ActivityTarget opportunity id foreign key", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "350b1f58-1a4e-4759-ac3d-2cff5fc0bf59", + "type": "RELATION", + "name": "activity", + "label": "Activity", + "description": "ActivityTarget activity", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "6a74e2a1-54a1-47d0-b56e-2f0a30e748ac", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activity", + "namePlural": "activities", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "70146bf7-008a-457c-a3eb-c1febb307eac" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6a74e2a1-54a1-47d0-b56e-2f0a30e748ac", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "350b1f58-1a4e-4759-ac3d-2cff5fc0bf59", + "name": "activity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "70146bf7-008a-457c-a3eb-c1febb307eac", + "name": "activityTargets" + } + } + }, + { + "__typename": "field", + "id": "96253d1c-f674-4fd2-ac83-bd8cb495cf0f", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts", + "labelSingular": "Connected Account", + "labelPlural": "Connected Accounts", + "description": "A connected account", + "icon": "IconAt", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "3c2a20e7-28bb-47b6-ac54-703700e7b3b7", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "ea6ef32a-1baf-410f-98b6-b1478080f2ad", + "type": "TEXT", + "name": "refreshToken", + "label": "Refresh Token", + "description": "Messaging provider refresh token", + "icon": "IconKey", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9497d34f-5219-46ca-bec7-ca85a0399ba2", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9d27b9b3-7760-4b58-82fc-931aaffca2ed", + "type": "DATE_TIME", + "name": "authFailedAt", + "label": "Auth failed at", + "description": "Auth failed at", + "icon": "IconX", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "fc97ddc4-f4ff-4e54-84e6-7ccc4bd8772e", + "type": "RELATION", + "name": "calendarChannels", + "label": "Calendar Channels", + "description": "Calendar Channels", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "6f69497c-d0e7-47f7-b271-12904c0f6b59", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "f0f91da6-93c0-4dbf-993f-5ecadde0ec82", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarChannel", + "namePlural": "calendarChannels", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "e4cad90a-5f83-4591-a371-6f65a74531b5" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6f69497c-d0e7-47f7-b271-12904c0f6b59", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "fc97ddc4-f4ff-4e54-84e6-7ccc4bd8772e", + "name": "calendarChannels" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "f0f91da6-93c0-4dbf-993f-5ecadde0ec82", + "nameSingular": "calendarChannel", + "namePlural": "calendarChannels" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "e4cad90a-5f83-4591-a371-6f65a74531b5", + "name": "connectedAccount" + } + } + }, + { + "__typename": "field", + "id": "d386f873-fef3-4a2b-80e9-3e96b2e3a892", + "type": "TEXT", + "name": "accessToken", + "label": "Access Token", + "description": "Messaging provider access token", + "icon": "IconKey", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4da294c8-5ae1-4c97-8804-6e2ea5a3b28c", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cb106d74-30da-4d03-9842-80453474ff43", + "type": "TEXT", + "name": "lastSyncHistoryId", + "label": "Last sync history ID", + "description": "Last sync history ID", + "icon": "IconHistory", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "62ddb5e4-1752-48f9-b23b-4f8eebb56b29", + "type": "TEXT", + "name": "provider", + "label": "provider", + "description": "The account provider", + "icon": "IconSettings", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4b1a8d45-8338-4f36-8495-bd230335ddf9", + "type": "RELATION", + "name": "accountOwner", + "label": "Account Owner", + "description": "Account Owner", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "08199572-bc4c-4516-9fc3-354e118b1e38", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "bd7607b2-e92f-4179-ab1b-af4013e6a6f1" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "08199572-bc4c-4516-9fc3-354e118b1e38", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "4b1a8d45-8338-4f36-8495-bd230335ddf9", + "name": "accountOwner" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "bd7607b2-e92f-4179-ab1b-af4013e6a6f1", + "name": "connectedAccounts" + } + } + }, + { + "__typename": "field", + "id": "e08005e5-5d49-4257-a010-78f30614bfa4", + "type": "UUID", + "name": "accountOwnerId", + "label": "Account Owner id (foreign key)", + "description": "Account Owner id foreign key", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3c2a20e7-28bb-47b6-ac54-703700e7b3b7", + "type": "TEXT", + "name": "handle", + "label": "handle", + "description": "The account handle (email, username, phone number, etc.)", + "icon": "IconMail", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9a910726-3ced-4da3-b1de-8646b9112ccb", + "type": "TEXT", + "name": "handleAliases", + "label": "Handle Aliases", + "description": "Handle Aliases", + "icon": "IconMail", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "56ffec90-5645-484b-ac07-4e64aeb4debe", + "type": "RELATION", + "name": "messageChannels", + "label": "Message Channels", + "description": "Message Channels", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "198d983d-8caa-4a98-96cc-69ed0d0c7ab7", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "10593c25-7116-4ee2-a448-60272e867704", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageChannel", + "namePlural": "messageChannels", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "a96cf30c-1f7b-4614-a8a9-d89c3900a306" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "198d983d-8caa-4a98-96cc-69ed0d0c7ab7", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "56ffec90-5645-484b-ac07-4e64aeb4debe", + "name": "messageChannels" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "10593c25-7116-4ee2-a448-60272e867704", + "nameSingular": "messageChannel", + "namePlural": "messageChannels" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "a96cf30c-1f7b-4614-a8a9-d89c3900a306", + "name": "connectedAccount" + } + } + }, + { + "__typename": "field", + "id": "80aec8e0-f61f-4eb2-ba6c-b5a36b81a8b0", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "labelSingular": "Opportunity", + "labelPlural": "Opportunities", + "description": "An opportunity", + "icon": "IconTargetArrow", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "1eb9c6d0-62a5-4b57-9ee6-0e8864bc10bf", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "cbb8ca95-b54c-4b75-9fe3-43ebea141537", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "Opportunity company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "75f9bd66-fae0-4f15-9c2c-10f728b2aa45", + "type": "UUID", + "name": "pointOfContactId", + "label": "Point of Contact id (foreign key)", + "description": "Opportunity point of contact id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1ff5b4b5-11cd-4a40-a158-0662120fa7a6", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1afeb7d7-2000-4ef5-a843-60769bf72c8b", + "type": "DATE_TIME", + "name": "closeDate", + "label": "Close date", + "description": "Opportunity close date", + "icon": "IconCalendarEvent", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1eb9c6d0-62a5-4b57-9ee6-0e8864bc10bf", + "type": "TEXT", + "name": "name", + "label": "Name", + "description": "The opportunity name", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "31bbc743-3b92-40bf-b2cd-e94e6dee9160", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "Opportunity company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "aa62c2e3-48d4-4e2f-b08d-ebe66ece3c3b", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "21596676-4dd1-4159-9ec5-d5bfab2e5d45" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "aa62c2e3-48d4-4e2f-b08d-ebe66ece3c3b", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "31bbc743-3b92-40bf-b2cd-e94e6dee9160", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "21596676-4dd1-4159-9ec5-d5bfab2e5d45", + "name": "opportunities" + } + } + }, + { + "__typename": "field", + "id": "cfdff652-450e-4068-94b4-254b8f107bb1", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "878e56e8-4f19-4180-aff5-7212b6f03fe6", + "type": "RELATION", + "name": "activityTargets", + "label": "Activities", + "description": "Activities tied to the opportunity", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "354082a1-2eb2-4d4c-974c-765b2901c797", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activityTarget", + "namePlural": "activityTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "8e54b513-194b-4c27-9cb1-8c2a868b1566" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "354082a1-2eb2-4d4c-974c-765b2901c797", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "878e56e8-4f19-4180-aff5-7212b6f03fe6", + "name": "activityTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8cbeabef-c8f7-4cdc-a38f-e1c41cae52e6", + "nameSingular": "activityTarget", + "namePlural": "activityTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "8e54b513-194b-4c27-9cb1-8c2a868b1566", + "name": "opportunity" + } + } + }, + { + "__typename": "field", + "id": "db4fa1e8-7e0d-4538-923d-562a0fe69820", + "type": "SELECT", + "name": "stage", + "label": "Stage", + "description": "Opportunity stage", + "icon": "IconProgressCheck", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'NEW'", + "options": [ + { + "id": "af639add-7929-4d4c-9b25-d46d5538683d", + "color": "red", + "label": "New", + "value": "NEW", + "position": 0 + }, + { + "id": "26e91321-d9b7-4271-be3a-0e830c964d8c", + "color": "purple", + "label": "Screening", + "value": "SCREENING", + "position": 1 + }, + { + "id": "40342d06-fcf7-43e9-8b62-952be5fb2dd5", + "color": "sky", + "label": "Meeting", + "value": "MEETING", + "position": 2 + }, + { + "id": "d30959ba-80bd-47cf-a906-7e71a0be34db", + "color": "turquoise", + "label": "Proposal", + "value": "PROPOSAL", + "position": 3 + }, + { + "id": "4e51e9a9-998f-417f-ac65-849514699c7a", + "color": "yellow", + "label": "Customer", + "value": "CUSTOMER", + "position": 4 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8128ca8b-7a70-4c33-bb38-0322bd1b96a1", + "type": "RELATION", + "name": "pointOfContact", + "label": "Point of Contact", + "description": "Opportunity point of contact", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "6ba5719c-8612-436c-95d7-0b7674ccfdce", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "55bda917-709a-47b6-aa4e-643319a4d780" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6ba5719c-8612-436c-95d7-0b7674ccfdce", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "8128ca8b-7a70-4c33-bb38-0322bd1b96a1", + "name": "pointOfContact" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "55bda917-709a-47b6-aa4e-643319a4d780", + "name": "pointOfContactForOpportunities" + } + } + }, + { + "__typename": "field", + "id": "b9f58a84-aad0-498c-baa1-5d31779f60c5", + "type": "POSITION", + "name": "position", + "label": "Position", + "description": "Opportunity record position", + "icon": "IconHierarchy2", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "37f365ff-5669-4da4-927e-f6c6d7cfb05e", + "type": "RELATION", + "name": "attachments", + "label": "Attachments", + "description": "Attachments linked to the opportunity", + "icon": "IconFileImport", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "c8bb21af-7e5d-440c-ad6d-ee2fb83dc411", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "3a89284d-8eaa-4b83-8b2f-b11d8f725301" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c8bb21af-7e5d-440c-ad6d-ee2fb83dc411", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "37f365ff-5669-4da4-927e-f6c6d7cfb05e", + "name": "attachments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "3a89284d-8eaa-4b83-8b2f-b11d8f725301", + "name": "opportunity" + } + } + }, + { + "__typename": "field", + "id": "6b4e56db-707e-414a-b461-017e781b1c63", + "type": "CURRENCY", + "name": "amount", + "label": "Amount", + "description": "Opportunity amount", + "icon": "IconCurrencyDollar", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": { + "amountMicros": null, + "currencyCode": "''" + }, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "bdc07845-b914-4fb9-bb56-55f4a074a4aa", + "type": "RELATION", + "name": "favorites", + "label": "Favorites", + "description": "Favorites linked to the opportunity", + "icon": "IconHeart", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "a4675608-4589-4265-b929-5403a8a1fcab", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "favorite", + "namePlural": "favorites", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "d1704978-f9de-4035-a610-31736644825d" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "a4675608-4589-4265-b929-5403a8a1fcab", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "bdc07845-b914-4fb9-bb56-55f4a074a4aa", + "name": "favorites" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "d1704978-f9de-4035-a610-31736644825d", + "name": "opportunity" + } + } + }, + { + "__typename": "field", + "id": "a51b5287-c5e3-41e3-81b2-d728cc152ae8", + "type": "RELATION", + "name": "taskTargets", + "label": "Tasks", + "description": "Tasks tied to the opportunity", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "516c6882-531f-42de-bc49-da3633ae8990", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "taskTarget", + "namePlural": "taskTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "8996de70-0e13-426e-9a34-1453c2dc7eca" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "516c6882-531f-42de-bc49-da3633ae8990", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "a51b5287-c5e3-41e3-81b2-d728cc152ae8", + "name": "taskTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "8996de70-0e13-426e-9a34-1453c2dc7eca", + "name": "opportunity" + } + } + }, + { + "__typename": "field", + "id": "26b60af3-55a1-4483-aff7-46d43a558846", + "type": "RELATION", + "name": "noteTargets", + "label": "Notes", + "description": "Notes tied to the opportunity", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "4765887f-b385-4514-9552-5ed4bd471a52", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "noteTarget", + "namePlural": "noteTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "5236db98-2a29-4643-90c4-a061a78284c9" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "4765887f-b385-4514-9552-5ed4bd471a52", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "26b60af3-55a1-4483-aff7-46d43a558846", + "name": "noteTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "9265f3a4-5816-49cc-8091-7a122328ecbc", + "nameSingular": "noteTarget", + "namePlural": "noteTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "5236db98-2a29-4643-90c4-a061a78284c9", + "name": "opportunity" + } + } + }, + { + "__typename": "field", + "id": "5ff5942f-fa00-4e12-895c-b8ffc7b2b53e", + "type": "RELATION", + "name": "timelineActivities", + "label": "Timeline Activities", + "description": "Timeline Activities linked to the opportunity.", + "icon": "IconTimelineEvent", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "2d8bf819-91c8-43a1-afe1-329215c64fab", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "607ab295-963c-4f89-9b45-7f3f1c31d364" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "2d8bf819-91c8-43a1-afe1-329215c64fab", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "5ff5942f-fa00-4e12-895c-b8ffc7b2b53e", + "name": "timelineActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "607ab295-963c-4f89-9b45-7f3f1c31d364", + "name": "opportunity" + } + } + }, + { + "__typename": "field", + "id": "bbfb3d9a-44b6-4e15-983b-01c345aadb56", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "message", + "namePlural": "messages", + "labelSingular": "Message", + "labelPlural": "Messages", + "description": "Message", + "icon": "IconMessage", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "f3bc21aa-63b2-4ac1-9bf4-3b8cae683741", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "2f04de1f-1bd3-4115-b40b-993e9fdaa6e7", + "type": "RELATION", + "name": "messageChannelMessageAssociations", + "label": "Message Channel Association", + "description": "Messages from the channel.", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "d3122ddd-2967-4198-b1a2-2821b2cf62ee", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "baca6fdd-07ef-469c-8b9d-364d2c22eb34" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d3122ddd-2967-4198-b1a2-2821b2cf62ee", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "nameSingular": "message", + "namePlural": "messages" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "2f04de1f-1bd3-4115-b40b-993e9fdaa6e7", + "name": "messageChannelMessageAssociations" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "baca6fdd-07ef-469c-8b9d-364d2c22eb34", + "name": "message" + } + } + }, + { + "__typename": "field", + "id": "cd29c4b5-3bf9-4b9a-a1df-a7d50e487501", + "type": "DATE_TIME", + "name": "receivedAt", + "label": "Received At", + "description": "The date the message was received", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "93f89d2e-8075-4f33-8644-9e209bee29ad", + "type": "TEXT", + "name": "headerMessageId", + "label": "Header message Id", + "description": "Message id from the message header", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "70dc8921-fceb-405c-bb8c-bcb9641f3f14", + "type": "SELECT", + "name": "direction", + "label": "Direction", + "description": "Message Direction", + "icon": "IconDirection", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'incoming'", + "options": [ + { + "id": "e31f3d65-af01-4f4d-ad2c-15a329d1ffe2", + "color": "green", + "label": "Incoming", + "value": "incoming", + "position": 0 + }, + { + "id": "cb8eb5f5-0cc5-44dc-bf25-bb97e30ca96e", + "color": "blue", + "label": "Outgoing", + "value": "outgoing", + "position": 1 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "274e4c06-7281-4a14-9ea0-398e01ad0d3d", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "f3bc21aa-63b2-4ac1-9bf4-3b8cae683741", + "type": "TEXT", + "name": "subject", + "label": "Subject", + "description": "Subject", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7fdb6c22-8e61-4674-a743-df09aef2aa2f", + "type": "RELATION", + "name": "messageThread", + "label": "Message Thread Id", + "description": "Message Thread Id", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "b002d1de-e11a-4be7-8f17-e68fe36441e5", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "565bef4e-4f25-45c0-a1c7-090a1f09d0cd", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageThread", + "namePlural": "messageThreads", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "9af0de66-551f-4c2d-ad4a-bdad114aa987" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "b002d1de-e11a-4be7-8f17-e68fe36441e5", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "nameSingular": "message", + "namePlural": "messages" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "7fdb6c22-8e61-4674-a743-df09aef2aa2f", + "name": "messageThread" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "565bef4e-4f25-45c0-a1c7-090a1f09d0cd", + "nameSingular": "messageThread", + "namePlural": "messageThreads" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "9af0de66-551f-4c2d-ad4a-bdad114aa987", + "name": "messages" + } + } + }, + { + "__typename": "field", + "id": "ddb70015-f385-4e2b-9927-31b3d6ee0c1d", + "type": "UUID", + "name": "messageThreadId", + "label": "Message Thread Id id (foreign key)", + "description": "Message Thread Id id foreign key", + "icon": "IconHash", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c85ef2a6-b96f-4eb9-bd54-872a2f6fd8d8", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3eb173ec-f635-40d3-b89f-3a72f95bb232", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "62492454-1575-4137-ab32-860c6970b29d", + "type": "RELATION", + "name": "messageParticipants", + "label": "Message Participants", + "description": "Message Participants", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "85b24729-a5bb-48bb-88cd-0cdb39f14033", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "a890fd3d-9f6c-4c6b-9ff2-72493c000c98" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "85b24729-a5bb-48bb-88cd-0cdb39f14033", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "nameSingular": "message", + "namePlural": "messages" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "62492454-1575-4137-ab32-860c6970b29d", + "name": "messageParticipants" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "b45e1221-6d79-41e5-8b9c-9e566aacd695", + "nameSingular": "messageParticipant", + "namePlural": "messageParticipants" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "a890fd3d-9f6c-4c6b-9ff2-72493c000c98", + "name": "message" + } + } + }, + { + "__typename": "field", + "id": "91ef387c-05e9-4349-8dfb-1c36ef925c4f", + "type": "TEXT", + "name": "text", + "label": "Text", + "description": "Text", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "taskTarget", + "namePlural": "taskTargets", + "labelSingular": "Task Target", + "labelPlural": "Task Targets", + "description": "An task target", + "icon": "IconCheckbox", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "87bb013d-8114-4f41-a46d-614ec2ae16fb", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "48fa26b6-ca6b-468c-b9c4-bf5ea65438e4", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "71f7e43c-10c7-4feb-bacc-ec93923ecb2a", + "type": "RELATION", + "name": "task", + "label": "Task", + "description": "TaskTarget task", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "73f74dcd-5c13-4caf-88f5-450ec331e735", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "task", + "namePlural": "tasks", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "d028be3b-c73d-428e-84a2-e76d5c1d5058" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "73f74dcd-5c13-4caf-88f5-450ec331e735", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "71f7e43c-10c7-4feb-bacc-ec93923ecb2a", + "name": "task" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "d028be3b-c73d-428e-84a2-e76d5c1d5058", + "name": "taskTargets" + } + } + }, + { + "__typename": "field", + "id": "fb93a5d1-830d-4788-9a71-14db2b0042d0", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "TaskTarget person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "87bb013d-8114-4f41-a46d-614ec2ae16fb", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "bb743bd2-1452-4053-94fb-2bb8b7c7fccd", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "TaskTarget company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "ac4e31f0-3daa-4fe8-b1ff-6d1abc0d684e", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "6aadfd7b-33b8-4481-baf7-3b63c055716d" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "ac4e31f0-3daa-4fe8-b1ff-6d1abc0d684e", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "bb743bd2-1452-4053-94fb-2bb8b7c7fccd", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "6aadfd7b-33b8-4481-baf7-3b63c055716d", + "name": "taskTargets" + } + } + }, + { + "__typename": "field", + "id": "ccb227ee-30e7-4c31-bc23-ef7f0e5fc708", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "TaskTarget person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "bd1aae4b-996d-4419-8870-90364605fb4a", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "97ceb237-a8a5-48a7-bfeb-dab65b29214f" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "bd1aae4b-996d-4419-8870-90364605fb4a", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "ccb227ee-30e7-4c31-bc23-ef7f0e5fc708", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "97ceb237-a8a5-48a7-bfeb-dab65b29214f", + "name": "taskTargets" + } + } + }, + { + "__typename": "field", + "id": "c7ebc9e4-5a0c-42fb-a5eb-eda974a81f83", + "type": "UUID", + "name": "opportunityId", + "label": "Opportunity id (foreign key)", + "description": "TaskTarget opportunity id foreign key", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "af536787-039c-4038-98e1-63093b97ed05", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "ce8915d2-c3a3-4cd7-a020-383e1bea0979", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "TaskTarget company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "f7f54354-71f5-48b5-a72e-000ca334d2f3", + "type": "UUID", + "name": "taskId", + "label": "Task id (foreign key)", + "description": "TaskTarget task id foreign key", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8996de70-0e13-426e-9a34-1453c2dc7eca", + "type": "RELATION", + "name": "opportunity", + "label": "Opportunity", + "description": "TaskTarget opportunity", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "516c6882-531f-42de-bc49-da3633ae8990", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "a51b5287-c5e3-41e3-81b2-d728cc152ae8" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "516c6882-531f-42de-bc49-da3633ae8990", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "8996de70-0e13-426e-9a34-1453c2dc7eca", + "name": "opportunity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "a51b5287-c5e3-41e3-81b2-d728cc152ae8", + "name": "taskTargets" + } + } + } + ] + }, + { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "favorite", + "namePlural": "favorites", + "labelSingular": "Favorite", + "labelPlural": "Favorites", + "description": "A favorite", + "icon": "IconHeart", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "a3c81538-fb5b-4bdf-b5ad-9ccc8b02f8a3", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "2389c7c9-c4d0-48d2-8444-59b0ca85c1be", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "Favorite person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "c4d7c4df-c9c2-4919-97da-21fa03fac8bb", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "92e107be-ec6d-401f-8c20-ee1a628ae57c" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c4d7c4df-c9c2-4919-97da-21fa03fac8bb", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "2389c7c9-c4d0-48d2-8444-59b0ca85c1be", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "92e107be-ec6d-401f-8c20-ee1a628ae57c", + "name": "favorites" + } + } + }, + { + "__typename": "field", + "id": "c3f42381-a945-481c-914c-a69e315e9d0f", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "Favorite company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "754b01f8-d32b-4447-82e9-c9756a893519", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "d1704978-f9de-4035-a610-31736644825d", + "type": "RELATION", + "name": "opportunity", + "label": "Opportunity", + "description": "Favorite opportunity", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "a4675608-4589-4265-b929-5403a8a1fcab", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "bdc07845-b914-4fb9-bb56-55f4a074a4aa" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "a4675608-4589-4265-b929-5403a8a1fcab", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "d1704978-f9de-4035-a610-31736644825d", + "name": "opportunity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "bdc07845-b914-4fb9-bb56-55f4a074a4aa", + "name": "favorites" + } + } + }, + { + "__typename": "field", + "id": "c1c3e041-1f41-4da9-99ed-a579eaa3c871", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "Favorite company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "79195013-edb9-45da-b0ba-6f42a4671bb7", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "8fc67f91-0bea-4a96-889f-80c9a0d464f1" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "79195013-edb9-45da-b0ba-6f42a4671bb7", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "c1c3e041-1f41-4da9-99ed-a579eaa3c871", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "8fc67f91-0bea-4a96-889f-80c9a0d464f1", + "name": "favorites" + } + } + }, + { + "__typename": "field", + "id": "a32a382c-3dc8-4a4c-8e5b-1c500ef958ee", + "type": "UUID", + "name": "workspaceMemberId", + "label": "Workspace Member id (foreign key)", + "description": "Favorite workspace member id foreign key", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cf36f444-35ee-41d5-89be-75eb89299443", + "type": "NUMBER", + "name": "position", + "label": "Position", + "description": "Favorite position", + "icon": "IconList", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": 0, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "5a4920d0-f734-4cd3-b510-7ad0dfd163f1", + "type": "UUID", + "name": "opportunityId", + "label": "Opportunity id (foreign key)", + "description": "Favorite opportunity id foreign key", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "b882275f-2bec-4599-8260-aabbc604204b", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "ab269a4f-7f0e-4d75-a84f-a6028d1c26e9", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "Favorite person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1ff0961a-3f5e-4060-9000-8ff853c527d2", + "type": "RELATION", + "name": "workspaceMember", + "label": "Workspace Member", + "description": "Favorite workspace member", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "ecdb31ed-50d7-4b0a-bbdc-d9929e76ae10", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "0c66c2ce-6037-4306-8e82-dbb50f53516f" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "ecdb31ed-50d7-4b0a-bbdc-d9929e76ae10", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "79957fde-71bc-4c5a-81d8-d567686fd345", + "nameSingular": "favorite", + "namePlural": "favorites" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "1ff0961a-3f5e-4060-9000-8ff853c527d2", + "name": "workspaceMember" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "0c66c2ce-6037-4306-8e82-dbb50f53516f", + "name": "favorites" + } + } + }, + { + "__typename": "field", + "id": "a3c81538-fb5b-4bdf-b5ad-9ccc8b02f8a3", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "6a0f0bac-17de-4e89-85f6-2affb52707b8", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "comment", + "namePlural": "comments", + "labelSingular": "Comment", + "labelPlural": "Comments", + "description": "A comment", + "icon": "IconMessageCircle", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "599ec80b-23ec-4712-bd17-6bbd2c9586b4", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "3010d08c-cc13-4dc6-b506-d1d4befb1e89", + "type": "UUID", + "name": "authorId", + "label": "Author id (foreign key)", + "description": "Comment author id foreign key", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4317a97d-5245-4364-a5a4-3cce09610598", + "type": "RELATION", + "name": "author", + "label": "Author", + "description": "Comment author", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "d1a28400-34f8-4b0c-9924-22f2683fc106", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "622fcdaa-c673-43a5-805b-6509a4cef638" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "d1a28400-34f8-4b0c-9924-22f2683fc106", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "6a0f0bac-17de-4e89-85f6-2affb52707b8", + "nameSingular": "comment", + "namePlural": "comments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "4317a97d-5245-4364-a5a4-3cce09610598", + "name": "author" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "622fcdaa-c673-43a5-805b-6509a4cef638", + "name": "authoredComments" + } + } + }, + { + "__typename": "field", + "id": "7439c8ae-7580-4448-b4eb-af113dabd17e", + "type": "TEXT", + "name": "body", + "label": "Body", + "description": "Comment body", + "icon": "IconLink", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "599ec80b-23ec-4712-bd17-6bbd2c9586b4", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "42d64f12-2338-4973-a3a2-894942d8c52b", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "655d1c76-4d74-45d2-a524-293e78a6005f", + "type": "UUID", + "name": "activityId", + "label": "Activity id (foreign key)", + "description": "Comment activity id foreign key", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "bf18155c-f3d9-4619-a69e-142fb49220b0", + "type": "RELATION", + "name": "activity", + "label": "Activity", + "description": "Comment activity", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "809b3b44-0197-4f92-8db1-dfbc50758fed", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activity", + "namePlural": "activities", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "c2ec3dfc-3dbb-4afc-bc3d-9b997d87f5c6" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "809b3b44-0197-4f92-8db1-dfbc50758fed", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "6a0f0bac-17de-4e89-85f6-2affb52707b8", + "nameSingular": "comment", + "namePlural": "comments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "bf18155c-f3d9-4619-a69e-142fb49220b0", + "name": "activity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "c2ec3dfc-3dbb-4afc-bc3d-9b997d87f5c6", + "name": "comments" + } + } + }, + { + "__typename": "field", + "id": "9f03a98d-1174-414a-aa68-258f07c113de", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "5ee0a5da-753d-46b4-b00f-ec7913406c82", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "webhook", + "namePlural": "webhooks", + "labelSingular": "Webhook", + "labelPlural": "Webhooks", + "description": "A webhook", + "icon": "IconRobot", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "86ef8c38-55c5-4948-862c-9d84854c1865", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "c9414d2c-4965-48cd-ad85-390631eca39f", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "86ef8c38-55c5-4948-862c-9d84854c1865", + "type": "TEXT", + "name": "targetUrl", + "label": "Target Url", + "description": "Webhook target url", + "icon": "IconLink", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7eec7ef2-6f6b-44db-884d-fe4b700a7e9c", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "f1e64e0c-e004-4f5f-9bd8-16a96e23ae98", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "d13b73ea-3d90-4ebc-aee5-91bbfcb9f4d8", + "type": "TEXT", + "name": "operation", + "label": "Operation", + "description": "Webhook operation", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "565bef4e-4f25-45c0-a1c7-090a1f09d0cd", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageThread", + "namePlural": "messageThreads", + "labelSingular": "Message Thread", + "labelPlural": "Message Threads", + "description": "Message Thread", + "icon": "IconMessage", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "92378c4d-6489-486f-a083-7f2053fb025b", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "59008d72-f1fd-4c74-b19d-d9430bc67528", + "type": "RELATION", + "name": "messageChannelMessageAssociations", + "label": "Message Channel Association", + "description": "Messages from the channel", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "6470760e-b463-4566-b75b-9147f27905f5", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "cc892247-0c9b-450b-9bac-7cf4e86eb770" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6470760e-b463-4566-b75b-9147f27905f5", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "565bef4e-4f25-45c0-a1c7-090a1f09d0cd", + "nameSingular": "messageThread", + "namePlural": "messageThreads" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "59008d72-f1fd-4c74-b19d-d9430bc67528", + "name": "messageChannelMessageAssociations" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "cc892247-0c9b-450b-9bac-7cf4e86eb770", + "name": "messageThread" + } + } + }, + { + "__typename": "field", + "id": "1db0717b-dd4a-40e0-9a5a-c03398221270", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9af0de66-551f-4c2d-ad4a-bdad114aa987", + "type": "RELATION", + "name": "messages", + "label": "Messages", + "description": "Messages from the thread.", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "b002d1de-e11a-4be7-8f17-e68fe36441e5", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "message", + "namePlural": "messages", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "7fdb6c22-8e61-4674-a743-df09aef2aa2f" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "b002d1de-e11a-4be7-8f17-e68fe36441e5", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "565bef4e-4f25-45c0-a1c7-090a1f09d0cd", + "nameSingular": "messageThread", + "namePlural": "messageThreads" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "9af0de66-551f-4c2d-ad4a-bdad114aa987", + "name": "messages" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7f2dfa44-2815-4153-b302-82c791b18b68", + "nameSingular": "message", + "namePlural": "messages" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "7fdb6c22-8e61-4674-a743-df09aef2aa2f", + "name": "messageThread" + } + } + }, + { + "__typename": "field", + "id": "a5ddcd04-06d4-4eee-8620-538c5a4d146d", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "92378c4d-6489-486f-a083-7f2053fb025b", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "4ddc69a0-8643-41a8-bba6-aa561723d3af", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "blocklist", + "namePlural": "blocklists", + "labelSingular": "Blocklist", + "labelPlural": "Blocklists", + "description": "Blocklist", + "icon": "IconForbid2", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "59e47eff-40dd-4dc3-89a4-103692c5fb9a", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "6f14fb92-9e04-4f73-ae88-9698aec6aaa2", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e3759ebe-8877-4991-b62e-a497e18cbd62", + "type": "RELATION", + "name": "workspaceMember", + "label": "WorkspaceMember", + "description": "WorkspaceMember", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "efb75db1-7707-4a21-a97b-8e9490ab4378", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "d099d12e-79bd-4787-a5d6-fdef989237be" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "efb75db1-7707-4a21-a97b-8e9490ab4378", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "4ddc69a0-8643-41a8-bba6-aa561723d3af", + "nameSingular": "blocklist", + "namePlural": "blocklists" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "e3759ebe-8877-4991-b62e-a497e18cbd62", + "name": "workspaceMember" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "d099d12e-79bd-4787-a5d6-fdef989237be", + "name": "blocklist" + } + } + }, + { + "__typename": "field", + "id": "59e47eff-40dd-4dc3-89a4-103692c5fb9a", + "type": "TEXT", + "name": "handle", + "label": "Handle", + "description": "Handle", + "icon": "IconAt", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c56d5dd8-e781-49be-a618-ff5cf29828ed", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6c92118a-f11a-49c1-a770-df11496ad2d2", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1e5d4d63-0e4f-4e44-b1d9-60ca3f6410a0", + "type": "UUID", + "name": "workspaceMemberId", + "label": "WorkspaceMember id (foreign key)", + "description": "WorkspaceMember id foreign key", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "4b55fcfc-2caf-4c79-a814-0103a0456896", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "auditLog", + "namePlural": "auditLogs", + "labelSingular": "Audit Log", + "labelPlural": "Audit Logs", + "description": "An audit log of actions performed in the system", + "icon": "IconIconTimelineEvent", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "30780af3-2c4c-4976-ae07-ca5d5bf48449", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "36f4a718-3161-4199-92f3-3c98702f0dd1", + "type": "TEXT", + "name": "objectName", + "label": "Object name", + "description": "Object name", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c2126f0d-8a1c-428c-81c7-98113669920e", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "dba895d0-0046-488e-a4a1-45b3a4c03103", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c10dd917-57e7-4e18-b34f-87fed79e8181", + "type": "UUID", + "name": "workspaceMemberId", + "label": "Workspace Member id (foreign key)", + "description": "Event workspace member id foreign key", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "2cbfee06-fbd5-4b22-a8e3-193a10ebd765", + "type": "UUID", + "name": "recordId", + "label": "Record id", + "description": "Record id", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1b762b97-d598-4387-a0cf-577fdda6ffa5", + "type": "TEXT", + "name": "objectMetadataId", + "label": "Object metadata id", + "description": "Object metadata id", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "16eb4366-d53d-4ff7-a6de-8ba29bf6ea00", + "type": "RELATION", + "name": "workspaceMember", + "label": "Workspace Member", + "description": "Event workspace member", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "567b7eea-73fc-4b29-899c-0be663704d4a", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "375850ab-423a-456d-8474-cbc3ec41cce9" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "567b7eea-73fc-4b29-899c-0be663704d4a", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "4b55fcfc-2caf-4c79-a814-0103a0456896", + "nameSingular": "auditLog", + "namePlural": "auditLogs" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "16eb4366-d53d-4ff7-a6de-8ba29bf6ea00", + "name": "workspaceMember" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "375850ab-423a-456d-8474-cbc3ec41cce9", + "name": "auditLogs" + } + } + }, + { + "__typename": "field", + "id": "30780af3-2c4c-4976-ae07-ca5d5bf48449", + "type": "TEXT", + "name": "name", + "label": "Event name", + "description": "Event name/type", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "56723462-1543-460a-b6c7-71e061f4ac97", + "type": "RAW_JSON", + "name": "properties", + "label": "Event details", + "description": "Json value for event details", + "icon": "IconListDetails", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "52f84fa7-3f1b-4469-bff7-02911cdbb68c", + "type": "RAW_JSON", + "name": "context", + "label": "Event context", + "description": "Json object to provide context (user, device, workspace, etc.)", + "icon": "IconListDetails", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "15dffafa-0b3f-419e-b3b3-46061221b93f", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities", + "labelSingular": "Timeline Activity", + "labelPlural": "Timeline Activities", + "description": "Aggregated / filtered event to be displayed on the timeline", + "icon": "IconIconTimelineEvent", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "272487be-ef3b-47b5-9daa-9db4bdb5f589", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "6eb305e6-b4d7-4ba2-906e-ff2c03aa5268", + "type": "RAW_JSON", + "name": "properties", + "label": "Event details", + "description": "Json value for event details", + "icon": "IconListDetails", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8e38d423-8770-47cb-a7ea-340a4660bdae", + "type": "UUID", + "name": "linkedObjectMetadataId", + "label": "Linked Object Metadata Id", + "description": "inked Object Metadata Id", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "607ab295-963c-4f89-9b45-7f3f1c31d364", + "type": "RELATION", + "name": "opportunity", + "label": "Opportunity", + "description": "Event opportunity", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "2d8bf819-91c8-43a1-afe1-329215c64fab", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "5ff5942f-fa00-4e12-895c-b8ffc7b2b53e" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "2d8bf819-91c8-43a1-afe1-329215c64fab", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "607ab295-963c-4f89-9b45-7f3f1c31d364", + "name": "opportunity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "5ff5942f-fa00-4e12-895c-b8ffc7b2b53e", + "name": "timelineActivities" + } + } + }, + { + "__typename": "field", + "id": "272487be-ef3b-47b5-9daa-9db4bdb5f589", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a152dacb-d9bd-4e9d-bfb1-d0c81c956c73", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6d737cbd-f56f-4efb-9a85-085f83486e13", + "type": "RELATION", + "name": "workspaceMember", + "label": "Workspace Member", + "description": "Event workspace member", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "24b2942b-88b5-4191-a55f-1c24bb19b3f8", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "cbfe556c-acc4-47d0-a506-9b1aabdf509a" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "24b2942b-88b5-4191-a55f-1c24bb19b3f8", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "6d737cbd-f56f-4efb-9a85-085f83486e13", + "name": "workspaceMember" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "cbfe556c-acc4-47d0-a506-9b1aabdf509a", + "name": "timelineActivities" + } + } + }, + { + "__typename": "field", + "id": "710f3236-3b79-41b5-8104-49e371a29989", + "type": "UUID", + "name": "linkedRecordId", + "label": "Linked Record id", + "description": "Linked Record id", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "cbed6e40-8d98-453a-86e9-449ce8eab3f1", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "Event person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "e1685c71-fca1-4236-95b8-d8b91f3afe2a", + "type": "DATE_TIME", + "name": "happensAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4cabe1aa-b451-4f10-a92b-97ec4393c1f1", + "type": "UUID", + "name": "noteId", + "label": "Note id (foreign key)", + "description": "Event note id foreign key", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3a7556ad-ab9d-484a-84aa-fe0666bf6d47", + "type": "UUID", + "name": "taskId", + "label": "Task id (foreign key)", + "description": "Event task id foreign key", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "ed1a37f1-7f80-4083-a3ba-22936127fe94", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "Event company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "521201aa-0596-4c0e-a0da-da7d5551591f", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "Event company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "ca5cbff9-b55a-4972-a6e1-eca6e3b43da7", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "d0bdf640-3fcb-46b5-8761-3ebdb016f3b4" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "ca5cbff9-b55a-4972-a6e1-eca6e3b43da7", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "521201aa-0596-4c0e-a0da-da7d5551591f", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "d0bdf640-3fcb-46b5-8761-3ebdb016f3b4", + "name": "timelineActivities" + } + } + }, + { + "__typename": "field", + "id": "176858da-c3b9-41ec-b574-47a464df5a10", + "type": "UUID", + "name": "opportunityId", + "label": "Opportunity id (foreign key)", + "description": "Event opportunity id foreign key", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "923d8ce7-f0d9-4f77-ae0d-aa59d67ec4d5", + "type": "RELATION", + "name": "note", + "label": "Note", + "description": "Event note", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "c88cd230-983b-418c-8b06-ca8334bce78d", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "note", + "namePlural": "notes", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "6b08967c-2aa2-4bd0-a570-3f89cea19bed" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c88cd230-983b-418c-8b06-ca8334bce78d", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "923d8ce7-f0d9-4f77-ae0d-aa59d67ec4d5", + "name": "note" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "nameSingular": "note", + "namePlural": "notes" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "6b08967c-2aa2-4bd0-a570-3f89cea19bed", + "name": "timelineActivities" + } + } + }, + { + "__typename": "field", + "id": "10ba73d9-6d51-4bf1-b532-b447fe1acd79", + "type": "RELATION", + "name": "task", + "label": "Task", + "description": "Event task", + "icon": "IconTargetArrow", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "9ee8ab5b-8377-4437-a60d-b138181ad4e1", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "task", + "namePlural": "tasks", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "7e009f35-8b25-401e-ac8b-76045aa60867" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "9ee8ab5b-8377-4437-a60d-b138181ad4e1", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "10ba73d9-6d51-4bf1-b532-b447fe1acd79", + "name": "task" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "7e009f35-8b25-401e-ac8b-76045aa60867", + "name": "timelineActivities" + } + } + }, + { + "__typename": "field", + "id": "07909ab0-cc9a-4a4d-ab31-d7426728c60c", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "Event person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "631d4fb4-82b7-46af-be99-39f115256634", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "e0158d3b-2ccf-4d97-a467-7a1d055b49e7" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "631d4fb4-82b7-46af-be99-39f115256634", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "07909ab0-cc9a-4a4d-ab31-d7426728c60c", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "e0158d3b-2ccf-4d97-a467-7a1d055b49e7", + "name": "timelineActivities" + } + } + }, + { + "__typename": "field", + "id": "dffb9429-0501-415e-96c0-94f333eb1124", + "type": "UUID", + "name": "workspaceMemberId", + "label": "Workspace Member id (foreign key)", + "description": "Event workspace member id foreign key", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6b447f58-3d4d-4fcc-8e99-ba7e4c479dcb", + "type": "TEXT", + "name": "linkedRecordCachedName", + "label": "Linked Record cached name", + "description": "Cached record name", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "61d37e96-fbea-4ebe-9f31-95b912abefeb", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "77c9f5eb-67a0-422b-bb13-36146e31df93", + "type": "TEXT", + "name": "name", + "label": "Event name", + "description": "Event name", + "icon": "IconAbc", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants", + "labelSingular": "Calendar event participant", + "labelPlural": "Calendar event participants", + "description": "Calendar event participants", + "icon": "IconCalendar", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "20d85d6f-6903-48cc-b86b-9fcc257eb0b0", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "ddda093d-12d3-4c2b-b82b-e5467c5b2d26", + "type": "SELECT", + "name": "responseStatus", + "label": "Response Status", + "description": "Response Status", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'NEEDS_ACTION'", + "options": [ + { + "id": "86b73c32-7cf9-433f-bc3a-8e7ce7d33e4a", + "color": "orange", + "label": "Needs Action", + "value": "NEEDS_ACTION", + "position": 0 + }, + { + "id": "71b087b9-38a0-44e2-a70a-1e79d74a2dd1", + "color": "red", + "label": "Declined", + "value": "DECLINED", + "position": 1 + }, + { + "id": "3877b415-4bf1-4d76-abd5-38057ad03de1", + "color": "yellow", + "label": "Tentative", + "value": "TENTATIVE", + "position": 2 + }, + { + "id": "db836204-d807-472e-bafc-5265465b950e", + "color": "green", + "label": "Accepted", + "value": "ACCEPTED", + "position": 3 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6cdc8d2b-243e-4dd4-b95a-4560a2876b30", + "type": "RELATION", + "name": "calendarEvent", + "label": "Event ID", + "description": "Event ID", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "14d1a448-3743-45c4-a8bb-944d1fd6a7e9", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "be1e7136-6dbe-4cd8-9c39-48b567eb927b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "calendarEvent", + "namePlural": "calendarEvents", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "4a66544b-9e04-4de5-96d7-db59e46266cd" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "14d1a448-3743-45c4-a8bb-944d1fd6a7e9", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "6cdc8d2b-243e-4dd4-b95a-4560a2876b30", + "name": "calendarEvent" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "be1e7136-6dbe-4cd8-9c39-48b567eb927b", + "nameSingular": "calendarEvent", + "namePlural": "calendarEvents" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "4a66544b-9e04-4de5-96d7-db59e46266cd", + "name": "calendarEventParticipants" + } + } + }, + { + "__typename": "field", + "id": "0d4bca4f-2ac2-4b20-9cc8-a48e790c91f3", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "ee538146-581f-45ac-8e50-46f0581e8664", + "type": "BOOLEAN", + "name": "isOrganizer", + "label": "Is Organizer", + "description": "Is Organizer", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": false, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3e2d6542-c27a-46dd-8093-6ef5ab6e58c0", + "type": "RELATION", + "name": "workspaceMember", + "label": "Workspace Member", + "description": "Workspace Member", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "41502f94-3354-4a6f-95a3-0029ecc1f765", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "36029525-7e87-426f-b809-2b44b2a0e707" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "41502f94-3354-4a6f-95a3-0029ecc1f765", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "3e2d6542-c27a-46dd-8093-6ef5ab6e58c0", + "name": "workspaceMember" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "36029525-7e87-426f-b809-2b44b2a0e707", + "name": "calendarEventParticipants" + } + } + }, + { + "__typename": "field", + "id": "4359b7ff-37de-458c-bcc1-e31efc46872d", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "82e6f5a4-a427-4e09-8560-2ab1519930f2", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "2b8670a5-31da-46e1-83d3-81f0656bd00f", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "Person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "70fa8b61-e6cf-4df4-bafc-a56d5e95aa47", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "4b9729f5-c820-4b2c-854a-e463cf9df0b9" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "70fa8b61-e6cf-4df4-bafc-a56d5e95aa47", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2fa80836-4098-4466-9a91-9c84fbeae04d", + "nameSingular": "calendarEventParticipant", + "namePlural": "calendarEventParticipants" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "2b8670a5-31da-46e1-83d3-81f0656bd00f", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "4b9729f5-c820-4b2c-854a-e463cf9df0b9", + "name": "calendarEventParticipants" + } + } + }, + { + "__typename": "field", + "id": "71215f10-55a7-4788-acb3-7edd527c7aeb", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "Person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a85f4356-7344-4ca9-ab92-f69ea3aa72fe", + "type": "UUID", + "name": "calendarEventId", + "label": "Event ID id (foreign key)", + "description": "Event ID id foreign key", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "57ec9d4a-fe19-4302-9973-238dfc0138c0", + "type": "UUID", + "name": "workspaceMemberId", + "label": "Workspace Member id (foreign key)", + "description": "Workspace Member id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3e80ff82-5719-4bef-b857-db82bd8c4971", + "type": "TEXT", + "name": "displayName", + "label": "Display Name", + "description": "Display Name", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "20d85d6f-6903-48cc-b86b-9fcc257eb0b0", + "type": "TEXT", + "name": "handle", + "label": "Handle", + "description": "Handle", + "icon": "IconMail", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "2ef99ca9-5081-4828-8abc-3d77462ba153", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "viewSort", + "namePlural": "viewSorts", + "labelSingular": "View Sort", + "labelPlural": "View Sorts", + "description": "(System) View Sorts", + "icon": "IconArrowsSort", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "80eb887c-9345-431e-bd7e-9f023ff9be74", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "4afd3d50-8612-4686-986e-3447012342de", + "type": "UUID", + "name": "fieldMetadataId", + "label": "Field Metadata Id", + "description": "View Sort target field", + "icon": "IconTag", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "80eb887c-9345-431e-bd7e-9f023ff9be74", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "af644e6f-d2f1-46cb-8f13-6116dbedaae4", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "80791468-ce47-44bb-a204-875e6572bf8a", + "type": "UUID", + "name": "viewId", + "label": "View id (foreign key)", + "description": "View Sort related view id foreign key", + "icon": "IconLayoutCollage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "dc0cca47-45ff-42c8-bc7b-69531bfccb62", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "60f8182b-9a55-4ba9-b7c2-b92979914cc5", + "type": "RELATION", + "name": "view", + "label": "View", + "description": "View Sort related view", + "icon": "IconLayoutCollage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "92560ff2-bdf7-4780-a604-d2a8a219bbb7", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "view", + "namePlural": "views", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "9e47a3a1-219c-47d3-8cc1-d9f73b21c36e" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "92560ff2-bdf7-4780-a604-d2a8a219bbb7", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2ef99ca9-5081-4828-8abc-3d77462ba153", + "nameSingular": "viewSort", + "namePlural": "viewSorts" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "60f8182b-9a55-4ba9-b7c2-b92979914cc5", + "name": "view" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "a225b6be-4d7b-481a-8c2a-e46b931747fb", + "nameSingular": "view", + "namePlural": "views" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "9e47a3a1-219c-47d3-8cc1-d9f73b21c36e", + "name": "viewSorts" + } + } + }, + { + "__typename": "field", + "id": "dbcd11a5-fabb-4371-ba17-883abd8624d6", + "type": "TEXT", + "name": "direction", + "label": "Direction", + "description": "View Sort direction", + "icon": null, + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'asc'", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "labelSingular": "Attachment", + "labelPlural": "Attachments", + "description": "An attachment", + "icon": "IconFileImport", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "9b3b269c-6bf3-48db-8a0f-2516e6b4dcd0", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "dd8e7902-d8a5-4644-a1eb-ac107c160467", + "type": "RELATION", + "name": "note", + "label": "Note", + "description": "Attachment note", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "c69cedf9-6a42-4c2c-b7a4-d882cb3e8951", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "note", + "namePlural": "notes", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "2a485f0e-8538-4753-98bf-4419cb4f405c" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c69cedf9-6a42-4c2c-b7a4-d882cb3e8951", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "dd8e7902-d8a5-4644-a1eb-ac107c160467", + "name": "note" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "de388042-5091-42bd-80c7-eb6bd2b13669", + "nameSingular": "note", + "namePlural": "notes" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "2a485f0e-8538-4753-98bf-4419cb4f405c", + "name": "attachments" + } + } + }, + { + "__typename": "field", + "id": "c2db4c8f-3ea8-4e1f-be07-f9fbee6efa0c", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3a89284d-8eaa-4b83-8b2f-b11d8f725301", + "type": "RELATION", + "name": "opportunity", + "label": "Opportunity", + "description": "Attachment opportunity", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "c8bb21af-7e5d-440c-ad6d-ee2fb83dc411", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "opportunity", + "namePlural": "opportunities", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "37f365ff-5669-4da4-927e-f6c6d7cfb05e" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c8bb21af-7e5d-440c-ad6d-ee2fb83dc411", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "3a89284d-8eaa-4b83-8b2f-b11d8f725301", + "name": "opportunity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "7faca30e-ebfd-4ef0-b34a-a17d8a4fd35b", + "nameSingular": "opportunity", + "namePlural": "opportunities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "37f365ff-5669-4da4-927e-f6c6d7cfb05e", + "name": "attachments" + } + } + }, + { + "__typename": "field", + "id": "9c06ea1f-a01d-41f2-be4d-c754704b587c", + "type": "UUID", + "name": "taskId", + "label": "Task id (foreign key)", + "description": "Attachment task id foreign key", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "287c0e7f-deb2-47a3-8166-5dff33c2c641", + "type": "TEXT", + "name": "type", + "label": "Type", + "description": "Attachment type", + "icon": "IconList", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a10c6c62-1a0a-4ad8-871a-b6b1a665f855", + "type": "UUID", + "name": "companyId", + "label": "Company id (foreign key)", + "description": "Attachment company id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "01266ea8-83c7-4aa4-993b-1545bbe2051a", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9e4e615f-9e7b-474c-b3eb-ca65c05dad8e", + "type": "RELATION", + "name": "person", + "label": "Person", + "description": "Attachment person", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "c4c8361f-f03f-43c6-b63c-c578f8781912", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "person", + "namePlural": "people", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "d052cd42-e48f-4323-8487-50eee4d86deb" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "c4c8361f-f03f-43c6-b63c-c578f8781912", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "9e4e615f-9e7b-474c-b3eb-ca65c05dad8e", + "name": "person" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "8f92ea2a-4028-4031-be6d-9c93b0873dbb", + "nameSingular": "person", + "namePlural": "people" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "d052cd42-e48f-4323-8487-50eee4d86deb", + "name": "attachments" + } + } + }, + { + "__typename": "field", + "id": "f3aaaac3-3c34-4a41-989d-66a8482efe63", + "type": "UUID", + "name": "activityId", + "label": "Activity id (foreign key)", + "description": "Attachment activity id foreign key", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "de7e9513-657a-4f0a-a1d5-3d5357520696", + "type": "RELATION", + "name": "author", + "label": "Author", + "description": "Attachment author", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "a5a4f416-659d-42e0-b10d-34e3f8b5b170", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "e5e3fb6d-b04c-43be-b3d0-dad2aabaf6fb" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "a5a4f416-659d-42e0-b10d-34e3f8b5b170", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "de7e9513-657a-4f0a-a1d5-3d5357520696", + "name": "author" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "e5e3fb6d-b04c-43be-b3d0-dad2aabaf6fb", + "name": "authoredAttachments" + } + } + }, + { + "__typename": "field", + "id": "b99216e8-0fa1-400d-9be4-afb68faf8511", + "type": "UUID", + "name": "authorId", + "label": "Author id (foreign key)", + "description": "Attachment author id foreign key", + "icon": "IconCircleUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6d0c80a7-f91b-4988-9278-b844ff765e59", + "type": "UUID", + "name": "opportunityId", + "label": "Opportunity id (foreign key)", + "description": "Attachment opportunity id foreign key", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "83f7ed8c-0132-43d8-80d5-829c4d02368f", + "type": "RELATION", + "name": "activity", + "label": "Activity", + "description": "Attachment activity", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "b693b22a-26d0-4965-b796-515133751128", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "activity", + "namePlural": "activities", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "dc07c3da-fa53-4a1c-8fb6-619673a1c928" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "b693b22a-26d0-4965-b796-515133751128", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "83f7ed8c-0132-43d8-80d5-829c4d02368f", + "name": "activity" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e5933d8f-fb3f-4349-b640-85923e82b11d", + "nameSingular": "activity", + "namePlural": "activities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "dc07c3da-fa53-4a1c-8fb6-619673a1c928", + "name": "attachments" + } + } + }, + { + "__typename": "field", + "id": "d01410a7-a992-4929-a989-0ce325c8f185", + "type": "UUID", + "name": "personId", + "label": "Person id (foreign key)", + "description": "Attachment person id foreign key", + "icon": "IconUser", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1c1a76ce-7291-4198-a626-3cf405f3c237", + "type": "RELATION", + "name": "task", + "label": "Task", + "description": "Attachment task", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "083b44f8-b354-4e36-a760-ae1c60c35f92", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "task", + "namePlural": "tasks", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "25739a43-3e60-4fb1-834e-ef0a13a04499" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "083b44f8-b354-4e36-a760-ae1c60c35f92", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "1c1a76ce-7291-4198-a626-3cf405f3c237", + "name": "task" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "25739a43-3e60-4fb1-834e-ef0a13a04499", + "name": "attachments" + } + } + }, + { + "__typename": "field", + "id": "92198599-f3ba-4f21-9e9b-e71766ba8289", + "type": "RELATION", + "name": "company", + "label": "Company", + "description": "Attachment company", + "icon": "IconBuildingSkyscraper", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "b97472b9-8873-4b5c-a400-82a6075c8a98", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "company", + "namePlural": "companies", + "isSystem": false, + "isRemote": false + }, + "fromFieldMetadataId": "aff246a7-7e60-49d9-aaf3-4b2dad05c862" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "b97472b9-8873-4b5c-a400-82a6075c8a98", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "92198599-f3ba-4f21-9e9b-e71766ba8289", + "name": "company" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "efe58182-ad08-44d0-baa6-fcca016b2341", + "nameSingular": "company", + "namePlural": "companies" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "aff246a7-7e60-49d9-aaf3-4b2dad05c862", + "name": "attachments" + } + } + }, + { + "__typename": "field", + "id": "9969a558-4d6f-4c2f-a8da-b1f75808f305", + "type": "TEXT", + "name": "fullPath", + "label": "Full path", + "description": "Attachment full path", + "icon": "IconLink", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "84b09935-0717-41d4-8ccc-5500623d4729", + "type": "UUID", + "name": "noteId", + "label": "Note id (foreign key)", + "description": "Attachment note id foreign key", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9b3b269c-6bf3-48db-8a0f-2516e6b4dcd0", + "type": "TEXT", + "name": "name", + "label": "Name", + "description": "Attachment name", + "icon": "IconFileUpload", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "abb9c80a-272f-4bbd-ab32-2c7a1c8562de", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "task", + "namePlural": "tasks", + "labelSingular": "Task", + "labelPlural": "Tasks", + "description": "A task", + "icon": "IconCheckbox", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "0080d59f-1930-4dbb-8f81-b8e1854eda9c", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "5b1537b8-774e-438f-858d-600c696be9f8", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "4f906e64-1dad-4ef2-bfa0-869059198469", + "type": "SELECT", + "name": "status", + "label": "Status", + "description": "Task status", + "icon": "IconCheck", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'TODO'", + "options": [ + { + "id": "2ac5360f-d5f3-42e4-97ee-11890e46135c", + "color": "sky", + "label": "To do", + "value": "TODO", + "position": 0 + }, + { + "id": "dac89bcd-430b-423d-a2d4-e3895051637d", + "color": "purple", + "label": "In progress", + "value": "IN_PROGESS", + "position": 1 + }, + { + "id": "9e773792-c960-4d77-b52e-72dd34bcf8b9", + "color": "green", + "label": "Done", + "value": "DONE", + "position": 1 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1e8a3fe6-cb73-4ddd-8c6a-b942603bdb57", + "type": "RICH_TEXT", + "name": "body", + "label": "Body", + "description": "Task body", + "icon": "IconFilePencil", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "31988450-eef5-4668-9def-626c889c6485", + "type": "RELATION", + "name": "assignee", + "label": "Assignee", + "description": "Task assignee", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "6d8f43e5-07f4-4f8c-bbfe-5b25b8a36442", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "0d3f0eb2-c112-497d-b68f-aceab6c81eb6" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "6d8f43e5-07f4-4f8c-bbfe-5b25b8a36442", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "31988450-eef5-4668-9def-626c889c6485", + "name": "assignee" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "fe576d51-e8b9-4089-936f-28579786dee0", + "nameSingular": "workspaceMember", + "namePlural": "workspaceMembers" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "0d3f0eb2-c112-497d-b68f-aceab6c81eb6", + "name": "assignedTasks" + } + } + }, + { + "__typename": "field", + "id": "25739a43-3e60-4fb1-834e-ef0a13a04499", + "type": "RELATION", + "name": "attachments", + "label": "Attachments", + "description": "Task attachments", + "icon": "IconFileImport", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "083b44f8-b354-4e36-a760-ae1c60c35f92", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "attachment", + "namePlural": "attachments", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "1c1a76ce-7291-4198-a626-3cf405f3c237" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "083b44f8-b354-4e36-a760-ae1c60c35f92", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "25739a43-3e60-4fb1-834e-ef0a13a04499", + "name": "attachments" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "2c95a8c8-c8da-480a-9ed5-bfe0b91bd27b", + "nameSingular": "attachment", + "namePlural": "attachments" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "1c1a76ce-7291-4198-a626-3cf405f3c237", + "name": "task" + } + } + }, + { + "__typename": "field", + "id": "7e009f35-8b25-401e-ac8b-76045aa60867", + "type": "RELATION", + "name": "timelineActivities", + "label": "Timeline Activities", + "description": "Timeline Activities linked to the task.", + "icon": "IconTimelineEvent", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "9ee8ab5b-8377-4437-a60d-b138181ad4e1", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "10ba73d9-6d51-4bf1-b532-b447fe1acd79" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "9ee8ab5b-8377-4437-a60d-b138181ad4e1", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "7e009f35-8b25-401e-ac8b-76045aa60867", + "name": "timelineActivities" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "3bf7c0ab-dbe7-4224-bf5a-0c9c53902424", + "nameSingular": "timelineActivity", + "namePlural": "timelineActivities" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "10ba73d9-6d51-4bf1-b532-b447fe1acd79", + "name": "task" + } + } + }, + { + "__typename": "field", + "id": "d028be3b-c73d-428e-84a2-e76d5c1d5058", + "type": "RELATION", + "name": "taskTargets", + "label": "Targets", + "description": "Task targets", + "icon": "IconCheckbox", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "73f74dcd-5c13-4caf-88f5-450ec331e735", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "taskTarget", + "namePlural": "taskTargets", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "71f7e43c-10c7-4feb-bacc-ec93923ecb2a" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "73f74dcd-5c13-4caf-88f5-450ec331e735", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "21c37514-7921-49fb-9a95-fcb329a3e392", + "nameSingular": "task", + "namePlural": "tasks" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "d028be3b-c73d-428e-84a2-e76d5c1d5058", + "name": "taskTargets" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "79fe1191-5c16-4c86-a80c-24fe6ef607f1", + "nameSingular": "taskTarget", + "namePlural": "taskTargets" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "71f7e43c-10c7-4feb-bacc-ec93923ecb2a", + "name": "task" + } + } + }, + { + "__typename": "field", + "id": "5d013b1d-60ed-4d4e-b57d-d01eeec0949d", + "type": "DATE_TIME", + "name": "dueAt", + "label": "Due Date", + "description": "Task due date", + "icon": "IconCalendarEvent", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6a828bd6-112f-431f-90ff-70344e1c3501", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "bce67a66-73df-4c75-a8fe-d8e82358b8c0", + "type": "UUID", + "name": "assigneeId", + "label": "Assignee id (foreign key)", + "description": "Task assignee id foreign key", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "959a681c-ebaa-457f-8354-841acb032bf7", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "0080d59f-1930-4dbb-8f81-b8e1854eda9c", + "type": "TEXT", + "name": "title", + "label": "Title", + "description": "Task title", + "icon": "IconNotes", + "isCustom": false, + "isActive": true, + "isSystem": false, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7c8f1b0c-2377-427c-bb0b-7d3d86373e20", + "type": "POSITION", + "name": "position", + "label": "Position", + "description": "Task record position", + "icon": "IconHierarchy2", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + } + ] + }, + { + "__typename": "object", + "id": "10593c25-7116-4ee2-a448-60272e867704", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageChannel", + "namePlural": "messageChannels", + "labelSingular": "Message Channel", + "labelPlural": "Message Channels", + "description": "Message Channels", + "icon": "IconMessage", + "isCustom": false, + "isRemote": false, + "isActive": true, + "isSystem": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "labelIdentifierFieldMetadataId": "5d1886b9-79db-48dc-b23a-443d671ae8a3", + "imageIdentifierFieldMetadataId": null, + "fields": [ + { + "__typename": "field", + "id": "205f3c8a-9c2f-42b6-b4ce-4a457b04a11a", + "type": "SELECT", + "name": "visibility", + "label": "Visibility", + "description": "Visibility", + "icon": "IconEyeglass", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'SHARE_EVERYTHING'", + "options": [ + { + "id": "dbf0b482-cd4c-402a-b28e-8d81645fd19d", + "color": "green", + "label": "Metadata", + "value": "METADATA", + "position": 0 + }, + { + "id": "0c9ed2ee-05c5-40bb-9488-8a1179331a22", + "color": "blue", + "label": "Subject", + "value": "SUBJECT", + "position": 1 + }, + { + "id": "0405ea65-980f-44d4-bfdd-e4e69268b7ce", + "color": "orange", + "label": "Share Everything", + "value": "SHARE_EVERYTHING", + "position": 2 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7121d744-8d47-48e8-9803-5a442ee498c5", + "type": "BOOLEAN", + "name": "isContactAutoCreationEnabled", + "label": "Is Contact Auto Creation Enabled", + "description": "Is Contact Auto Creation Enabled", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": true, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "5d1886b9-79db-48dc-b23a-443d671ae8a3", + "type": "TEXT", + "name": "handle", + "label": "Handle", + "description": "Handle", + "icon": "IconAt", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "fdea3582-e284-4a57-8295-3fa03bcda9c7", + "type": "SELECT", + "name": "syncStage", + "label": "Sync stage", + "description": "Sync stage", + "icon": "IconStatusChange", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'FULL_MESSAGE_LIST_FETCH_PENDING'", + "options": [ + { + "id": "5f884c69-afb5-476b-a3d9-644a781b58af", + "color": "blue", + "label": "Full messages list fetch pending", + "value": "FULL_MESSAGE_LIST_FETCH_PENDING", + "position": 0 + }, + { + "id": "0404a24b-90a2-4c18-bec7-9a20ff06cbb1", + "color": "blue", + "label": "Partial messages list fetch pending", + "value": "PARTIAL_MESSAGE_LIST_FETCH_PENDING", + "position": 1 + }, + { + "id": "17666b2a-b73f-43d0-ab95-228fc9773434", + "color": "orange", + "label": "Messages list fetch ongoing", + "value": "MESSAGE_LIST_FETCH_ONGOING", + "position": 2 + }, + { + "id": "16acc320-4402-403a-b6d2-54afcd61e96c", + "color": "blue", + "label": "Messages import pending", + "value": "MESSAGES_IMPORT_PENDING", + "position": 3 + }, + { + "id": "759b141c-c218-4e82-9a71-f414f495ca5f", + "color": "orange", + "label": "Messages import ongoing", + "value": "MESSAGES_IMPORT_ONGOING", + "position": 4 + }, + { + "id": "b8634eaf-7688-49a3-a23a-9777fb7d5a81", + "color": "red", + "label": "Failed", + "value": "FAILED", + "position": 5 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "9b4daed9-12c3-4761-af10-bf2469fd4b6d", + "type": "DATE_TIME", + "name": "syncStageStartedAt", + "label": "Sync stage started at", + "description": "Sync stage started at", + "icon": "IconHistory", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6ba53985-adbb-4596-bc3d-dcb01c78c962", + "type": "DATE_TIME", + "name": "createdAt", + "label": "Creation date", + "description": "Creation date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "aa3bed9b-c22a-4526-b3e7-fd250c4434b9", + "type": "DATE_TIME", + "name": "syncedAt", + "label": "Last sync date", + "description": "Last sync date", + "icon": "IconHistory", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "974b0515-dc0c-4148-b2ff-618a30ab409a", + "type": "BOOLEAN", + "name": "isSyncEnabled", + "label": "Is Sync Enabled", + "description": "Is Sync Enabled", + "icon": "IconRefresh", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": true, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "988b91db-4154-4b1e-8792-ba46e001294b", + "type": "SELECT", + "name": "contactAutoCreationPolicy", + "label": "Contact auto creation policy", + "description": "Automatically create People records when receiving or sending emails", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'SENT'", + "options": [ + { + "id": "62c08fb6-0468-40ea-9eec-0bdf41055b84", + "color": "green", + "label": "Sent and Received", + "value": "SENT_AND_RECEIVED", + "position": 0 + }, + { + "id": "5fb7c4c3-13ba-4231-a80f-fd4982f493bb", + "color": "blue", + "label": "Sent", + "value": "SENT", + "position": 1 + }, + { + "id": "d355a8b9-4606-477e-99ae-f04822713900", + "color": "red", + "label": "None", + "value": "NONE", + "position": 2 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "375af514-e4c5-4fbd-b386-8f2f288999da", + "type": "RELATION", + "name": "messageChannelMessageAssociations", + "label": "Message Channel Association", + "description": "Messages from the channel.", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": { + "__typename": "relation", + "id": "3033b53c-97c6-44af-9696-de653a17b513", + "relationType": "ONE_TO_MANY", + "toObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations", + "isSystem": true, + "isRemote": false + }, + "toFieldMetadataId": "927eb9ef-c1a8-4453-8a8a-2273ebff07d9" + }, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "3033b53c-97c6-44af-9696-de653a17b513", + "direction": "ONE_TO_MANY", + "sourceObjectMetadata": { + "__typename": "object", + "id": "10593c25-7116-4ee2-a448-60272e867704", + "nameSingular": "messageChannel", + "namePlural": "messageChannels" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "375af514-e4c5-4fbd-b386-8f2f288999da", + "name": "messageChannelMessageAssociations" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "e7853605-2c8f-41e7-bf88-72a2acbd0f02", + "nameSingular": "messageChannelMessageAssociation", + "namePlural": "messageChannelMessageAssociations" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "927eb9ef-c1a8-4453-8a8a-2273ebff07d9", + "name": "messageChannel" + } + } + }, + { + "__typename": "field", + "id": "d89569d4-199d-4205-a9a6-92ee4fea17fd", + "type": "SELECT", + "name": "type", + "label": "Type", + "description": "Channel Type", + "icon": "IconMessage", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "'email'", + "options": [ + { + "id": "3bdf0c5e-ad60-46e1-8bf2-3824705a714c", + "color": "green", + "label": "Email", + "value": "email", + "position": 0 + }, + { + "id": "b11d8f43-0f21-4a23-bde5-4042770da8f7", + "color": "blue", + "label": "SMS", + "value": "sms", + "position": 1 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "3d88ab90-2a74-4506-b620-2ac74ce7d5c7", + "type": "NUMBER", + "name": "throttleFailureCount", + "label": "Throttle Failure Count", + "description": "Throttle Failure Count", + "icon": "IconX", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": 0, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "58f0bec1-4b20-4673-ac0f-767f6d2cf0a3", + "type": "SELECT", + "name": "syncStatus", + "label": "Sync status", + "description": "Sync status", + "icon": "IconStatusChange", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": [ + { + "id": "d1644f32-fc4b-44fb-a258-0329e32159b4", + "color": "yellow", + "label": "Ongoing", + "value": "ONGOING", + "position": 1 + }, + { + "id": "bd5a33b2-fe5b-4eb2-b757-2899816240fe", + "color": "blue", + "label": "Not Synced", + "value": "NOT_SYNCED", + "position": 2 + }, + { + "id": "115d9ecc-1e88-451c-a568-49536227095c", + "color": "green", + "label": "Active", + "value": "ACTIVE", + "position": 3 + }, + { + "id": "8371f797-828b-4802-8888-dfb9d6dd2332", + "color": "red", + "label": "Failed Insufficient Permissions", + "value": "FAILED_INSUFFICIENT_PERMISSIONS", + "position": 4 + }, + { + "id": "edac429d-a08c-40bd-bf97-bc3d1ae7f60d", + "color": "red", + "label": "Failed Unknown", + "value": "FAILED_UNKNOWN", + "position": 5 + } + ], + "relationDefinition": null + }, + { + "__typename": "field", + "id": "7f02464e-070a-433d-b92c-9d649e56aec5", + "type": "UUID", + "name": "connectedAccountId", + "label": "Connected Account id (foreign key)", + "description": "Connected Account id foreign key", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": null, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "6775b782-7854-4ed1-989d-1f7f83b67f3c", + "type": "UUID", + "name": "id", + "label": "Id", + "description": "Id", + "icon": "Icon123", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "uuid", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "a96cf30c-1f7b-4614-a8a9-d89c3900a306", + "type": "RELATION", + "name": "connectedAccount", + "label": "Connected Account", + "description": "Connected Account", + "icon": "IconUserCircle", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": true, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": { + "__typename": "relation", + "id": "198d983d-8caa-4a98-96cc-69ed0d0c7ab7", + "relationType": "ONE_TO_MANY", + "fromObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "dataSourceId": "3d54886d-9b45-4842-a67e-f542cf3f24be", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts", + "isSystem": true, + "isRemote": false + }, + "fromFieldMetadataId": "56ffec90-5645-484b-ac07-4e64aeb4debe" + }, + "defaultValue": null, + "options": null, + "relationDefinition": { + "__typename": "RelationDefinition", + "relationId": "198d983d-8caa-4a98-96cc-69ed0d0c7ab7", + "direction": "MANY_TO_ONE", + "sourceObjectMetadata": { + "__typename": "object", + "id": "10593c25-7116-4ee2-a448-60272e867704", + "nameSingular": "messageChannel", + "namePlural": "messageChannels" + }, + "sourceFieldMetadata": { + "__typename": "field", + "id": "a96cf30c-1f7b-4614-a8a9-d89c3900a306", + "name": "connectedAccount" + }, + "targetObjectMetadata": { + "__typename": "object", + "id": "82351615-9692-4bd7-a13e-75efa8c8516e", + "nameSingular": "connectedAccount", + "namePlural": "connectedAccounts" + }, + "targetFieldMetadata": { + "__typename": "field", + "id": "56ffec90-5645-484b-ac07-4e64aeb4debe", + "name": "messageChannels" + } + } + }, + { + "__typename": "field", + "id": "d64a4731-5b06-47c1-9649-1a69f753a577", + "type": "DATE_TIME", + "name": "updatedAt", + "label": "Update date", + "description": "Update date", + "icon": "IconCalendar", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "now", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "8bde7841-67b3-41ff-b8a3-a0eedfa66e6e", + "type": "TEXT", + "name": "syncCursor", + "label": "Last sync cursor", + "description": "Last sync cursor", + "icon": "IconHistory", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": "''", + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "1101dcbe-1cbb-4b29-8efe-981b42b633ef", + "type": "BOOLEAN", + "name": "excludeGroupEmails", + "label": "Exclude group emails", + "description": "Exclude group emails", + "icon": "IconUsersGroup", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": true, + "options": null, + "relationDefinition": null + }, + { + "__typename": "field", + "id": "c25fc0b3-d3e8-4ad5-b1de-6aace9a384ae", + "type": "BOOLEAN", + "name": "excludeNonProfessionalEmails", + "label": "Exclude non professional emails", + "description": "Exclude non professional emails", + "icon": "IconBriefcase", + "isCustom": false, + "isActive": true, + "isSystem": true, + "isNullable": false, + "createdAt": "2024-07-31T10:44:41.328Z", + "updatedAt": "2024-07-31T10:44:41.328Z", + "fromRelationMetadata": null, + "toRelationMetadata": null, + "defaultValue": true, + "options": null, + "relationDefinition": null + } + ] + } + ]; + + // Todo fix typing here (the backend is not in sync with the frontend) + return mockArray as ObjectMetadataItem[]; }; diff --git a/packages/twenty-front/src/modules/object-metadata/utils/isLabelIdentifierField.ts b/packages/twenty-front/src/modules/object-metadata/utils/isLabelIdentifierField.ts index 06bc0c576..1a40a8767 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/isLabelIdentifierField.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/isLabelIdentifierField.ts @@ -13,7 +13,8 @@ export const isLabelIdentifierField = ({ ObjectMetadataItem, 'labelIdentifierFieldMetadataId' >; -}) => - isDefined(objectMetadataItem.labelIdentifierFieldMetadataId) +}) => { + return isDefined(objectMetadataItem.labelIdentifierFieldMetadataId) ? fieldMetadataItem.id === objectMetadataItem.labelIdentifierFieldMetadataId : fieldMetadataItem.name === DEFAULT_LABEL_IDENTIFIER_FIELD_NAME; +}; diff --git a/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts b/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts index 983741c6c..b9c7ebc91 100644 --- a/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts +++ b/packages/twenty-front/src/modules/object-metadata/utils/mapFieldMetadataToGraphQLQuery.ts @@ -40,6 +40,7 @@ export const mapFieldMetadataToGraphQLQuery = ({ FieldMetadataType.MultiSelect, FieldMetadataType.Position, FieldMetadataType.RawJson, + FieldMetadataType.RichText, ].includes(fieldType); if (fieldIsSimpleValue) { diff --git a/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts b/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts index bd864bc57..0f33f81bc 100644 --- a/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts +++ b/packages/twenty-front/src/modules/object-record/cache/hooks/useGetRecordFromCache.ts @@ -1,5 +1,5 @@ -import { useCallback } from 'react'; import { useApolloClient } from '@apollo/client'; +import { useCallback } from 'react'; import { useRecoilValue } from 'recoil'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; diff --git a/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx b/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx index 94674aa57..db5e7aabd 100644 --- a/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx +++ b/packages/twenty-front/src/modules/object-record/components/RecordChip.tsx @@ -3,9 +3,7 @@ import { AvatarChip, AvatarChipVariant } from 'twenty-ui'; import { getLinkToShowPage } from '@/object-metadata/utils/getLinkToShowPage'; import { useRecordChipData } from '@/object-record/hooks/useRecordChipData'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; -import { isNonEmptyString } from '@sniptt/guards'; -import { MouseEvent } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink'; export type RecordChipProps = { objectNameSingular: string; @@ -20,31 +18,22 @@ export const RecordChip = ({ className, variant, }: RecordChipProps) => { - const navigate = useNavigate(); - const { recordChipData } = useRecordChipData({ objectNameSingular, record, }); - const handleAvatarChipClick = (event: MouseEvent) => { - const linkToShowPage = getLinkToShowPage(objectNameSingular, record); - - if (isNonEmptyString(linkToShowPage)) { - event.stopPropagation(); - navigate(linkToShowPage); - } - }; - return ( - + + {}} + /> + ); }; diff --git a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useUpdateOneRecordMutation.test.tsx b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useUpdateOneRecordMutation.test.tsx index f0ee8b5a0..e847679bc 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useUpdateOneRecordMutation.test.tsx +++ b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useUpdateOneRecordMutation.test.tsx @@ -3,6 +3,7 @@ import { print } from 'graphql'; import { RecoilRoot } from 'recoil'; import { useUpdateOneRecordMutation } from '@/object-record/hooks/useUpdateOneRecordMutation'; +import { normalizeGQLQuery } from '~/utils/normalizeGQLQuery'; const expectedQueryTemplate = ` mutation UpdateOnePerson($idToUpdate: ID!, $input: PersonUpdateInput!) { @@ -32,8 +33,7 @@ mutation UpdateOnePerson($idToUpdate: ID!, $input: PersonUpdateInput!) { avatarUrl companyId } -} -`.replace(/\s/g, ''); +}`; describe('useUpdateOneRecordMutation', () => { it('should return a valid createManyRecordsMutation', () => { @@ -53,11 +53,10 @@ describe('useUpdateOneRecordMutation', () => { expect(updateOneRecordMutation).toBeDefined(); - const printedReceivedQuery = print(updateOneRecordMutation).replace( - /\s/g, - '', - ); + const printedReceivedQuery = print(updateOneRecordMutation); - expect(printedReceivedQuery).toEqual(expectedQueryTemplate); + expect(normalizeGQLQuery(printedReceivedQuery)).toEqual( + normalizeGQLQuery(expectedQueryTemplate), + ); }); }); diff --git a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx index 9765a085f..77bf9bf09 100644 --- a/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx @@ -96,8 +96,8 @@ export const useRecordActionBar = ({ const { deleteTableData } = useDeleteTableData(baseTableDataParams); const handleDeleteClick = useCallback(() => { - deleteTableData(); - }, [deleteTableData]); + deleteTableData(selectedRecordIds); + }, [deleteTableData, selectedRecordIds]); const handleExecuteQuickActionOnClick = useCallback(async () => { callback?.(); diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx index 46ca7d33f..b402d1c59 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx @@ -4,7 +4,7 @@ import { BooleanFieldDisplay } from '@/object-record/record-field/meta-types/dis import { LinksFieldDisplay } from '@/object-record/record-field/meta-types/display/components/LinksFieldDisplay'; import { RatingFieldDisplay } from '@/object-record/record-field/meta-types/display/components/RatingFieldDisplay'; import { RelationFromManyFieldDisplay } from '@/object-record/record-field/meta-types/display/components/RelationFromManyFieldDisplay'; - +import { RichTextFieldDisplay } from '@/object-record/record-field/meta-types/display/components/RichTextFieldDisplay'; import { isFieldIdentifierDisplay } from '@/object-record/record-field/meta-types/display/utils/isFieldIdentifierDisplay'; import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean'; import { isFieldDisplayedAsPhone } from '@/object-record/record-field/types/guards/isFieldDisplayedAsPhone'; @@ -12,6 +12,7 @@ import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldL import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating'; import { isFieldRelationFromManyObjects } from '@/object-record/record-field/types/guards/isFieldRelationFromManyObjects'; import { isFieldRelationToOneObject } from '@/object-record/record-field/types/guards/isFieldRelationToOneObject'; +import { isFieldRichText } from '@/object-record/record-field/types/guards/isFieldRichText'; import { FieldContext } from '../contexts/FieldContext'; import { AddressFieldDisplay } from '../meta-types/display/components/AddressFieldDisplay'; import { ChipFieldDisplay } from '../meta-types/display/components/ChipFieldDisplay'; @@ -93,5 +94,7 @@ export const FieldDisplay = () => { ) : isFieldRating(fieldDefinition) ? ( + ) : isFieldRichText(fieldDefinition) ? ( + ) : null; }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx index 5ac286d7e..bea16402a 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/components/FieldInput.tsx @@ -20,6 +20,8 @@ import { isFieldRelationToOneObject } from '@/object-record/record-field/types/g import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId'; +import { RichTextFieldInput } from '@/object-record/record-field/meta-types/input/components/RichTextFieldInput'; +import { isFieldRichText } from '@/object-record/record-field/types/guards/isFieldRichText'; import { FieldContext } from '../contexts/FieldContext'; import { BooleanFieldInput } from '../meta-types/input/components/BooleanFieldInput'; import { CurrencyFieldInput } from '../meta-types/input/components/CurrencyFieldInput'; @@ -175,6 +177,8 @@ export const FieldInput = ({ onTab={onTab} onShiftTab={onShiftTab} /> + ) : isFieldRichText(fieldDefinition) ? ( + ) : ( <> )} diff --git a/packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldReadOnly.ts b/packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldReadOnly.ts new file mode 100644 index 000000000..192eb843f --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/hooks/useIsFieldReadOnly.ts @@ -0,0 +1,14 @@ +import { useContext } from 'react'; + +import { FieldMetadataType } from '~/generated-metadata/graphql'; +import { FieldContext } from '../contexts/FieldContext'; + +export const useIsFieldReadOnly = () => { + const { fieldDefinition } = useContext(FieldContext); + + return ( + fieldDefinition.type === FieldMetadataType.RichText || + fieldDefinition.metadata.fieldName === 'noteTargets' || + fieldDefinition.metadata.fieldName === 'taskTargets' // TODO: do something cleaner + ); +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/RichTextFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/RichTextFieldDisplay.tsx new file mode 100644 index 000000000..a472772eb --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/RichTextFieldDisplay.tsx @@ -0,0 +1,11 @@ +import { useTextFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useTextFieldDisplay'; +import { getFirstNonEmptyLineOfRichText } from '@/ui/input/editor/utils/getFirstNonEmptyLineOfRichText'; +import { PartialBlock } from '@blocknote/core'; + +export const RichTextFieldDisplay = () => { + const { fieldValue } = useTextFieldDisplay(); + const parsedField = + fieldValue === '' ? null : (JSON.parse(fieldValue) as PartialBlock[]); + + return <>{getFirstNonEmptyLineOfRichText(parsedField)}; +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/RichTextFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/RichTextFieldInput.tsx new file mode 100644 index 000000000..14d34db7c --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/RichTextFieldInput.tsx @@ -0,0 +1,5 @@ +import { RichTextFieldDisplay } from '@/object-record/record-field/meta-types/display/components/RichTextFieldDisplay'; + +export const RichTextFieldInput = () => { + return ; +}; diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts index 830a757c3..4aea03c27 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/FieldMetadata.ts @@ -95,6 +95,11 @@ export type FieldRawJsonMetadata = { placeHolder: string; }; +export type FieldRichTextMetadata = { + objectMetadataNameSingular?: string; + fieldName: string; +}; + export type FieldDefinitionRelationType = | 'FROM_MANY_OBJECTS' | 'FROM_ONE_OBJECT' diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts index c82974a1a..901612a86 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/guards/assertFieldMetadata.ts @@ -61,7 +61,9 @@ type AssertFieldMetadataFunction = < ? FieldAddressMetadata : E extends 'RAW_JSON' ? FieldRawJsonMetadata - : never, + : E extends 'RICH_TEXT' + ? FieldTextMetadata + : never, >( fieldType: E, fieldTypeGuard: ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRichText.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRichText.ts new file mode 100644 index 000000000..2b4c59082 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldRichText.ts @@ -0,0 +1,9 @@ +import { FieldMetadataType } from '~/generated-metadata/graphql'; + +import { FieldDefinition } from '../FieldDefinition'; +import { FieldMetadata, FieldRichTextMetadata } from '../FieldMetadata'; + +export const isFieldRichText = ( + field: Pick, 'type'>, +): field is FieldDefinition => + field.type === FieldMetadataType.RichText; diff --git a/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts b/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts index 5bea46d43..9b0c97b3b 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts @@ -23,6 +23,7 @@ import { isFieldPhone } from '@/object-record/record-field/types/guards/isFieldP import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating'; import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFieldRawJson'; import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation'; +import { isFieldRichText } from '@/object-record/record-field/types/guards/isFieldRichText'; import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { isFieldSelectValue } from '@/object-record/record-field/types/guards/isFieldSelectValue'; import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText'; @@ -54,6 +55,7 @@ export const isFieldValueEmpty = ({ isFieldBoolean(fieldDefinition) || isFieldRelation(fieldDefinition) || isFieldRawJson(fieldDefinition) || + isFieldRichText(fieldDefinition) || isFieldPhone(fieldDefinition) ) { return isValueEmpty(fieldValue); diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useRecordTableRecordGqlFields.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useRecordTableRecordGqlFields.ts index fc8929564..b9b3e12e8 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useRecordTableRecordGqlFields.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useRecordTableRecordGqlFields.ts @@ -34,6 +34,18 @@ export const useRecordTableRecordGqlFields = ({ ), ...identifierQueryFields, position: true, + noteTargets: { + note: { + id: true, + title: true, + }, + }, + taskTargets: { + task: { + id: true, + title: true, + }, + }, }; return recordGqlFields; diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useDeleteTableData.ts b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useDeleteTableData.ts index 8c2fca1b9..2c8e8f6d5 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useDeleteTableData.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/options/hooks/useDeleteTableData.ts @@ -17,13 +17,10 @@ export const useDeleteTableData = ({ objectNameSingular, }); - const { - resetTableRowSelection, - selectedRowIdsSelector, - hasUserSelectedAllRowsState, - } = useRecordTable({ - recordTableId: recordIndexId, - }); + const { resetTableRowSelection, hasUserSelectedAllRowsState } = + useRecordTable({ + recordTableId: recordIndexId, + }); const tableRowIds = useRecoilValue( tableRowIdsComponentState({ @@ -36,18 +33,14 @@ export const useDeleteTableData = ({ }); const { favorites, deleteFavorite } = useFavorites(); - const selectedRowIds = useRecoilValue(selectedRowIdsSelector()); - const hasUserSelectedAllRows = useRecoilValue(hasUserSelectedAllRowsState); - const deleteRecords = async () => { - let recordIdsToDelete = selectedRowIds; - + const deleteRecords = async (recordIdsToDelete: string[]) => { if (hasUserSelectedAllRows) { const allRecordIds = await fetchAllRecordIds(); const unselectedRecordIds = tableRowIds.filter( - (recordId) => !selectedRowIds.includes(recordId), + (recordId) => !recordIdsToDelete.includes(recordId), ); recordIdsToDelete = allRecordIds.filter( diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx index 58b0e0224..4db2eefa8 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/components/RecordShowContainer.tsx @@ -1,8 +1,12 @@ import groupBy from 'lodash.groupby'; import { useRecoilState, useRecoilValue } from 'recoil'; +import { ActivityTargetsInlineCell } from '@/activities/inline-cell/components/ActivityTargetsInlineCell'; +import { Note } from '@/activities/types/Note'; +import { Task } from '@/activities/types/Task'; import { useLabelIdentifierFieldMetadataItem } from '@/object-metadata/hooks/useLabelIdentifierFieldMetadataItem'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { @@ -62,7 +66,7 @@ export const RecordShowContainer = ({ recordLoadingFamilyState(objectRecordId), ); - const [recordFromStore] = useRecoilState( + const [recordFromStore] = useRecoilState( recordStoreFamilyState(objectRecordId), ); @@ -131,90 +135,147 @@ export const RecordShowContainer = ({ : 'inlineFieldMetadataItems', ); + const inlineRelationFieldMetadataItems = relationFieldMetadataItems?.filter( + (fieldMetadataItem) => + (objectNameSingular === CoreObjectNameSingular.Note && + fieldMetadataItem.name === 'noteTargets') || + (objectNameSingular === CoreObjectNameSingular.Task && + fieldMetadataItem.name === 'taskTargets'), + ); + + const boxedRelationFieldMetadataItems = relationFieldMetadataItems?.filter( + (fieldMetadataItem) => + objectNameSingular !== CoreObjectNameSingular.Note && + fieldMetadataItem.name !== 'noteTargets' && + objectNameSingular !== CoreObjectNameSingular.Task && + fieldMetadataItem.name !== 'taskTargets', + ); + const isReadOnly = objectMetadataItem.isRemote; const isMobile = useIsMobile() || isInRightDrawer; const isPrefetchLoading = useIsPrefetchLoading(); - const summary = ( + const summaryCard = isDefined(recordFromStore) ? ( + + + + } + avatarType={recordIdentifier?.avatarType ?? 'rounded'} + onUploadPicture={ + objectNameSingular === 'person' ? onUploadPicture : undefined + } + /> + ) : ( + <> + ); + + const fieldsBox = ( <> {isDefined(recordFromStore) && ( <> - - - - } - avatarType={recordIdentifier?.avatarType ?? 'rounded'} - onUploadPicture={ - objectNameSingular === 'person' ? onUploadPicture : undefined - } - /> {isPrefetchLoading ? ( ) : ( - inlineFieldMetadataItems.map((fieldMetadataItem, index) => ( - - - - )) + <> + {inlineRelationFieldMetadataItems?.map( + (fieldMetadataItem, index) => ( + + + + ), + )} + {inlineFieldMetadataItems?.map((fieldMetadataItem, index) => ( + + + + ))} + )} - {relationFieldMetadataItems?.map((fieldMetadataItem, index) => ( + {boxedRelationFieldMetadataItems?.map((fieldMetadataItem, index) => ( - {!isMobile && summary} + {!isMobile && summaryCard} + {!isMobile && fieldsBox} - {recordFromStore ? ( - - ) : ( - <> - )} + } + fieldsBox={fieldsBox} + loading={isPrefetchLoading || loading || recordLoading} + /> ); diff --git a/packages/twenty-front/src/modules/object-record/record-show/graphql/operations/factories/findOneRecordForShowPageOperationSignatureFactory.ts b/packages/twenty-front/src/modules/object-record/record-show/graphql/operations/factories/findOneRecordForShowPageOperationSignatureFactory.ts index f3ec81af0..510c1f7a5 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/graphql/operations/factories/findOneRecordForShowPageOperationSignatureFactory.ts +++ b/packages/twenty-front/src/modules/object-record/record-show/graphql/operations/factories/findOneRecordForShowPageOperationSignatureFactory.ts @@ -1,10 +1,46 @@ +import { generateActivityTargetMorphFieldKeys } from '@/activities/utils/generateActivityTargetMorphFieldKeys'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { RecordGqlOperationSignatureFactory } from '@/object-record/graphql/types/RecordGqlOperationSignatureFactory'; import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields'; export const buildFindOneRecordForShowPageOperationSignature: RecordGqlOperationSignatureFactory = - ({ objectMetadataItem }: { objectMetadataItem: ObjectMetadataItem }) => ({ + ({ + objectMetadataItem, + objectMetadataItems, + }: { + objectMetadataItem: ObjectMetadataItem; + objectMetadataItems: ObjectMetadataItem[]; + }) => ({ objectNameSingular: objectMetadataItem.nameSingular, variables: {}, - fields: generateDepthOneRecordGqlFields({ objectMetadataItem }), + fields: { + ...generateDepthOneRecordGqlFields({ objectMetadataItem }), + ...(objectMetadataItem.nameSingular === CoreObjectNameSingular.Task + ? { + taskTargets: { + id: true, + __typename: true, + createdAt: true, + updatedAt: true, + note: true, + noteId: true, + ...generateActivityTargetMorphFieldKeys(objectMetadataItems), + }, + } + : {}), + ...(objectMetadataItem.nameSingular === 'Note' + ? { + noteTargets: { + id: true, + __typename: true, + createdAt: true, + updatedAt: true, + task: true, + taskId: true, + ...generateActivityTargetMorphFieldKeys(objectMetadataItems), + }, + } + : {}), + }, }); diff --git a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts index 0455dd6de..667f4eac1 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts +++ b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPage.ts @@ -6,6 +6,7 @@ import { useIcons } from 'twenty-ui'; import { useFavorites } from '@/favorites/hooks/useFavorites'; import { useLabelIdentifierFieldMetadataItem } from '@/object-metadata/hooks/useLabelIdentifierFieldMetadataItem'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; import { buildFindOneRecordForShowPageOperationSignature } from '@/object-record/record-show/graphql/operations/factories/findOneRecordForShowPageOperationSignatureFactory'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; @@ -30,6 +31,7 @@ export const useRecordShowPage = ( } const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular }); + const { objectMetadataItems } = useObjectMetadataItems(); const { labelIdentifierFieldMetadataItem } = useLabelIdentifierFieldMetadataItem({ objectNameSingular }); const { favorites, createFavorite, deleteFavorite } = useFavorites(); @@ -39,7 +41,10 @@ export const useRecordShowPage = ( const { getIcon } = useIcons(); const headerIcon = getIcon(objectMetadataItem?.icon); const FIND_ONE_RECORD_FOR_SHOW_PAGE_OPERATION_SIGNATURE = - buildFindOneRecordForShowPageOperationSignature({ objectMetadataItem }); + buildFindOneRecordForShowPageOperationSignature({ + objectMetadataItem, + objectMetadataItems, + }); const { record, loading } = useFindOneRecord({ objectRecordId, diff --git a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts index 35b43e1be..d252e80ca 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts +++ b/packages/twenty-front/src/modules/object-record/record-show/hooks/useRecordShowPagePagination.ts @@ -1,4 +1,6 @@ /* eslint-disable @nx/workspace-no-navigate-prefer-link */ +import { isNonEmptyString } from '@sniptt/guards'; +import { useState } from 'react'; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; import { useSetRecoilState } from 'recoil'; @@ -10,8 +12,6 @@ import { useRecordIdsFromFindManyCacheRootQuery } from '@/object-record/record-s import { buildShowPageURL } from '@/object-record/record-show/utils/buildShowPageURL'; import { buildIndexTablePageURL } from '@/object-record/record-table/utils/buildIndexTableURL'; import { useQueryVariablesFromActiveFieldsOfViewOrDefaultView } from '@/views/hooks/useQueryVariablesFromActiveFieldsOfViewOrDefaultView'; -import { isNonEmptyString } from '@sniptt/guards'; -import { useState } from 'react'; import { capitalize } from '~/utils/string/capitalize'; export const useRecordShowPagePagination = ( diff --git a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx index 0ce3ef74b..784da33b4 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/record-detail-section/components/RecordDetailRelationSection.tsx @@ -1,6 +1,6 @@ -import { useCallback, useContext } from 'react'; import styled from '@emotion/styled'; import qs from 'qs'; +import { useCallback, useContext } from 'react'; import { useRecoilValue } from 'recoil'; import { IconForbid, IconPencil, IconPlus } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx index 8b56f8d24..9b0d08e43 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFieldInput.tsx @@ -4,13 +4,11 @@ import { FieldInput } from '@/object-record/record-field/components/FieldInput'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent'; import { RecordTableContext } from '@/object-record/record-table/contexts/RecordTableContext'; -import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext'; export const RecordTableCellFieldInput = () => { const { onUpsertRecord, onMoveFocus, onCloseTableCell } = useContext(RecordTableContext); const { entityId, fieldDefinition } = useContext(FieldContext); - const { isReadOnly } = useContext(RecordTableRowContext); const handleEnter: FieldInputEvent = (persistField) => { onUpsertRecord({ @@ -89,7 +87,7 @@ export const RecordTableCellFieldInput = () => { onShiftTab={handleShiftTab} onSubmit={handleSubmit} onTab={handleTab} - isReadOnly={isReadOnly} + isReadOnly={true} /> ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx index 6cc3f7577..29c513857 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx @@ -22,6 +22,7 @@ import { isDefined } from '~/utils/isDefined'; import { TableHotkeyScope } from '../../types/TableHotkeyScope'; +import { useIsFieldReadOnly } from '@/object-record/record-field/hooks/useIsFieldReadOnly'; import { RecordTableCellDisplayContainer } from './RecordTableCellDisplayContainer'; type RecordTableCellSoftFocusModeProps = { @@ -35,7 +36,11 @@ export const RecordTableCellSoftFocusMode = ({ }: RecordTableCellSoftFocusModeProps) => { const { columnIndex } = useContext(RecordTableCellContext); const closeCurrentTableCell = useCloseCurrentTableCellInEditMode(); - const { isReadOnly } = useContext(RecordTableRowContext); + const { isReadOnly: isRowReadOnly } = useContext(RecordTableRowContext); + + const isFieldReadOnly = useIsFieldReadOnly(); + + const isCellReadOnly = isFieldReadOnly || isRowReadOnly; const { openTableCell } = useOpenRecordTableCellFromCell(); @@ -73,7 +78,7 @@ export const RecordTableCellSoftFocusMode = ({ useScopedHotkeys( Key.Enter, () => { - if (!isFieldInputOnly) { + if (!isFieldInputOnly && !isCellReadOnly) { openTableCell(); } else { toggleEditOnlyInput(); @@ -111,7 +116,7 @@ export const RecordTableCellSoftFocusMode = ({ ); const handleClick = () => { - if (!isFieldInputOnly) { + if (!isFieldInputOnly && !isCellReadOnly) { openTableCell(); } }; @@ -143,7 +148,7 @@ export const RecordTableCellSoftFocusMode = ({ isDefined(buttonIcon) && !editModeContentOnly && (!isFirstColumn || !isEmpty) && - !isReadOnly; + !isCellReadOnly; return ( <> diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useUpsertRecord.test.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useUpsertRecord.test.tsx index 2bf6ff27a..f330c7efb 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useUpsertRecord.test.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/__tests__/useUpsertRecord.test.tsx @@ -3,7 +3,9 @@ import { ReactNode } from 'react'; import { RecoilRoot } from 'recoil'; import { createState } from 'twenty-ui'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { textfieldDefinition } from '@/object-record/record-field/__mocks__/fieldDefinitions'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; @@ -53,6 +55,8 @@ const updateOneRecordMock = jest.fn(); createOneRecord: createOneRecordMock, }); +const objectMetadataItems = getObjectMetadataItemsMock(); + const Wrapper = ({ children, pendingRecordIdMockedValue, @@ -64,6 +68,7 @@ const Wrapper = ({ }) => ( { + snapshot.set(objectMetadataItemsState, objectMetadataItems); snapshot.set(pendingRecordIdState, pendingRecordIdMockedValue); snapshot.set(draftValueState, draftValueMockedValue); }} diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUpsertRecord.ts b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUpsertRecord.ts index 553c6aa83..db70da8c9 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUpsertRecord.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/hooks/useUpsertRecord.ts @@ -1,5 +1,7 @@ import { useRecoilCallback } from 'recoil'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { recordFieldInputDraftValueComponentSelector } from '@/object-record/record-field/states/selectors/recordFieldInputDraftValueComponentSelector'; import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState'; @@ -26,6 +28,21 @@ export const useUpsertRecord = ({ fieldName: string, recordTableId: string, ) => { + const objectMetadataItems = snapshot + .getLoadable(objectMetadataItemsState) + .getValue(); + + const foundObjectMetadataItem = objectMetadataItems.find( + (item) => item.nameSingular === objectNameSingular, + ); + + if (!foundObjectMetadataItem) { + throw new Error('Object metadata item cannot be found'); + } + + const labelIdentifierFieldMetadataItem = + getLabelIdentifierFieldMetadataItem(foundObjectMetadataItem); + const tableScopeId = getScopeIdFromComponentId(recordTableId); const recordTablePendingRecordIdState = extractComponentState( @@ -51,14 +68,14 @@ export const useUpsertRecord = ({ if (isDefined(recordTablePendingRecordId) && isDefined(draftValue)) { createOneRecord({ id: recordTablePendingRecordId, - name: draftValue, + [labelIdentifierFieldMetadataItem?.name ?? 'name']: draftValue, position: 'first', }); } else if (!recordTablePendingRecordId) { persistField(); } }, - [createOneRecord], + [createOneRecord, objectNameSingular], ); return { upsertRecord }; diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/components/ActivityTargetInlineCellEditModeMultiRecordsEffect.tsx b/packages/twenty-front/src/modules/object-record/relation-picker/components/ActivityTargetInlineCellEditModeMultiRecordsEffect.tsx index 440bab3c7..425877c20 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/components/ActivityTargetInlineCellEditModeMultiRecordsEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/relation-picker/components/ActivityTargetInlineCellEditModeMultiRecordsEffect.tsx @@ -7,6 +7,7 @@ import { } from 'recoil'; import { useObjectRecordMultiSelectScopedStates } from '@/activities/hooks/useObjectRecordMultiSelectScopedStates'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { objectRecordMultiSelectComponentFamilyState } from '@/object-record/record-field/states/objectRecordMultiSelectComponentFamilyState'; import { useRelationPickerScopedStates } from '@/object-record/relation-picker/hooks/internal/useRelationPickerScopedStates'; import { @@ -48,9 +49,14 @@ export const ActivityTargetInlineCellEditModeMultiRecordsEffect = ({ const relationPickerSearchFilter = useRecoilValue( relationPickerSearchFilterState, ); + const { filteredSelectedObjectRecords, loading, objectRecordsToSelect } = useMultiObjectSearch({ searchFilterValue: relationPickerSearchFilter, + excludedObjects: [ + CoreObjectNameSingular.Task, + CoreObjectNameSingular.Note, + ], selectedObjectRecordIds, excludedObjectRecordIds: [], limit: 10, diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearch.ts b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearch.ts index b91c00084..8651e7f42 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearch.ts +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearch.ts @@ -1,3 +1,4 @@ +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery } from '@/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndSelectedItemsQuery'; import { useMultiObjectSearchMatchesSearchFilterAndToSelectQuery } from '@/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery'; @@ -30,11 +31,13 @@ export const useMultiObjectSearch = ({ selectedObjectRecordIds, limit, excludedObjectRecordIds = [], + excludedObjects, }: { searchFilterValue: string; selectedObjectRecordIds: SelectedObjectRecordId[]; limit?: number; excludedObjectRecordIds?: SelectedObjectRecordId[]; + excludedObjects?: CoreObjectNameSingular[]; }): MultiObjectSearch => { const { selectedObjectRecords, selectedObjectRecordsLoading } = useMultiObjectSearchSelectedItemsQuery({ @@ -54,6 +57,7 @@ export const useMultiObjectSearch = ({ toSelectAndMatchesSearchFilterObjectRecords, toSelectAndMatchesSearchFilterObjectRecordsLoading, } = useMultiObjectSearchMatchesSearchFilterAndToSelectQuery({ + excludedObjects, excludedObjectRecordIds, searchFilterValue, selectedObjectRecordIds, diff --git a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts index 8d3b4e076..607eef180 100644 --- a/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts +++ b/packages/twenty-front/src/modules/object-record/relation-picker/hooks/useMultiObjectSearchMatchesSearchFilterAndToSelectQuery.ts @@ -2,6 +2,7 @@ import { useQuery } from '@apollo/client'; import { useRecoilValue } from 'recoil'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { EMPTY_QUERY } from '@/object-record/constants/EmptyQuery'; import { useGenerateCombinedFindManyRecordsQuery } from '@/object-record/multiple-objects/hooks/useGenerateCombinedFindManyRecordsQuery'; import { useLimitPerMetadataItem } from '@/object-record/relation-picker/hooks/useLimitPerMetadataItem'; @@ -21,17 +22,21 @@ export const useMultiObjectSearchMatchesSearchFilterAndToSelectQuery = ({ excludedObjectRecordIds, searchFilterValue, limit, + excludedObjects, }: { selectedObjectRecordIds: SelectedObjectRecordId[]; excludedObjectRecordIds: SelectedObjectRecordId[]; searchFilterValue: string; limit?: number; + excludedObjects?: CoreObjectNameSingular[]; }) => { const objectMetadataItems = useRecoilValue(objectMetadataItemsState); - const selectableObjectMetadataItems = objectMetadataItems.filter( - ({ isSystem, isRemote }) => !isSystem && !isRemote, - ); + const selectableObjectMetadataItems = objectMetadataItems + .filter(({ isSystem, isRemote }) => !isSystem && !isRemote) + .filter(({ nameSingular }) => { + return !excludedObjects?.includes(nameSingular as CoreObjectNameSingular); + }); const { searchFilterPerMetadataItemNameSingular } = useSearchFilterPerMetadataItem({ diff --git a/packages/twenty-front/src/modules/object-record/select/utils/getObjectFilterFields.ts b/packages/twenty-front/src/modules/object-record/select/utils/getObjectFilterFields.ts index 6ad643eaa..c1a1d8855 100644 --- a/packages/twenty-front/src/modules/object-record/select/utils/getObjectFilterFields.ts +++ b/packages/twenty-front/src/modules/object-record/select/utils/getObjectFilterFields.ts @@ -1,8 +1,4 @@ export const getObjectFilterFields = (objectSingleName: string) => { - if (objectSingleName === 'company') { - return ['name']; - } - if (['workspaceMember', 'person'].includes(objectSingleName)) { return ['name.firstName', 'name.lastName']; } diff --git a/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts b/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts index 3f6c58370..f77e2be50 100644 --- a/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts +++ b/packages/twenty-front/src/modules/object-record/utils/generateEmptyFieldValue.ts @@ -84,6 +84,9 @@ export const generateEmptyFieldValue = ( case FieldMetadataType.RawJson: { return null; } + case FieldMetadataType.RichText: { + return null; + } default: { throw new Error('Unhandled FieldMetadataType'); } diff --git a/packages/twenty-front/src/modules/object-record/utils/isFieldCellSupported.ts b/packages/twenty-front/src/modules/object-record/utils/isFieldCellSupported.ts index c06278e9a..bfdeb6e17 100644 --- a/packages/twenty-front/src/modules/object-record/utils/isFieldCellSupported.ts +++ b/packages/twenty-front/src/modules/object-record/utils/isFieldCellSupported.ts @@ -1,3 +1,4 @@ +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { isObjectMetadataAvailableForRelation } from '@/object-metadata/utils/isObjectMetadataAvailableForRelation'; import { @@ -7,9 +8,11 @@ import { export const isFieldCellSupported = (fieldMetadataItem: FieldMetadataItem) => { if ( - [FieldMetadataType.Uuid, FieldMetadataType.Position].includes( - fieldMetadataItem.type, - ) + [ + FieldMetadataType.Uuid, + FieldMetadataType.Position, + FieldMetadataType.RichText, + ].includes(fieldMetadataItem.type) ) { return false; } @@ -22,6 +25,25 @@ export const isFieldCellSupported = (fieldMetadataItem: FieldMetadataItem) => { fieldMetadataItem.fromRelationMetadata?.toObjectMetadata ?? fieldMetadataItem.toRelationMetadata?.fromObjectMetadata; + // Hack to display targets on Notes and Tasks + if ( + fieldMetadataItem.fromRelationMetadata?.toObjectMetadata?.nameSingular === + CoreObjectNameSingular.NoteTarget && + fieldMetadataItem.relationDefinition?.sourceObjectMetadata + .nameSingular === CoreObjectNameSingular.Note + ) { + return true; + } + + if ( + fieldMetadataItem.fromRelationMetadata?.toObjectMetadata?.nameSingular === + CoreObjectNameSingular.TaskTarget && + fieldMetadataItem.relationDefinition?.sourceObjectMetadata + .nameSingular === CoreObjectNameSingular.Task + ) { + return true; + } + if ( !relationMetadata || // TODO: Many to many relations are not supported yet. diff --git a/packages/twenty-front/src/modules/object-record/utils/sanitizeRecordInput.ts b/packages/twenty-front/src/modules/object-record/utils/sanitizeRecordInput.ts index 54f9bd224..bbad8bd46 100644 --- a/packages/twenty-front/src/modules/object-record/utils/sanitizeRecordInput.ts +++ b/packages/twenty-front/src/modules/object-record/utils/sanitizeRecordInput.ts @@ -36,7 +36,7 @@ export const sanitizeRecordInput = ({ (field) => field.name === relationIdFieldName, ); - return relationIdFieldMetadataItem + return relationIdFieldMetadataItem && fieldValue?.id ? [relationIdFieldName, fieldValue?.id ?? null] : undefined; } diff --git a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsFieldTypeConfigs.ts b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsFieldTypeConfigs.ts index cd2580d56..dd0f75991 100644 --- a/packages/twenty-front/src/modules/settings/data-model/constants/SettingsFieldTypeConfigs.ts +++ b/packages/twenty-front/src/modules/settings/data-model/constants/SettingsFieldTypeConfigs.ts @@ -4,6 +4,7 @@ import { IconCheck, IconCoins, IconComponent, + IconFilePencil, IconJson, IconKey, IconLink, @@ -131,6 +132,11 @@ export const SETTINGS_FIELD_TYPE_CONFIGS = { Icon: IconJson, defaultValue: { key: 'value' }, }, + [FieldMetadataType.RichText]: { + label: 'Rich Text', + Icon: IconFilePencil, + defaultValue: { key: 'value' }, + }, } as const satisfies Record< SettingsSupportedFieldType, SettingsFieldTypeConfig diff --git a/packages/twenty-front/src/modules/ui/input/editor/utils/__tests__/getFirstNonEmptyLineOfRichText.test.tsx b/packages/twenty-front/src/modules/ui/input/editor/utils/__tests__/getFirstNonEmptyLineOfRichText.test.tsx new file mode 100644 index 000000000..13986df3c --- /dev/null +++ b/packages/twenty-front/src/modules/ui/input/editor/utils/__tests__/getFirstNonEmptyLineOfRichText.test.tsx @@ -0,0 +1,77 @@ +import { PartialBlock } from '@blocknote/core'; +import { getFirstNonEmptyLineOfRichText } from '../getFirstNonEmptyLineOfRichText'; + +describe('getFirstNonEmptyLineOfRichText', () => { + it('should return an empty string if the input is null', () => { + const result = getFirstNonEmptyLineOfRichText(null); + expect(result).toBe(''); + }); + + it('should return an empty string if the input is an empty array', () => { + const result = getFirstNonEmptyLineOfRichText([]); + expect(result).toBe(''); + }); + + it('should return the first non-empty line of text', () => { + const input: PartialBlock[] = [ + { content: [{ text: '', type: 'text', styles: {} }] }, + { content: [{ text: ' ', type: 'text', styles: {} }] }, + { content: [{ text: 'First non-empty line', type: 'text', styles: {} }] }, + { content: [{ text: 'Second line', type: 'text', styles: {} }] }, + ]; + const result = getFirstNonEmptyLineOfRichText(input); + expect(result).toBe('First non-empty line'); + }); + + it('should return an empty string if all lines are empty', () => { + const input: PartialBlock[] = [ + { content: [{ text: '', type: 'text', styles: {} }] }, + { content: [{ text: ' ', type: 'text', styles: {} }] }, + { content: [{ text: '\n', type: 'text', styles: {} }] }, + ]; + const result = getFirstNonEmptyLineOfRichText(input); + expect(result).toBe(''); + }); + + it('should handle mixed content correctly', () => { + const input: PartialBlock[] = [ + { content: [{ text: '', type: 'text', styles: {} }] }, + { content: [{ text: ' ', type: 'text', styles: {} }] }, + { content: [{ text: 'First non-empty line', type: 'text', styles: {} }] }, + { content: [{ text: '', type: 'text', styles: {} }] }, + { + content: [{ text: 'Second non-empty line', type: 'text', styles: {} }], + }, + ]; + const result = getFirstNonEmptyLineOfRichText(input); + expect(result).toBe('First non-empty line'); + }); + + it('should handle content with multiple text objects correctly', () => { + const input: PartialBlock[] = [ + { + content: [ + { text: '', type: 'text', styles: {} }, + { text: ' ', type: 'text', styles: {} }, + ], + }, + { + content: [ + { text: 'First non-empty line', type: 'text', styles: {} }, + { text: 'Second line', type: 'text', styles: {} }, + ], + }, + ]; + const result = getFirstNonEmptyLineOfRichText(input); + expect(result).toBe('First non-empty line'); + }); + + it('should handle content with undefined or null content', () => { + const input: PartialBlock[] = [ + { content: undefined }, + { content: [{ text: 'First non-empty line', type: 'text', styles: {} }] }, + ]; + const result = getFirstNonEmptyLineOfRichText(input); + expect(result).toBe('First non-empty line'); + }); +}); diff --git a/packages/twenty-front/src/modules/ui/input/editor/utils/getFirstNonEmptyLineOfRichText.ts b/packages/twenty-front/src/modules/ui/input/editor/utils/getFirstNonEmptyLineOfRichText.ts new file mode 100644 index 000000000..ef8ab6114 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/input/editor/utils/getFirstNonEmptyLineOfRichText.ts @@ -0,0 +1,23 @@ +import { PartialBlock } from '@blocknote/core'; +import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; + +export const getFirstNonEmptyLineOfRichText = ( + fieldValue: PartialBlock[] | null, +): string => { + if (fieldValue === null) { + return ''; + } + for (const node of fieldValue) { + if (!isUndefinedOrNull(node.content)) { + const contentArray = node.content as Array<{ text: string }>; + if (contentArray.length > 0) { + for (const content of contentArray) { + if (content.text.trim() !== '') { + return content.text; + } + } + } + } + } + return ''; +}; diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx index 1da369918..18eaf4aa4 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx @@ -2,7 +2,12 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { motion } from 'framer-motion'; import { useRef } from 'react'; -import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil'; +import { + useRecoilCallback, + useRecoilState, + useRecoilValue, + useSetRecoilState, +} from 'recoil'; import { Key } from 'ts-key-enum'; import { RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID } from '@/ui/layout/right-drawer/constants/RightDrawerClickOutsideListener'; @@ -16,7 +21,6 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { isDefined } from '~/utils/isDefined'; import { useRightDrawer } from '../hooks/useRightDrawer'; -import { isRightDrawerExpandedState } from '../states/isRightDrawerExpandedState'; import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState'; import { rightDrawerPageState } from '../states/rightDrawerPageState'; import { RightDrawerHotkeyScope } from '../types/RightDrawerHotkeyScope'; @@ -49,8 +53,7 @@ export const RightDrawer = () => { const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState); - const isRightDrawerExpanded = useRecoilValue(isRightDrawerExpandedState); - const [, setIsRightDrawerAnimationCompleted] = useRecoilState( + const setIsRightDrawerAnimationCompleted = useSetRecoilState( isRightDrawerAnimationCompletedState, ); @@ -101,7 +104,7 @@ export const RightDrawer = () => { const isMobile = useIsMobile(); const rightDrawerWidth = isRightDrawerOpen - ? isMobile || isRightDrawerExpanded + ? isMobile ? '100%' : theme.rightDrawerWidth : '0'; diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx index 20c931f86..01172f55a 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx @@ -4,8 +4,6 @@ import { useRecoilState, useRecoilValue } from 'recoil'; import { RightDrawerCalendarEvent } from '@/activities/calendar/right-drawer/components/RightDrawerCalendarEvent'; import { RightDrawerAIChat } from '@/activities/copilot/right-drawer/components/RightDrawerAIChat'; import { RightDrawerEmailThread } from '@/activities/emails/right-drawer/components/RightDrawerEmailThread'; -import { RightDrawerCreateActivity } from '@/activities/right-drawer/components/create/RightDrawerCreateActivity'; -import { RightDrawerEditActivity } from '@/activities/right-drawer/components/edit/RightDrawerEditActivity'; import { RightDrawerRecord } from '@/object-record/record-right-drawer/components/RightDrawerRecord'; import { RightDrawerTopBar } from '@/ui/layout/right-drawer/components/RightDrawerTopBar'; import { isRightDrawerMinimizedState } from '@/ui/layout/right-drawer/states/isRightDrawerMinimizedState'; @@ -31,14 +29,6 @@ const StyledRightDrawerBody = styled.div` `; const RIGHT_DRAWER_PAGES_CONFIG = { - [RightDrawerPages.CreateActivity]: { - page: , - topBar: , - }, - [RightDrawerPages.EditActivity]: { - page: , - topBar: , - }, [RightDrawerPages.ViewEmailThread]: { page: , topBar: , diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx index 1e371c0eb..64eddfd9b 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx @@ -3,8 +3,9 @@ import styled from '@emotion/styled'; import { useRecoilState, useRecoilValue } from 'recoil'; import { Chip, ChipAccent, ChipSize, useIcons } from 'twenty-ui'; -import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage'; +import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState'; import { viewableRecordNameSingularState } from '@/object-record/record-right-drawer/states/viewableRecordNameSingularState'; import { RightDrawerTopBarCloseButton } from '@/ui/layout/right-drawer/components/RightDrawerTopBarCloseButton'; import { RightDrawerTopBarExpandButton } from '@/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton'; @@ -62,6 +63,8 @@ export const RightDrawerTopBar = ({ page }: { page: RightDrawerPages }) => { viewableRecordNameSingularState, ); + const viewableRecordId = useRecoilValue(viewableRecordIdState); + const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular: viewableRecordNameSingular ?? 'company', }); @@ -80,20 +83,15 @@ export const RightDrawerTopBar = ({ page }: { page: RightDrawerPages }) => { onClick={handleOnclick} isRightDrawerMinimized={isRightDrawerMinimized} > - {!isRightDrawerMinimized && - (page === RightDrawerPages.EditActivity || - page === RightDrawerPages.CreateActivity) && } - {!isRightDrawerMinimized && - page !== RightDrawerPages.EditActivity && - page !== RightDrawerPages.CreateActivity && ( - } - size={ChipSize.Large} - accent={ChipAccent.TextSecondary} - clickable={false} - /> - )} + {!isRightDrawerMinimized && ( + } + size={ChipSize.Large} + accent={ChipAccent.TextSecondary} + clickable={false} + /> + )} {isRightDrawerMinimized && ( @@ -106,8 +104,15 @@ export const RightDrawerTopBar = ({ page }: { page: RightDrawerPages }) => { {!isMobile && !isRightDrawerMinimized && ( )} + {!isMobile && !isRightDrawerMinimized && ( - + )} diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx index 8e4942b99..f3d187a94 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBarExpandButton.tsx @@ -1,33 +1,19 @@ -import { - IconLayoutSidebarRightCollapse, - IconLayoutSidebarRightExpand, -} from 'twenty-ui'; - import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; +import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink'; +import { IconExternalLink } from 'twenty-ui'; -export const RightDrawerTopBarExpandButton = () => { - const { isRightDrawerExpanded, downsizeRightDrawer, expandRightDrawer } = - useRightDrawer(); - - const handleButtonClick = () => { - if (isRightDrawerExpanded === true) { - downsizeRightDrawer(); - return; - } - expandRightDrawer(); - }; +export const RightDrawerTopBarExpandButton = ({ to }: { to: string }) => { + const { closeRightDrawer } = useRightDrawer(); return ( - + + + ); }; diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageIcons.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageIcons.ts index 429436b66..5b8c112be 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageIcons.ts +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageIcons.ts @@ -1,8 +1,6 @@ import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages'; export const RIGHT_DRAWER_PAGE_ICONS = { - [RightDrawerPages.CreateActivity]: 'IconNote', - [RightDrawerPages.EditActivity]: 'IconNote', [RightDrawerPages.ViewEmailThread]: 'IconMail', [RightDrawerPages.ViewCalendarEvent]: 'IconCalendarEvent', [RightDrawerPages.ViewRecord]: 'Icon123', diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageTitles.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageTitles.ts index 18517c80d..9bf58e09c 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageTitles.ts +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/constants/RightDrawerPageTitles.ts @@ -1,8 +1,6 @@ import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages'; export const RIGHT_DRAWER_PAGE_TITLES = { - [RightDrawerPages.CreateActivity]: 'Create Activity', - [RightDrawerPages.EditActivity]: 'Edit Activity', [RightDrawerPages.ViewEmailThread]: 'Email Thread', [RightDrawerPages.ViewCalendarEvent]: 'Calendar Event', [RightDrawerPages.ViewRecord]: 'Record Editor', diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx index 843de0118..4556ac627 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/__tests__/useRightDrawer.test.tsx @@ -1,8 +1,7 @@ -import { act } from 'react-dom/test-utils'; import { renderHook } from '@testing-library/react'; +import { act } from 'react-dom/test-utils'; import { RecoilRoot, useRecoilValue } from 'recoil'; -import { isRightDrawerExpandedState } from '../../states/isRightDrawerExpandedState'; import { isRightDrawerOpenState } from '../../states/isRightDrawerOpenState'; import { rightDrawerPageState } from '../../states/rightDrawerPageState'; import { RightDrawerPages } from '../../types/RightDrawerPages'; @@ -13,7 +12,6 @@ describe('useRightDrawer', () => { const useCombinedHooks = () => { const { openRightDrawer, closeRightDrawer } = useRightDrawer(); const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState); - const isRightDrawerExpanded = useRecoilValue(isRightDrawerExpandedState); const rightDrawerPage = useRecoilValue(rightDrawerPageState); @@ -21,7 +19,6 @@ describe('useRightDrawer', () => { openRightDrawer, closeRightDrawer, isRightDrawerOpen, - isRightDrawerExpanded, rightDrawerPage, }; }; @@ -31,26 +28,21 @@ describe('useRightDrawer', () => { }); expect(result.current.rightDrawerPage).toBeNull(); - expect(result.current.isRightDrawerExpanded).toBeFalsy(); expect(result.current.isRightDrawerOpen).toBeFalsy(); expect(result.current.openRightDrawer).toBeInstanceOf(Function); expect(result.current.closeRightDrawer).toBeInstanceOf(Function); await act(async () => { - result.current.openRightDrawer(RightDrawerPages.CreateActivity); + result.current.openRightDrawer(RightDrawerPages.ViewRecord); }); - expect(result.current.rightDrawerPage).toEqual( - RightDrawerPages.CreateActivity, - ); - expect(result.current.isRightDrawerExpanded).toBeFalsy(); + expect(result.current.rightDrawerPage).toEqual(RightDrawerPages.ViewRecord); expect(result.current.isRightDrawerOpen).toBeTruthy(); await act(async () => { result.current.closeRightDrawer(); }); - expect(result.current.isRightDrawerExpanded).toBeFalsy(); expect(result.current.isRightDrawerOpen).toBeFalsy(); }); }); diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts index 86cc303c8..9aeb48bc1 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/hooks/useRightDrawer.ts @@ -1,25 +1,22 @@ -import { useRecoilCallback, useRecoilState } from 'recoil'; +import { useRecoilCallback, useRecoilValue } from 'recoil'; import { isRightDrawerMinimizedState } from '@/ui/layout/right-drawer/states/isRightDrawerMinimizedState'; import { rightDrawerCloseEventState } from '@/ui/layout/right-drawer/states/rightDrawerCloseEventsState'; -import { isRightDrawerExpandedState } from '../states/isRightDrawerExpandedState'; import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState'; import { rightDrawerPageState } from '../states/rightDrawerPageState'; import { RightDrawerPages } from '../types/RightDrawerPages'; export const useRightDrawer = () => { - const [isRightDrawerOpen] = useRecoilState(isRightDrawerOpenState); - const [isRightDrawerExpanded] = useRecoilState(isRightDrawerExpandedState); - const [isRightDrawerMinimized] = useRecoilState(isRightDrawerMinimizedState); + const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState); + const isRightDrawerMinimized = useRecoilValue(isRightDrawerMinimizedState); - const [rightDrawerPage] = useRecoilState(rightDrawerPageState); + const rightDrawerPage = useRecoilValue(rightDrawerPageState); const openRightDrawer = useRecoilCallback( ({ set }) => (rightDrawerPage: RightDrawerPages) => { set(rightDrawerPageState, rightDrawerPage); - set(isRightDrawerExpandedState, false); set(isRightDrawerOpenState, true); set(isRightDrawerMinimizedState, false); }, @@ -29,7 +26,6 @@ export const useRightDrawer = () => { const closeRightDrawer = useRecoilCallback( ({ set }) => () => { - set(isRightDrawerExpandedState, false); set(isRightDrawerOpenState, false); set(isRightDrawerMinimizedState, false); }, @@ -39,7 +35,6 @@ export const useRightDrawer = () => { const minimizeRightDrawer = useRecoilCallback( ({ set }) => () => { - set(isRightDrawerExpandedState, false); set(isRightDrawerOpenState, true); set(isRightDrawerMinimizedState, true); }, @@ -50,32 +45,11 @@ export const useRightDrawer = () => { ({ set }) => () => { set(isRightDrawerMinimizedState, false); - set(isRightDrawerExpandedState, false); set(isRightDrawerOpenState, true); }, [], ); - const expandRightDrawer = useRecoilCallback( - ({ set }) => - () => { - set(isRightDrawerExpandedState, true); - set(isRightDrawerOpenState, true); - set(isRightDrawerMinimizedState, false); - }, - [], - ); - - const downsizeRightDrawer = useRecoilCallback( - ({ set }) => - () => { - set(isRightDrawerExpandedState, false); - set(isRightDrawerOpenState, true); - set(isRightDrawerMinimizedState, false); - }, - [], - ); - const isSameEventThanRightDrawerClose = useRecoilCallback( ({ snapshot }) => (event: MouseEvent | TouchEvent) => { @@ -95,14 +69,11 @@ export const useRightDrawer = () => { return { rightDrawerPage, isRightDrawerOpen, - isRightDrawerExpanded, isRightDrawerMinimized, openRightDrawer, closeRightDrawer, minimizeRightDrawer, maximizeRightDrawer, - expandRightDrawer, - downsizeRightDrawer, isSameEventThanRightDrawerClose, }; }; diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/states/isRightDrawerExpandedState.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/states/isRightDrawerExpandedState.ts deleted file mode 100644 index 002c9e8cd..000000000 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/states/isRightDrawerExpandedState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createState } from 'twenty-ui'; - -export const isRightDrawerExpandedState = createState({ - key: 'isRightDrawerExpandedState', - defaultValue: false, -}); diff --git a/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts b/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts index e579b6544..200602767 100644 --- a/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts +++ b/packages/twenty-front/src/modules/ui/layout/right-drawer/types/RightDrawerPages.ts @@ -1,6 +1,4 @@ export enum RightDrawerPages { - CreateActivity = 'create-activity', - EditActivity = 'edit-activity', ViewEmailThread = 'view-email-thread', ViewCalendarEvent = 'view-calendar-event', ViewRecord = 'view-record', diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageActivityContainer.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageActivityContainer.tsx new file mode 100644 index 000000000..4e89aa1af --- /dev/null +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageActivityContainer.tsx @@ -0,0 +1,31 @@ +import { RichTextEditor } from '@/activities/components/RichTextEditor'; +import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import styled from '@emotion/styled'; + +const StyledShowPageActivityContainer = styled.div` + margin-top: ${({ theme }) => theme.spacing(2)}; + width: 100%; +`; +export const ShowPageActivityContainer = ({ + targetableObject, +}: { + targetableObject: Pick< + ActivityTargetableObject, + 'targetObjectNameSingular' | 'id' + >; +}) => { + return ( + + + + ); +}; diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx index 883317ca5..9e5621d9d 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx @@ -2,7 +2,6 @@ import styled from '@emotion/styled'; import { IconCheckbox, IconNotes, IconPlus } from 'twenty-ui'; import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer'; -import { ActivityType } from '@/activities/types/Activity'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { PageHotkeyScope } from '@/types/PageHotkeyScope'; import { IconButton } from '@/ui/input/button/components/IconButton'; @@ -11,6 +10,7 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { SHOW_PAGE_ADD_BUTTON_DROPDOWN_ID } from '@/ui/layout/show-page/constants/ShowPageAddButtonDropdownId'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; +import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { Dropdown } from '../../dropdown/components/Dropdown'; import { DropdownMenu } from '../../dropdown/components/DropdownMenu'; @@ -24,17 +24,37 @@ export const ShowPageAddButton = ({ activityTargetObject: ActivityTargetableObject; }) => { const { closeDropdown, toggleDropdown } = useDropdown('add-show-page'); - const openCreateActivity = useOpenCreateActivityDrawer(); + const openNote = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Note, + }); + const openTask = useOpenCreateActivityDrawer({ + activityObjectNameSingular: CoreObjectNameSingular.Task, + }); - const handleSelect = (type: ActivityType) => { - openCreateActivity({ - type, - targetableObjects: [activityTargetObject], - }); + const handleSelect = (objectNameSingular: CoreObjectNameSingular) => { + if (objectNameSingular === CoreObjectNameSingular.Note) { + openNote({ + targetableObjects: [activityTargetObject], + }); + } + if (objectNameSingular === CoreObjectNameSingular.Task) { + openTask({ + targetableObjects: [activityTargetObject], + }); + } closeDropdown(); }; + if ( + activityTargetObject.targetObjectNameSingular === + CoreObjectNameSingular.Task || + activityTargetObject.targetObjectNameSingular === + CoreObjectNameSingular.Note + ) { + return; + } + return ( handleSelect('Note')} + onClick={() => handleSelect(CoreObjectNameSingular.Note)} accent="default" LeftIcon={IconNotes} text="Note" /> handleSelect('Task')} + onClick={() => handleSelect(CoreObjectNameSingular.Task)} accent="default" LeftIcon={IconCheckbox} text="Task" diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx index 2ef8c280b..f35d34d0e 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageRightContainer.tsx @@ -3,7 +3,7 @@ import { useRecoilValue } from 'recoil'; import { IconCalendarEvent, IconCheckbox, - IconHome, + IconList, IconMail, IconNotes, IconPaperclip, @@ -16,9 +16,9 @@ import { Attachments } from '@/activities/files/components/Attachments'; import { Notes } from '@/activities/notes/components/Notes'; import { ObjectTasks } from '@/activities/tasks/components/ObjectTasks'; import { TimelineActivities } from '@/activities/timelineActivities/components/TimelineActivities'; -import { TimelineActivitiesQueryEffect } from '@/activities/timelineActivities/components/TimelineActivitiesQueryEffect'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; +import { ShowPageActivityContainer } from '@/ui/layout/show-page/components/ShowPageActivityContainer'; import { TabList } from '@/ui/layout/tab/components/TabList'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; @@ -51,8 +51,9 @@ type ShowPageRightContainerProps = { tasks?: boolean; notes?: boolean; emails?: boolean; - summary?: JSX.Element; - isRightDrawer?: boolean; + fieldsBox?: JSX.Element; + summaryCard?: JSX.Element; + isInRightDrawer?: boolean; loading: boolean; }; @@ -63,10 +64,13 @@ export const ShowPageRightContainer = ({ notes, emails, loading, - summary, - isRightDrawer = false, + fieldsBox, + summaryCard, + isInRightDrawer = false, }: ShowPageRightContainerProps) => { - const { activeTabIdState } = useTabList(TAB_LIST_COMPONENT_ID); + const { activeTabIdState } = useTabList( + `${TAB_LIST_COMPONENT_ID}-${isInRightDrawer}`, + ); const activeTabId = useRecoilValue(activeTabIdState); const targetObjectNameSingular = @@ -80,24 +84,60 @@ export const ShowPageRightContainer = ({ const shouldDisplayCalendarTab = isCompanyOrPerson; const shouldDisplayEmailsTab = emails && isCompanyOrPerson; - const isMobile = useIsMobile() || isRightDrawer; + const isMobile = useIsMobile() || isInRightDrawer; const tabs = [ { - id: 'summary', - title: 'Summary', - Icon: IconHome, + id: 'richText', + title: 'Note', + Icon: IconNotes, + hide: + loading || + (targetableObject.targetObjectNameSingular !== + CoreObjectNameSingular.Note && + targetableObject.targetObjectNameSingular !== + CoreObjectNameSingular.Task), + }, + { + id: 'fields', + title: 'Fields', + Icon: IconList, hide: !isMobile, }, { id: 'timeline', title: 'Timeline', Icon: IconTimelineEvent, - hide: !timeline || isRightDrawer, + hide: !timeline || isInRightDrawer, + }, + { + id: 'tasks', + title: 'Tasks', + Icon: IconCheckbox, + hide: + !tasks || + targetableObject.targetObjectNameSingular === + CoreObjectNameSingular.Note || + targetableObject.targetObjectNameSingular === + CoreObjectNameSingular.Task, + }, + { + id: 'notes', + title: 'Notes', + Icon: IconNotes, + hide: + !notes || + targetableObject.targetObjectNameSingular === + CoreObjectNameSingular.Note || + targetableObject.targetObjectNameSingular === + CoreObjectNameSingular.Task, + }, + { + id: 'files', + title: 'Files', + Icon: IconPaperclip, + hide: !notes, }, - { id: 'tasks', title: 'Tasks', Icon: IconCheckbox, hide: !tasks }, - { id: 'notes', title: 'Notes', Icon: IconNotes, hide: !notes }, - { id: 'files', title: 'Files', Icon: IconPaperclip, hide: !notes }, { id: 'emails', title: 'Emails', @@ -117,14 +157,23 @@ export const ShowPageRightContainer = ({ case 'timeline': return ( <> - - ); - case 'summary': - return summary; + case 'richText': + return ( + (targetableObject.targetObjectNameSingular === + CoreObjectNameSingular.Note || + targetableObject.targetObjectNameSingular === + CoreObjectNameSingular.Task) && ( + + ) + ); + case 'fields': + return fieldsBox; case 'tasks': return ; case 'notes': @@ -142,10 +191,11 @@ export const ShowPageRightContainer = ({ return ( + {summaryCard} diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx index d4f33fb82..04e6c6723 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx @@ -1,8 +1,8 @@ -import { Link, useNavigate } from 'react-router-dom'; import isPropValid from '@emotion/is-prop-valid'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { isNonEmptyString } from '@sniptt/guards'; +import { Link, useNavigate } from 'react-router-dom'; import { useSetRecoilState } from 'recoil'; import { IconComponent, MOBILE_VIEWPORT, Pill } from 'twenty-ui'; diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem.tsx new file mode 100644 index 000000000..0d29e4c26 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem.tsx @@ -0,0 +1,43 @@ +import { + NavigationDrawerItem, + NavigationDrawerItemProps, +} from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import styled from '@emotion/styled'; + +const StyledItem = styled.div` + margin-left: ${({ theme }) => theme.spacing(4)}; +`; + +type NavigationDrawerSubItemProps = NavigationDrawerItemProps; + +export const NavigationDrawerSubItem = ({ + className, + label, + level = 1, + Icon, + to, + onClick, + active, + danger, + soon, + count, + keyboard, +}: NavigationDrawerSubItemProps) => { + return ( + + + + ); +}; diff --git a/packages/twenty-front/src/modules/users/components/UserProviderEffect.tsx b/packages/twenty-front/src/modules/users/components/UserProviderEffect.tsx index 9ab6656f4..7213ffdda 100644 --- a/packages/twenty-front/src/modules/users/components/UserProviderEffect.tsx +++ b/packages/twenty-front/src/modules/users/components/UserProviderEffect.tsx @@ -54,6 +54,7 @@ export const UserProviderEffect = () => { setCurrentWorkspaceMember({ ...workspaceMember, colorScheme: (workspaceMember.colorScheme as ColorScheme) ?? 'Light', + locale: workspaceMember.locale ?? 'en', }); // TODO: factorize diff --git a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx index 0fc67d6ab..944bef3a8 100644 --- a/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx +++ b/packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx @@ -1,6 +1,6 @@ -import { MouseEvent, useCallback } from 'react'; import styled from '@emotion/styled'; import { DropResult } from '@hello-pangea/dnd'; +import { MouseEvent, useCallback } from 'react'; import { useSetRecoilState } from 'recoil'; import { IconLock, IconPencil, IconPlus, useIcons } from 'twenty-ui'; @@ -84,6 +84,22 @@ export const ViewPickerListContent = () => { return ( <> + {indexView && ( + handleViewSelect(indexView.id)} + LeftIcon={getIcon(indexView.icon)} + text={indexView.name} + accent="placeholder" + isDragDisabled + /> + )} ( diff --git a/packages/twenty-front/src/modules/workspace-member/types/WorkspaceMember.ts b/packages/twenty-front/src/modules/workspace-member/types/WorkspaceMember.ts index 61977b340..46365c934 100644 --- a/packages/twenty-front/src/modules/workspace-member/types/WorkspaceMember.ts +++ b/packages/twenty-front/src/modules/workspace-member/types/WorkspaceMember.ts @@ -14,7 +14,7 @@ export type WorkspaceMember = { lastName: string; }; avatarUrl?: string | null; - locale?: string | null; + locale: string | null; colorScheme?: ColorScheme; createdAt: string; updatedAt: string; diff --git a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep2.tsx b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep2.tsx index 4aea76d82..61207d602 100644 --- a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep2.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep2.tsx @@ -161,13 +161,9 @@ export const SettingsObjectNewFieldStep2 = () => { const excludedFieldTypes: SettingsSupportedFieldType[] = ( [ - // FieldMetadataType.Email, - // FieldMetadataType.FullName, FieldMetadataType.Link, FieldMetadataType.Numeric, - // FieldMetadataType.Probability, - // FieldMetadataType.Uuid, - // FieldMetadataType.Phone, + FieldMetadataType.RichText, ] as const ).filter(isDefined); diff --git a/packages/twenty-front/src/pages/tasks/Tasks.tsx b/packages/twenty-front/src/pages/tasks/Tasks.tsx deleted file mode 100644 index 978f35205..000000000 --- a/packages/twenty-front/src/pages/tasks/Tasks.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import styled from '@emotion/styled'; -import { IconArchive, IconCheck, IconCheckbox } from 'twenty-ui'; - -import { TasksRecoilScopeContext } from '@/activities/states/recoil-scope-contexts/TasksRecoilScopeContext'; -import { PageAddTaskButton } from '@/activities/tasks/components/PageAddTaskButton'; -import { TaskGroups } from '@/activities/tasks/components/TaskGroups'; -import { TASKS_TAB_LIST_COMPONENT_ID } from '@/activities/tasks/constants/TasksTabListComponentId'; -import { ObjectFilterDropdownButton } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton'; -import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; -import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope'; -import { PageBody } from '@/ui/layout/page/PageBody'; -import { PageContainer } from '@/ui/layout/page/PageContainer'; -import { PageHeader } from '@/ui/layout/page/PageHeader'; -import { TabList } from '@/ui/layout/tab/components/TabList'; -import { TopBar } from '@/ui/layout/top-bar/TopBar'; -import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; - -import { TasksEffect } from './TasksEffect'; - -const StyledTasksContainer = styled.div` - display: flex; - flex: 1; - flex-direction: column; - height: 100%; - overflow: auto; -`; - -const StyledTabListContainer = styled.div` - align-items: end; - display: flex; - height: 40px; -`; - -export const Tasks = () => { - const TASK_TABS = [ - { - id: 'to-do', - title: 'To do', - Icon: IconCheck, - }, - { - id: 'done', - title: 'Done', - Icon: IconArchive, - }, - ]; - - const filterDropdownId = 'tasks-assignee-filter'; - - return ( - - - - - - - - - - - - - } - rightComponent={ - - } - /> - - - - - - - ); -}; diff --git a/packages/twenty-front/src/pages/tasks/TasksEffect.tsx b/packages/twenty-front/src/pages/tasks/TasksEffect.tsx deleted file mode 100644 index 9476c755f..000000000 --- a/packages/twenty-front/src/pages/tasks/TasksEffect.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { useEffect } from 'react'; -import { useRecoilValue } from 'recoil'; -import { v4 } from 'uuid'; - -import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; -import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; -import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; -import { isDefined } from '~/utils/isDefined'; - -import { tasksFilterDefinitions } from './tasks-filter-definitions'; - -type TasksEffectProps = { - filterDropdownId: string; -}; - -export const TasksEffect = ({ filterDropdownId }: TasksEffectProps) => { - const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - const { - setSelectedFilter, - setAvailableFilterDefinitions, - setObjectFilterDropdownSelectedRecordIds, - } = useFilterDropdown({ - filterDropdownId: filterDropdownId, - }); - - useEffect(() => { - setAvailableFilterDefinitions(tasksFilterDefinitions); - }, [setAvailableFilterDefinitions]); - - useEffect(() => { - if (isDefined(currentWorkspaceMember)) { - setSelectedFilter({ - id: v4(), - fieldMetadataId: 'assigneeId', - value: JSON.stringify(currentWorkspaceMember.id), - operand: ViewFilterOperand.Is, - displayValue: - currentWorkspaceMember.name?.firstName + - ' ' + - currentWorkspaceMember.name?.lastName, - displayAvatarUrl: currentWorkspaceMember.avatarUrl ?? undefined, - definition: tasksFilterDefinitions[0], - }); - - setObjectFilterDropdownSelectedRecordIds([currentWorkspaceMember.id]); - } - }, [ - currentWorkspaceMember, - setSelectedFilter, - setObjectFilterDropdownSelectedRecordIds, - ]); - return <>; -}; diff --git a/packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx b/packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx deleted file mode 100644 index 458e3f301..000000000 --- a/packages/twenty-front/src/pages/tasks/__stories__/Tasks.stories.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { graphql, HttpResponse } from 'msw'; - -import { AppPath } from '@/types/AppPath'; -import { - PageDecorator, - PageDecoratorArgs, -} from '~/testing/decorators/PageDecorator'; -import { graphqlMocks } from '~/testing/graphqlMocks'; -import { mockedWorkspaceMemberData } from '~/testing/mock-data/users'; -import { sleep } from '~/utils/sleep'; - -import { Tasks } from '../Tasks'; - -const meta: Meta = { - title: 'Pages/Tasks/Default', - component: Tasks, - decorators: [PageDecorator], - args: { routePath: AppPath.TasksPage }, - parameters: { - msw: { - handlers: [ - graphql.query('FindOneWorkspaceMember', () => { - return HttpResponse.json({ - data: { - workspaceMember: mockedWorkspaceMemberData, - }, - }); - }), - graphqlMocks.handlers, - ], - }, - }, -}; - -export default meta; - -export type Story = StoryObj; - -export const Default: Story = { - play: async () => { - await sleep(100); - }, -}; diff --git a/packages/twenty-front/src/pages/tasks/tasks-filter-definitions.tsx b/packages/twenty-front/src/pages/tasks/tasks-filter-definitions.tsx deleted file mode 100644 index 34839160c..000000000 --- a/packages/twenty-front/src/pages/tasks/tasks-filter-definitions.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { IconUserCircle } from 'twenty-ui'; - -import { Activity } from '@/activities/types/Activity'; -import { FilterDefinitionByEntity } from '@/object-record/object-filter-dropdown/types/FilterDefinitionByEntity'; - -export const tasksFilterDefinitions: FilterDefinitionByEntity[] = [ - { - fieldMetadataId: 'assigneeId', - label: 'Assignee', - iconName: 'IconUser', - type: 'RELATION', - relationObjectMetadataNamePlural: 'workspaceMembers', - relationObjectMetadataNameSingular: 'workspaceMember', - selectAllLabel: 'All assignees', - SelectAllIcon: IconUserCircle, - }, -]; diff --git a/packages/twenty-front/src/testing/graphqlMocks.ts b/packages/twenty-front/src/testing/graphqlMocks.ts index 696ba7eac..2b1cfdbdf 100644 --- a/packages/twenty-front/src/testing/graphqlMocks.ts +++ b/packages/twenty-front/src/testing/graphqlMocks.ts @@ -6,19 +6,20 @@ import { GET_CLIENT_CONFIG } from '@/client-config/graphql/queries/getClientConf import { FIND_MANY_OBJECT_METADATA_ITEMS } from '@/object-metadata/graphql/queries'; import { GET_CURRENT_USER } from '@/users/graphql/queries/getCurrentUser'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; -import { mockedActivities } from '~/testing/mock-data/activities'; import { getCompaniesMock, getCompanyDuplicateMock, } from '~/testing/mock-data/companies'; import { mockedClientConfig } from '~/testing/mock-data/config'; import { mockedObjectMetadataItemsQueryResult } from '~/testing/mock-data/metadata'; +import { mockedNotes } from '~/testing/mock-data/notes'; import { getPeopleMock } from '~/testing/mock-data/people'; import { mockedRemoteTables } from '~/testing/mock-data/remote-tables'; import { mockedUserData } from '~/testing/mock-data/users'; import { mockedViewsData } from '~/testing/mock-data/views'; import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members'; +import { mockedTasks } from '~/testing/mock-data/tasks'; import { mockedRemoteServers } from './mock-data/remote-servers'; import { mockedViewFieldsData } from './mock-data/view-fields'; @@ -267,15 +268,41 @@ export const graphqlMocks = { }, }); }), - graphql.query('FindManyActivities', () => { + graphql.query('FindManyNotes', () => { return HttpResponse.json({ data: { activities: { - edges: mockedActivities.map(({ activityTargets, ...rest }) => ({ + edges: mockedNotes.map(({ noteTargets, ...rest }) => ({ node: { ...rest, - activityTargets: { - edges: activityTargets.map((t) => ({ node: t })), + noteTargets: { + edges: noteTargets?.map((t) => ({ node: t })), + }, + attachments: { + edges: [], + }, + }, + cursor: null, + })), + pageInfo: { + hasNextPage: false, + hasPreviousPage: false, + startCursor: null, + endCursor: null, + }, + }, + }, + }); + }), + graphql.query('FindManyTasks', () => { + return HttpResponse.json({ + data: { + activities: { + edges: mockedTasks.map(({ taskTargets, ...rest }) => ({ + node: { + ...rest, + taskTargets: { + edges: taskTargets?.map((t) => ({ node: t })), }, attachments: { edges: [], diff --git a/packages/twenty-front/src/testing/mock-data/activities.ts b/packages/twenty-front/src/testing/mock-data/activities.ts deleted file mode 100644 index 7ccb6def2..000000000 --- a/packages/twenty-front/src/testing/mock-data/activities.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { Activity } from '@/activities/types/Activity'; -import { ActivityTarget } from '@/activities/types/ActivityTarget'; -import { Comment } from '@/activities/types/Comment'; -import { Company } from '@/companies/types/Company'; -import { Person } from '@/people/types/Person'; -import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; - -type MockedActivity = Pick< - Activity, - | 'id' - | 'createdAt' - | 'updatedAt' - | '__typename' - | 'type' - | 'body' - | 'title' - | 'authorId' - | 'dueAt' - | 'completedAt' - | 'reminderAt' - | 'assigneeId' -> & { - author: WorkspaceMember; - assignee: WorkspaceMember; - comments: Comment[]; - activityTargets: Array< - Pick< - ActivityTarget, - | 'id' - | '__typename' - | 'createdAt' - | 'updatedAt' - | 'activityId' - | 'personId' - | 'companyId' - | 'targetObjectNameSingular' - > & { - activity: Pick; - person?: Pick | null; - company?: Pick< - Company, - 'id' | 'name' | 'domainName' | '__typename' - > | null; - } - >; -}; - -const workspaceMember: WorkspaceMember = { - __typename: 'WorkspaceMember', - id: '374fe3a5-df1e-4119-afe0-2a62a2ba481e', - name: { - firstName: 'Charles', - lastName: 'Test', - }, - avatarUrl: '', - locale: 'en', - createdAt: '2023-04-26T10:23:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - userId: 'e2409670-1088-46b4-858e-f20a598d9d0f', - userEmail: 'charles@test.com', - colorScheme: 'Light', -}; - -export const mockedTasks: Array = [ - { - id: 'c554852c-b28a-4307-a41d-a7a0fdde3386', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - reminderAt: null, - title: 'My very first task', - type: 'Task', - body: '', - dueAt: '2023-04-26T10:12:42.33625+00:00', - completedAt: null, - author: workspaceMember, - assignee: workspaceMember, - assigneeId: workspaceMember.id, - authorId: workspaceMember.id, - comments: [], - activityTargets: [], - __typename: 'Activity', - }, -]; - -export const mockedActivities: Array = [ - { - id: '3ecaa1be-aac7-463a-a38e-64078dd451d5', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - reminderAt: null, - title: 'My very first note', - type: 'Note', - body: '', - dueAt: '2023-04-26T10:12:42.33625+00:00', - completedAt: null, - author: workspaceMember, - assignee: workspaceMember, - assigneeId: workspaceMember.id, - authorId: workspaceMember.id, - comments: [], - activityTargets: [ - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb300', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - targetObjectNameSingular: 'company', - personId: null, - companyId: '89bb825c-171e-4bcc-9cf7-43448d6fb280', - company: { - __typename: 'Company', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb280', - name: 'Airbnb', - domainName: { - primaryLinkLabel: '', - primaryLinkUrl: 'https://www.airbnb.com', - }, - }, - person: null, - activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb230', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - }, - __typename: 'ActivityTarget', - }, - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb301', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - targetObjectNameSingular: 'company', - personId: null, - companyId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', - company: { - __typename: 'Company', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', - name: 'Aircall', - domainName: 'aircall.io', - }, - person: null, - activityId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb231', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - }, - __typename: 'ActivityTarget', - }, - ], - __typename: 'Activity', - }, - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - reminderAt: null, - title: 'Another note', - body: '', - type: 'Note', - completedAt: null, - dueAt: '2029-08-26T10:12:42.33625+00:00', - author: { - ...workspaceMember, - colorScheme: 'Dark', - }, - assignee: { ...workspaceMember, colorScheme: 'Dark' }, - assigneeId: workspaceMember.id, - authorId: workspaceMember.id, - comments: [], - activityTargets: [ - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278t', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - targetObjectNameSingular: 'person', - personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', // Alexandre - person: { - __typename: 'Person', - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', - name: { - firstName: 'Alexandre', - lastName: 'Test', - }, - avatarUrl: '', - }, - company: null, - companyId: null, - activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - createdAt: '2023-04-26T10:12:42.33625+00:00', - updatedAt: '2023-04-26T10:23:42.33625+00:00', - }, - __typename: 'ActivityTarget', - }, - { - id: '89bb825c-171e-4bcc-9cf7-43448d6fb279t', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', // Jean d'Eau - companyId: null, - targetObjectNameSingular: 'person', - company: null, - person: { - __typename: 'Person', - id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', - name: { - firstName: 'Jean', - lastName: "d'Eau", - }, - avatarUrl: '', - }, - activityId: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - activity: { - __typename: 'Activity', - id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - }, - __typename: 'ActivityTarget', - }, - ], - __typename: 'Activity', - }, -]; diff --git a/packages/twenty-front/src/testing/mock-data/generated/standard-metadata-query-result.ts b/packages/twenty-front/src/testing/mock-data/generated/standard-metadata-query-result.ts index cd1e9603a..5af0f701b 100644 --- a/packages/twenty-front/src/testing/mock-data/generated/standard-metadata-query-result.ts +++ b/packages/twenty-front/src/testing/mock-data/generated/standard-metadata-query-result.ts @@ -9447,7 +9447,7 @@ export const mockedStandardObjectMetadataQueryResult: ObjectMetadataItemsQuery = "isNullable": false, "createdAt": "2024-06-07T09:05:12.599Z", "updatedAt": "2024-06-07T09:05:12.599Z", - "defaultValue": "'Note'", + "defaultValue": "'NOTE'", "options": null, "relationDefinition": null, "fromRelationMetadata": null, @@ -9654,7 +9654,7 @@ export const mockedStandardObjectMetadataQueryResult: ObjectMetadataItemsQuery = "node": { "__typename": "field", "id": "f7d5db6e-0916-49cc-a4d4-b0489b8fbdbc", - "type": "TEXT", + "type": "RICH_TEXT", "name": "body", "label": "Body", "description": "Activity body", @@ -11701,7 +11701,7 @@ export const mockedStandardObjectMetadataQueryResult: ObjectMetadataItemsQuery = "node": { "__typename": "field", "id": "cd9efab6-a13f-4d5b-96fc-193cd3c8bce1", - "type": "TEXT", + "type": "RICH_TEXT", "name": "body", "label": "Body", "description": "Comment body", diff --git a/packages/twenty-front/src/testing/mock-data/notes.ts b/packages/twenty-front/src/testing/mock-data/notes.ts new file mode 100644 index 000000000..e1bdcab0b --- /dev/null +++ b/packages/twenty-front/src/testing/mock-data/notes.ts @@ -0,0 +1,124 @@ +import { Note } from '@/activities/types/Note'; +import { NoteTarget } from '@/activities/types/NoteTarget'; + +type MockedNote = Partial & { __typename?: string }; + +export const mockedNotes: Array = [ + { + id: '3ecaa1be-aac7-463a-a38e-64078dd451d5', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + title: 'My very first note', + body: null, + noteTargets: [ + { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb300', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + targetObjectNameSingular: 'company', + personId: null, + companyId: '89bb825c-171e-4bcc-9cf7-43448d6fb280', + company: { + __typename: 'Company', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb280', + name: 'Airbnb', + domainName: 'airbnb.com', + }, + person: null, + noteId: '89bb825c-171e-4bcc-9cf7-43448d6fb230', + note: { + __typename: 'Activity', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + }, + __typename: 'NoteTarget', + }, + { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb301', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + targetObjectNameSingular: 'company', + personId: null, + companyId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', + company: { + __typename: 'Company', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', + name: 'Aircall', + domainName: 'aircall.io', + }, + person: null, + noteId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', + note: { + __typename: 'Note', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb231', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + __typename: 'NoteTarget', + }, + ] as Array, + }, + { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + title: 'Another note', + body: null, + noteTargets: [ + { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278t', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + targetObjectNameSingular: 'person', + personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', // Alexandre + person: { + __typename: 'Person', + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b', + name: { + firstName: 'Alexandre', + lastName: 'Test', + }, + avatarUrl: '', + }, + company: null, + companyId: null, + noteId: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', + note: { + __typename: 'Note', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + }, + __typename: 'NoteTarget', + }, + { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb279t', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + personId: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', // Jean d'Eau + companyId: null, + targetObjectNameSingular: 'person', + company: null, + person: { + __typename: 'Person', + id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6d', + name: { + firstName: 'Jean', + lastName: "d'Eau", + }, + avatarUrl: '', + }, + noteId: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', + note: { + __typename: 'Note', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278a', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + __typename: 'NoteTarget', + }, + ] as Array, + __typename: 'Note', + }, +]; diff --git a/packages/twenty-front/src/testing/mock-data/tasks.ts b/packages/twenty-front/src/testing/mock-data/tasks.ts new file mode 100644 index 000000000..aa906a69b --- /dev/null +++ b/packages/twenty-front/src/testing/mock-data/tasks.ts @@ -0,0 +1,87 @@ +import { Task } from '@/activities/types/Task'; +import { TaskTarget } from '@/activities/types/TaskTarget'; +import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; + +type MockedTask = Task & { __typename?: string }; + +const workspaceMember: WorkspaceMember = { + __typename: 'WorkspaceMember', + id: '374fe3a5-df1e-4119-afe0-2a62a2ba481e', + name: { + firstName: 'Charles', + lastName: 'Test', + }, + avatarUrl: '', + locale: 'en', + createdAt: '2023-04-26T10:23:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + userId: 'e2409670-1088-46b4-858e-f20a598d9d0f', + userEmail: 'charles@test.com', + colorScheme: 'Light', +}; + +export const mockedTasks: Array = [ + { + id: '3ecaa1be-aac7-463a-a38e-64078dd451d5', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + title: 'My very first note', + body: null, + dueAt: '2023-04-26T10:12:42.33625+00:00', + status: null, + assignee: workspaceMember, + assigneeId: workspaceMember.id, + taskTargets: [ + { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb300', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + targetObjectNameSingular: 'company', + personId: null, + companyId: '89bb825c-171e-4bcc-9cf7-43448d6fb280', + company: { + __typename: 'Company', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb280', + name: 'Airbnb', + domainName: { + primaryLinkLabel: '', + primaryLinkUrl: 'https://www.airbnb.com', + }, + }, + person: null, + taskId: '89bb825c-171e-4bcc-9cf7-43448d6fb230', + task: { + __typename: 'Task', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb230', + createdAt: '2023-04-26T10:12:42.33625+00:00', + updatedAt: '2023-04-26T10:23:42.33625+00:00', + }, + __typename: 'TaskTarget', + }, + { + id: '89bb825c-171e-4bcc-9cf7-43448d6fb301', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + targetObjectNameSingular: 'company', + personId: null, + companyId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', + company: { + __typename: 'Company', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb278', + name: 'Aircall', + domainName: 'aircall.io', + }, + person: null, + taskId: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae', + task: { + __typename: 'Task', + id: '89bb825c-171e-4bcc-9cf7-43448d6fb231', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + __typename: 'TaskTarget', + }, + ] as Array, + __typename: 'Task', + }, +]; diff --git a/packages/twenty-front/src/utils/normalizeGQLField.ts b/packages/twenty-front/src/utils/normalizeGQLField.ts new file mode 100644 index 000000000..ede9253da --- /dev/null +++ b/packages/twenty-front/src/utils/normalizeGQLField.ts @@ -0,0 +1,8 @@ +import { parse } from 'graphql'; + +export const normalizeGQLField = (query: string) => { + // Parse the query to an AST, then print it back to a string. + // This normalizes whitespace and sorts fields alphabetically. + // Used in tests to compare fields regardless of order. + return parse('{' + query + '}').toString(); +}; diff --git a/packages/twenty-front/src/utils/normalizeGQLQuery.ts b/packages/twenty-front/src/utils/normalizeGQLQuery.ts new file mode 100644 index 000000000..fecdae3be --- /dev/null +++ b/packages/twenty-front/src/utils/normalizeGQLQuery.ts @@ -0,0 +1,8 @@ +import { parse } from 'graphql'; + +export const normalizeGQLQuery = (query: string) => { + // Parse the query to an AST, then print it back to a string. + // This normalizes whitespace and sorts fields alphabetically. + // Used in tests to compare queries. + return parse(query).toString(); +}; diff --git a/packages/twenty-front/tsconfig.json b/packages/twenty-front/tsconfig.json index e55b6b262..ac1d6e2f9 100644 --- a/packages/twenty-front/tsconfig.json +++ b/packages/twenty-front/tsconfig.json @@ -28,6 +28,7 @@ } }, "files": [], + "exclude": ["**/object-metadata/utils/getObjectMetadataItemsMock.ts"], "include": [], "references": [ { diff --git a/packages/twenty-server/src/database/commands/database-command.module.ts b/packages/twenty-server/src/database/commands/database-command.module.ts index 10ce74e95..c12d651e5 100644 --- a/packages/twenty-server/src/database/commands/database-command.module.ts +++ b/packages/twenty-server/src/database/commands/database-command.module.ts @@ -8,6 +8,7 @@ import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-dem import { DataSeedWorkspaceCommand } from 'src/database/commands/data-seed-dev-workspace.command'; import { ConfirmationQuestion } from 'src/database/commands/questions/confirmation.question'; import { UpgradeTo0_23CommandModule } from 'src/database/commands/upgrade-version/0-23/0-23-upgrade-version.module'; +import { UpgradeVersionModule } from 'src/database/commands/upgrade-version/upgrade-version.module'; import { WorkspaceAddTotalCountCommand } from 'src/database/commands/workspace-add-total-count.command'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; @@ -44,8 +45,8 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp ObjectMetadataModule, DataSeedDemoWorkspaceModule, WorkspaceCacheVersionModule, - // Upgrades UpgradeTo0_23CommandModule, + UpgradeVersionModule, ], providers: [ DataSeedWorkspaceCommand, diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-update-activities.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-update-activities.command.ts new file mode 100644 index 000000000..3b409e01c --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-update-activities.command.ts @@ -0,0 +1,464 @@ +import { Logger } from '@nestjs/common'; + +import chalk from 'chalk'; +import { Command, CommandRunner, Option } from 'nest-commander'; +import { QueryRunner } from 'typeorm'; +import { v4 } from 'uuid'; + +import { TypeORMService } from 'src/database/typeorm/typeorm.service'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; +import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; +import { notesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view'; +import { tasksAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view'; +import { tasksByStatusView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view'; +import { WorkspaceStatusService } from 'src/engine/workspace-manager/workspace-status/services/workspace-status.service'; +import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity'; +import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; +import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity'; +import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.workspace-entity'; +import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; +import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; +import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; + +interface UpdateActivitiesCommandOptions { + workspaceId?: string; +} + +type CoreLogicFunction = (params: { + workspaceId: string; + queryRunner?: QueryRunner; + schema?: string; +}) => Promise; + +@Command({ + name: 'migrate-0.23:update-activities-type', + description: 'Migrate Activity object to Note and Task objects', +}) +export class UpdateActivitiesCommand extends CommandRunner { + private readonly logger = new Logger(UpdateActivitiesCommand.name); + + constructor( + private readonly workspaceStatusService: WorkspaceStatusService, + private readonly typeORMService: TypeORMService, + private readonly dataSourceService: DataSourceService, + private readonly workspaceCacheVersionService: WorkspaceCacheVersionService, + private readonly objectMetadataService: ObjectMetadataService, + private readonly twentyORMGlobalManager: TwentyORMGlobalManager, + ) { + super(); + } + + @Option({ + flags: '-w, --workspace-id [workspace_id]', + description: 'workspace id. Command runs on all workspaces if not provided', + required: false, + }) + parseWorkspaceId(value: string): string { + return value; + } + + async run( + _passedParam: string[], + options: UpdateActivitiesCommandOptions, + ): Promise { + const updateActivities = async ({ + workspaceId, + queryRunner, + schema, + }: { + workspaceId: string; + queryRunner: QueryRunner; + schema: string; + }): Promise => { + /*********************** + // Transfer Activities to NOTE + Tasks + ***********************/ + + const activityRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspaceId, + 'activity', + ); + const noteRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspaceId, + 'note', + ); + const noteTargetRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspaceId, + 'noteTarget', + ); + const taskRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspaceId, + 'task', + ); + const taskTargetRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspaceId, + 'taskTarget', + ); + const timelineActivityRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspaceId, + 'timelineActivity', + ); + const attachmentRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + workspaceId, + 'attachment', + ); + + const objectMetadata = + await this.objectMetadataService.findManyWithinWorkspace(workspaceId); + + const noteObjectMetadataId = objectMetadata.find( + (object) => object.nameSingular === 'note', + )?.id; + + const taskObjectMetadataId = objectMetadata.find( + (object) => object.nameSingular === 'task', + )?.id; + + const activityObjectMetadataId = objectMetadata.find( + (object) => object.nameSingular === 'activity', + )?.id; + + const activitiesToTransfer = await activityRepository.find({ + order: { createdAt: 'ASC' }, + relations: ['activityTargets'], + }); + + for (let i = 0; i < activitiesToTransfer.length; i++) { + const activity = activitiesToTransfer[i]; + + if (activity.type === 'Note') { + const note = noteRepository.create({ + id: activity.id, + title: activity.title, + body: activity.body, + createdAt: activity.createdAt, + updatedAt: activity.updatedAt, + position: i, + }); + + await noteRepository.save(note); + + if (activity.activityTargets && activity.activityTargets.length > 0) { + const noteTargets = activity.activityTargets.map( + (activityTarget) => { + const { activityId, ...activityTargetData } = activityTarget; + + return noteTargetRepository.create({ + noteId: activityId, + ...activityTargetData, + }); + }, + ); + + await noteTargetRepository.save(noteTargets); + } + + await timelineActivityRepository.update( + { + linkedObjectMetadataId: activityObjectMetadataId, + linkedRecordId: activity.id, + }, + { + linkedObjectMetadataId: noteObjectMetadataId, + }, + ); + + await attachmentRepository.update( + { + activityId: activity.id, + }, + { + activityId: null, + noteId: activity.id, + }, + ); + } else if (activity.type === 'Task') { + const task = taskRepository.create({ + id: activity.id, + title: activity.title, + body: activity.body, + status: activity.completedAt ? 'DONE' : 'TODO', + dueAt: activity.dueAt, + assigneeId: activity.assigneeId, + position: i, + createdAt: activity.createdAt, + updatedAt: activity.updatedAt, + }); + + await taskRepository.save(task); + + if (activity.activityTargets && activity.activityTargets.length > 0) { + const taskTargets = activity.activityTargets.map( + (activityTarget) => { + const { activityId, ...activityTargetData } = activityTarget; + + return taskTargetRepository.create({ + taskId: activityId, + ...activityTargetData, + }); + }, + ); + + await taskTargetRepository.save(taskTargets); + } + + await timelineActivityRepository.update( + { + linkedObjectMetadataId: activityObjectMetadataId, + linkedRecordId: activity.id, + }, + { + linkedObjectMetadataId: taskObjectMetadataId, + }, + ); + await attachmentRepository.update( + { + activityId: activity.id, + }, + { + activityId: null, + taskId: activity.id, + }, + ); + } else { + throw new Error(`Unknown activity type: ${activity.type}`); + } + } + + // Hack to make sure the command is indempotent and return if one of the view exists + const viewExists = await queryRunner.manager + .createQueryBuilder() + .select() + .from(`${schema}.view`, 'view') + .where('name = :name', { name: 'All Notes' }) + .getRawOne(); + + if (!viewExists) { + await this.createViews( + objectMetadata, + queryRunner, + schema, + workspaceId, + ); + } + }; + + return this.sharedBoilerplate(_passedParam, options, updateActivities); + } + + private async createViews( + objectMetadata: ObjectMetadataEntity[], + queryRunner: QueryRunner, + schema: string, + workspaceId: string, + ) { + const objectMetadataMap = objectMetadata.reduce((acc, object) => { + acc[object.standardId ?? ''] = { + id: object.id, + fields: object.fields.reduce((acc, field) => { + acc[field.standardId ?? ''] = field.id; + + return acc; + }, {}), + }; + + return acc; + }, {}) as Record; + + const viewDefinitions = [ + await notesAllView(objectMetadataMap), + await tasksAllView(objectMetadataMap), + await tasksByStatusView(objectMetadataMap), + ]; + + const viewDefinitionsWithId = viewDefinitions.map((viewDefinition) => ({ + ...viewDefinition, + id: v4(), + })); + + await queryRunner.manager + .createQueryBuilder() + .insert() + .into(`${schema}.view`, [ + 'id', + 'name', + 'objectMetadataId', + 'type', + 'key', + 'position', + 'icon', + 'kanbanFieldMetadataId', + ]) + .values( + viewDefinitionsWithId.map( + ({ + id, + name, + objectMetadataId, + type, + key, + position, + icon, + kanbanFieldMetadataId, + }) => ({ + id, + name, + objectMetadataId, + type, + key, + position, + icon, + kanbanFieldMetadataId, + }), + ), + ) + .returning('*') + .execute(); + + for (const viewDefinition of viewDefinitionsWithId) { + if (viewDefinition.fields && viewDefinition.fields.length > 0) { + await queryRunner.manager + .createQueryBuilder() + .insert() + .into(`${schema}.viewField`, [ + 'fieldMetadataId', + 'position', + 'isVisible', + 'size', + 'viewId', + ]) + .values( + viewDefinition.fields.map((field) => ({ + fieldMetadataId: field.fieldMetadataId, + position: field.position, + isVisible: field.isVisible, + size: field.size, + viewId: viewDefinition.id, + })), + ) + .execute(); + } + + if (viewDefinition.filters && viewDefinition.filters.length > 0) { + await queryRunner.manager + .createQueryBuilder() + .insert() + .into(`${schema}.viewFilter`, [ + 'fieldMetadataId', + 'displayValue', + 'operand', + 'value', + 'viewId', + ]) + .values( + viewDefinition.filters.map((filter: any) => ({ + fieldMetadataId: filter.fieldMetadataId, + displayValue: filter.displayValue, + operand: filter.operand, + value: filter.value, + viewId: viewDefinition.id, + })), + ) + .execute(); + } + + await this.workspaceCacheVersionService.incrementVersion(workspaceId); + } + } + + // This is an attempt to do something more generic that could be reused in every command + // Next step if it works well for a few command is to isolated it into a file so + // it can be reused and not copy-pasted. + async sharedBoilerplate( + _passedParam: string[], + options: UpdateActivitiesCommandOptions, + coreLogic: CoreLogicFunction, + ) { + const workspaceIds = options.workspaceId + ? [options.workspaceId] + : await this.workspaceStatusService.getActiveWorkspaceIds(); + + if (!workspaceIds.length) { + this.logger.log(chalk.yellow('No workspace found')); + + return; + } + + this.logger.log( + chalk.green(`Running command on ${workspaceIds.length} workspaces`), + ); + + const requiresQueryRunner = + coreLogic.toString().includes('queryRunner') || + coreLogic.toString().includes('schema'); + + for (const workspaceId of workspaceIds) { + try { + if (requiresQueryRunner) { + await this.executeWithQueryRunner(workspaceId, coreLogic); + } else { + await coreLogic({ workspaceId }); + } + + this.logger.log( + chalk.green(`Running command on workspace ${workspaceId} done`), + ); + } catch (error) { + this.logger.error( + `Migration failed for workspace ${workspaceId}: ${error.message}, ${error.stack}`, + ); + } + } + + this.logger.log(chalk.green(`Command completed!`)); + } + + private async executeWithQueryRunner( + workspaceId: string, + coreLogic: CoreLogicFunction, + ) { + const dataSourceMetadatas = + await this.dataSourceService.getDataSourcesMetadataFromWorkspaceId( + workspaceId, + ); + + for (const dataSourceMetadata of dataSourceMetadatas) { + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); + + if (workspaceDataSource) { + const queryRunner = workspaceDataSource.createQueryRunner(); + + await queryRunner.connect(); + await queryRunner.startTransaction(); + + try { + await coreLogic({ + workspaceId, + queryRunner, + schema: dataSourceMetadata.schema, + }); + await queryRunner.commitTransaction(); + } catch (error) { + await queryRunner.rollbackTransaction(); + this.logger.log( + chalk.red(`Running command on workspace ${workspaceId} failed`), + ); + throw error; + } finally { + await queryRunner.release(); + } + } + } + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.command.ts index 2d5d21372..696cbac3e 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.command.ts @@ -4,6 +4,7 @@ import { MigrateDomainNameFromTextToLinksCommand } from 'src/database/commands/u import { MigrateLinkFieldsToLinksCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-link-fields-to-links.command'; import { MigrateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-message-channel-sync-status-enum.command'; import { SetWorkspaceActivationStatusCommand } from 'src/database/commands/upgrade-version/0-23/0-23-set-workspace-activation-status.command'; +import { UpdateActivitiesCommand } from 'src/database/commands/upgrade-version/0-23/0-23-update-activities.command'; interface Options { workspaceId?: string; @@ -19,6 +20,7 @@ export class UpgradeTo0_23Command extends CommandRunner { private readonly migrateDomainNameFromTextToLinks: MigrateDomainNameFromTextToLinksCommand, private readonly migrateMessageChannelSyncStatusEnumCommand: MigrateMessageChannelSyncStatusEnumCommand, private readonly setWorkspaceActivationStatusCommand: SetWorkspaceActivationStatusCommand, + private readonly updateActivitiesCommand: UpdateActivitiesCommand, ) { super(); } @@ -41,5 +43,6 @@ export class UpgradeTo0_23Command extends CommandRunner { options, ); await this.setWorkspaceActivationStatusCommand.run(_passedParam, options); + await this.updateActivitiesCommand.run(_passedParam, options); } } diff --git a/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.module.ts b/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.module.ts index 1ff3602b8..c259f63cf 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version/0-23/0-23-upgrade-version.module.ts @@ -5,6 +5,7 @@ import { MigrateDomainNameFromTextToLinksCommand } from 'src/database/commands/u import { MigrateLinkFieldsToLinksCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-link-fields-to-links.command'; import { MigrateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-message-channel-sync-status-enum.command'; import { SetWorkspaceActivationStatusCommand } from 'src/database/commands/upgrade-version/0-23/0-23-set-workspace-activation-status.command'; +import { UpdateActivitiesCommand } from 'src/database/commands/upgrade-version/0-23/0-23-update-activities.command'; import { UpgradeTo0_23Command } from 'src/database/commands/upgrade-version/0-23/0-23-upgrade-version.command'; import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; @@ -13,6 +14,7 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; import { WorkspaceStatusModule } from 'src/engine/workspace-manager/workspace-status/workspace-manager.module'; import { ViewModule } from 'src/modules/view/view.module'; @@ -29,12 +31,14 @@ import { ViewModule } from 'src/modules/view/view.module'; TypeORMModule, ViewModule, BillingModule, + ObjectMetadataModule, ], providers: [ MigrateLinkFieldsToLinksCommand, MigrateDomainNameFromTextToLinksCommand, MigrateMessageChannelSyncStatusEnumCommand, SetWorkspaceActivationStatusCommand, + UpdateActivitiesCommand, UpgradeTo0_23Command, ], }) diff --git a/packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.command.ts b/packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.command.ts new file mode 100644 index 000000000..0fc4fa9f8 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.command.ts @@ -0,0 +1,128 @@ +import { Logger } from '@nestjs/common'; +import { isUndefined } from '@nestjs/common/utils/shared.utils'; + +import * as fs from 'fs'; +import * as path from 'path'; + +import chalk from 'chalk'; +import { Command, CommandRunner, Option } from 'nest-commander'; +import * as semver from 'semver'; + +import { MigrateDomainNameFromTextToLinksCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-domain-to-links.command'; +import { MigrateLinkFieldsToLinksCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-link-fields-to-links.command'; +import { MigrateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-message-channel-sync-status-enum.command'; +import { SetWorkspaceActivationStatusCommand } from 'src/database/commands/upgrade-version/0-23/0-23-set-workspace-activation-status.command'; +import { UpdateActivitiesCommand } from 'src/database/commands/upgrade-version/0-23/0-23-update-activities.command'; + +interface UpgradeCommandOptions { + workspaceId?: string; +} + +type VersionUpgradeMap = { + [version: string]: CommandRunner[]; +}; + +@Command({ + name: 'upgrade-version', + description: 'Upgrade to a specific version', +}) +export class UpgradeVersionCommand extends CommandRunner { + private readonly logger = new Logger(UpgradeVersionCommand.name); + + constructor( + private readonly migrateLinkFieldsToLinksCommand: MigrateLinkFieldsToLinksCommand, + private readonly migrateDomainNameFromTextToLinksCommand: MigrateDomainNameFromTextToLinksCommand, + private readonly migrateMessageChannelSyncStatusEnumCommand: MigrateMessageChannelSyncStatusEnumCommand, + private readonly setWorkspaceActivationStatusCommand: SetWorkspaceActivationStatusCommand, + private readonly updateActivitiesCommand: UpdateActivitiesCommand, + ) { + super(); + } + + @Option({ + flags: '-v, --version ', + description: 'Version to upgrade to', + required: true, + }) + parseVersion(value: string): string { + return value; + } + + @Option({ + flags: '-w, --workspace-id [workspace_id]', + description: 'workspace id. Command runs on all workspaces if not provided', + required: false, + }) + parseWorkspaceId(value: string): string { + return value; + } + + async run( + passedParams: string[], + options: UpgradeCommandOptions & { version: string }, + ): Promise { + const { version, ...upgradeOptions } = options; + + const versionUpgradeMap = { + '0.23': [ + this.migrateLinkFieldsToLinksCommand, + this.migrateDomainNameFromTextToLinksCommand, + this.migrateMessageChannelSyncStatusEnumCommand, + this.setWorkspaceActivationStatusCommand, + this.updateActivitiesCommand, + ], + }; + + await this.validateVersions(version, versionUpgradeMap); + + if (!versionUpgradeMap[version]) { + throw new Error( + `No migration commands found for version ${version}. This could mean there were no database changes required for this version.`, + ); + } + + for (const command of versionUpgradeMap[version]) { + await command.run(passedParams, upgradeOptions); + } + + this.logger.log(chalk.green(`Successfully upgraded to version ${version}`)); + } + + private async getCurrentCodeVersion(): Promise { + const packageJsonPath = path.join(process.cwd(), 'package.json'); + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + + return packageJson.version; + } + + private async validateVersions( + targetVersion: string, + versionUpgradeMap: VersionUpgradeMap, + ): Promise { + const currentVersion = await this.getCurrentCodeVersion(); + + const cleanCurrentVersion = semver.coerce(currentVersion); + const cleanTargetVersion = semver.coerce(targetVersion); + + if (!cleanCurrentVersion || !cleanTargetVersion) { + throw new Error( + `Invalid version format. Current Code: ${currentVersion}, Target: ${targetVersion}`, + ); + } + + const targetMajorMinor = `${cleanTargetVersion.major}.${cleanTargetVersion.minor}`; + + if ( + semver.gt(cleanTargetVersion, cleanCurrentVersion) && + isUndefined(versionUpgradeMap[targetMajorMinor]) + ) { + throw new Error( + `Cannot upgrade to ${cleanTargetVersion}. Your current code version is ${cleanCurrentVersion}. Please update your codebase or upgrade your Docker image first.`, + ); + } + + this.logger.log( + `Current Code Version: ${currentVersion}, Target: ${targetVersion}`, + ); + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.module.ts b/packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.module.ts new file mode 100644 index 000000000..c4eda860c --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version/upgrade-version.module.ts @@ -0,0 +1,62 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module'; +import { MigrateDomainNameFromTextToLinksCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-domain-to-links.command'; +import { MigrateLinkFieldsToLinksCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-link-fields-to-links.command'; +import { MigrateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/upgrade-version/0-23/0-23-migrate-message-channel-sync-status-enum.command'; +import { SetWorkspaceActivationStatusCommand } from 'src/database/commands/upgrade-version/0-23/0-23-set-workspace-activation-status.command'; +import { UpdateActivitiesCommand } from 'src/database/commands/upgrade-version/0-23/0-23-update-activities.command'; +import { UpgradeVersionCommand } from 'src/database/commands/upgrade-version/upgrade-version.command'; +import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; +import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; +import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity'; +import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; +import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; +import { WorkspaceStatusModule } from 'src/engine/workspace-manager/workspace-status/workspace-manager.module'; +import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module'; +import { ViewModule } from 'src/modules/view/view.module'; + +@Module({ + imports: [ + WorkspaceManagerModule, + DataSourceModule, + TypeORMModule, + TypeOrmModule.forFeature( + [Workspace, BillingSubscription, FeatureFlagEntity], + 'core', + ), + TypeOrmModule.forFeature( + [FieldMetadataEntity, ObjectMetadataEntity], + 'metadata', + ), + WorkspaceModule, + WorkspaceDataSourceModule, + WorkspaceSyncMetadataModule, + WorkspaceStatusModule, + ObjectMetadataModule, + DataSeedDemoWorkspaceModule, + WorkspaceCacheVersionModule, + FieldMetadataModule, + ViewModule, + BillingModule, + ], + providers: [ + UpgradeVersionCommand, + MigrateLinkFieldsToLinksCommand, + MigrateDomainNameFromTextToLinksCommand, + MigrateMessageChannelSyncStatusEnumCommand, + SetWorkspaceActivationStatusCommand, + UpdateActivitiesCommand, + ], +}) +export class UpgradeVersionModule {} diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/demo/workspaces.ts b/packages/twenty-server/src/database/typeorm-seeds/core/demo/workspaces.ts index bc0b3c93b..6a4758b71 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/demo/workspaces.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/demo/workspaces.ts @@ -1,5 +1,7 @@ import { DataSource } from 'typeorm'; +import { WorkspaceActivationStatus } from 'src/engine/core-modules/workspace/workspace.entity'; + const tableName = 'workspace'; export const seedWorkspaces = async ( @@ -16,6 +18,7 @@ export const seedWorkspaces = async ( 'domainName', 'inviteHash', 'logo', + 'activationStatus', ]) .orIgnore() .values([ @@ -25,6 +28,7 @@ export const seedWorkspaces = async ( domainName: 'demo.dev', inviteHash: 'demo.dev-invite-hash', logo: 'https://twentyhq.github.io/placeholder-images/workspaces/apple-logo.png', + activationStatus: WorkspaceActivationStatus.ACTIVE, }, ]) .execute(); diff --git a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts index d988d614a..4fd127e27 100644 --- a/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts +++ b/packages/twenty-server/src/engine/api/__mocks__/object-metadata-item.mock.ts @@ -189,6 +189,13 @@ const fieldRawJsonMock = { defaultValue: null, }; +const fieldRichTextMock = { + name: 'fieldRichText', + type: FieldMetadataType.RICH_TEXT, + isNullable: true, + defaultValue: null, +}; + export const fields = [ fieldUuidMock, fieldTextMock, @@ -210,6 +217,7 @@ export const fields = [ fieldPositionMock, fieldAddressMock, fieldRawJsonMock, + fieldRichTextMock, ]; export const objectMetadataItemMock = { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts index 161ee31a5..9656430d9 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts @@ -16,25 +16,25 @@ import { import { FieldMetadataSettings } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface'; -import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum'; import { - StringFilterType, + BigFloatFilterType, + BooleanFilterType, DateFilterType, FloatFilterType, - BooleanFilterType, - BigFloatFilterType, RawJsonFilterType, + StringFilterType, } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input'; -import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum'; +import { IDFilterType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/id-filter.input-type'; import { BigFloatScalarType, UUIDScalarType, } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { PositionScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/position.scalar'; import { RawJSONScalar } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars/raw-json.scalar'; -import { IDFilterType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/id-filter.input-type'; import { getNumberFilterType } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-number-filter-type.util'; import { getNumberScalarType } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-number-scalar-type.util'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; export interface TypeOptions { nullable?: boolean; @@ -74,6 +74,7 @@ export class TypeMapperService { [FieldMetadataType.NUMERIC, BigFloatScalarType], [FieldMetadataType.POSITION, PositionScalarType], [FieldMetadataType.RAW_JSON, RawJSONScalar], + [FieldMetadataType.RICH_TEXT, GraphQLString], ]); return typeScalarMapping.get(fieldMetadataType); @@ -109,6 +110,7 @@ export class TypeMapperService { [FieldMetadataType.NUMERIC, BigFloatFilterType], [FieldMetadataType.POSITION, FloatFilterType], [FieldMetadataType.RAW_JSON, RawJsonFilterType], + [FieldMetadataType.RICH_TEXT, StringFilterType], ]); return typeFilterMapping.get(fieldMetadataType); @@ -132,6 +134,7 @@ export class TypeMapperService { [FieldMetadataType.MULTI_SELECT, OrderByDirectionType], [FieldMetadataType.POSITION, OrderByDirectionType], [FieldMetadataType.RAW_JSON, OrderByDirectionType], + [FieldMetadataType.RICH_TEXT, OrderByDirectionType], ]); return typeOrderByMapping.get(fieldMetadataType); diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts index 8b22e2f71..1f337f499 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/map-field-metadata-to-graphql-query.utils.ts @@ -30,6 +30,7 @@ export const mapFieldMetadataToGraphqlQuery = ( FieldMetadataType.MULTI_SELECT, FieldMetadataType.POSITION, FieldMetadataType.RAW_JSON, + FieldMetadataType.RICH_TEXT, ].includes(fieldType); if (fieldIsSimpleValue) { diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts index 09d864377..97a8b79e3 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/__tests__/components.utils.spec.ts @@ -1,10 +1,10 @@ -import { computeSchemaComponents } from 'src/engine/core-modules/open-api/utils/components.utils'; import { fields, objectMetadataItemMock, } from 'src/engine/api/__mocks__/object-metadata-item.mock'; -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { computeSchemaComponents } from 'src/engine/core-modules/open-api/utils/components.utils'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; describe('computeSchemaComponents', () => { it('should test all field types', () => { @@ -134,6 +134,9 @@ describe('computeSchemaComponents', () => { fieldRawJson: { type: 'object', }, + fieldRichText: { + type: 'string', + }, }, }, 'ObjectName with Relations': { diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts index 6d65e82a2..74b72c67d 100644 --- a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts @@ -1,8 +1,5 @@ import { OpenAPIV3_1 } from 'openapi-types'; -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { capitalize } from 'src/utils/capitalize'; import { computeDepthParameters, computeEndingBeforeParameters, @@ -13,6 +10,9 @@ import { computeStartingAfterParameters, } from 'src/engine/core-modules/open-api/utils/parameters.utils'; import { compositeTypeDefintions } from 'src/engine/metadata-modules/field-metadata/composite-types'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { capitalize } from 'src/utils/capitalize'; type Property = OpenAPIV3_1.SchemaObject; @@ -26,6 +26,7 @@ const getFieldProperties = (type: FieldMetadataType): Property => { return { type: 'string', format: 'uuid' }; case FieldMetadataType.TEXT: case FieldMetadataType.PHONE: + case FieldMetadataType.RICH_TEXT: return { type: 'string' }; case FieldMetadataType.EMAIL: return { type: 'string', format: 'email' }; diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts index 39f6f7556..5cb2cac07 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts @@ -33,6 +33,11 @@ export class FieldMetadataDefaultValueRawJson { value: object | null; } +export class FieldMetadataDefaultValueRichText { + @ValidateIf((_object, value) => value !== null) + @IsString() + value: string | null; +} export class FieldMetadataDefaultValueNumber { @ValidateIf((object, value) => value !== null) @IsNumber() @@ -105,6 +110,7 @@ export class FieldMetadataDefaultValueNowFunction { @IsNotEmpty() value: typeof fieldMetadataDefaultValueFunctionName.NOW; } + export class FieldMetadataDefaultValueAddress { @ValidateIf((_object, value) => value !== null) @IsString() diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts index 5a80230f7..12e3b6af1 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts @@ -1,25 +1,25 @@ import { - Entity, - Unique, - PrimaryGeneratedColumn, Column, - ManyToOne, - JoinColumn, - OneToOne, CreateDateColumn, - UpdateDateColumn, - Relation, + Entity, + JoinColumn, + ManyToOne, OneToMany, + OneToOne, + PrimaryGeneratedColumn, + Relation, + Unique, + UpdateDateColumn, } from 'typeorm'; -import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface'; import { FieldMetadataSettings } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface'; +import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-field-metadata/index-field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; -import { IndexFieldMetadataEntity } from 'src/engine/metadata-modules/index-field-metadata/index-field-metadata.entity'; export enum FieldMetadataType { UUID = 'UUID', @@ -42,6 +42,7 @@ export enum FieldMetadataType { POSITION = 'POSITION', ADDRESS = 'ADDRESS', RAW_JSON = 'RAW_JSON', + RICH_TEXT = 'RICH_TEXT', } @Entity('fieldMetadata') diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts index f3e24005c..61d4f09ba 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts @@ -4,13 +4,14 @@ import { FieldMetadataDefaultValueCurrency, FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueFullName, - FieldMetadataDefaultValueRawJson, FieldMetadataDefaultValueLink, + FieldMetadataDefaultValueLinks, + FieldMetadataDefaultValueNowFunction, FieldMetadataDefaultValueNumber, + FieldMetadataDefaultValueRawJson, + FieldMetadataDefaultValueRichText, FieldMetadataDefaultValueString, FieldMetadataDefaultValueUuidFunction, - FieldMetadataDefaultValueNowFunction, - FieldMetadataDefaultValueLinks, } from 'src/engine/metadata-modules/field-metadata/dtos/default-value.input'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; @@ -44,6 +45,7 @@ type FieldMetadataDefaultValueMapping = { [FieldMetadataType.SELECT]: FieldMetadataDefaultValueString; [FieldMetadataType.MULTI_SELECT]: FieldMetadataDefaultValueString; [FieldMetadataType.RAW_JSON]: FieldMetadataDefaultValueRawJson; + [FieldMetadataType.RICH_TEXT]: FieldMetadataDefaultValueRichText; }; export type FieldMetadataClassValidation = diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts index 776c49db6..15fca239e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts @@ -6,23 +6,23 @@ import { FieldMetadataDefaultValue, } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface'; -import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FieldMetadataDefaultValueAddress, FieldMetadataDefaultValueBoolean, FieldMetadataDefaultValueCurrency, + FieldMetadataDefaultValueDate, FieldMetadataDefaultValueDateTime, FieldMetadataDefaultValueFullName, - FieldMetadataDefaultValueRawJson, FieldMetadataDefaultValueLink, + FieldMetadataDefaultValueLinks, + FieldMetadataDefaultValueNowFunction, FieldMetadataDefaultValueNumber, + FieldMetadataDefaultValueRawJson, FieldMetadataDefaultValueString, FieldMetadataDefaultValueStringArray, - FieldMetadataDefaultValueNowFunction, FieldMetadataDefaultValueUuidFunction, - FieldMetadataDefaultValueDate, - FieldMetadataDefaultValueLinks, } from 'src/engine/metadata-modules/field-metadata/dtos/default-value.input'; +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util'; export const defaultValueValidatorsMap = { @@ -48,6 +48,7 @@ export const defaultValueValidatorsMap = { [FieldMetadataType.SELECT]: [FieldMetadataDefaultValueString], [FieldMetadataType.MULTI_SELECT]: [FieldMetadataDefaultValueStringArray], [FieldMetadataType.ADDRESS]: [FieldMetadataDefaultValueAddress], + [FieldMetadataType.RICH_TEXT]: [FieldMetadataDefaultValueString], [FieldMetadataType.RAW_JSON]: [FieldMetadataDefaultValueRawJson], [FieldMetadataType.LINKS]: [FieldMetadataDefaultValueLinks], }; diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts index 5c4f64213..b1de619ef 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts @@ -15,6 +15,7 @@ export const fieldMetadataTypeToColumnType = ( case FieldMetadataType.UUID: return 'uuid'; case FieldMetadataType.TEXT: + case FieldMetadataType.RICH_TEXT: return 'text'; case FieldMetadataType.PHONE: case FieldMetadataType.EMAIL: diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts index 02dcfe59a..9e479d2c9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts @@ -1,17 +1,17 @@ import { Injectable, Logger } from '@nestjs/common'; -import { WorkspaceColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-factory.interface'; import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface'; +import { WorkspaceColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-factory.interface'; import { WorkspaceColumnActionOptions } from 'src/engine/metadata-modules/workspace-migration/interfaces/workspace-column-action-options.interface'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { BasicColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory'; +import { CompositeColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory'; +import { EnumColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory'; import { WorkspaceMigrationColumnAction, WorkspaceMigrationColumnActionType, } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; -import { BasicColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory'; -import { EnumColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/enum-column-action.factory'; -import { CompositeColumnActionFactory } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory'; import { WorkspaceMigrationException, WorkspaceMigrationExceptionCode, @@ -72,6 +72,7 @@ export class WorkspaceMigrationFactory { [FieldMetadataType.NUMBER, { factory: this.basicColumnActionFactory }], [FieldMetadataType.POSITION, { factory: this.basicColumnActionFactory }], [FieldMetadataType.RAW_JSON, { factory: this.basicColumnActionFactory }], + [FieldMetadataType.RICH_TEXT, { factory: this.basicColumnActionFactory }], [FieldMetadataType.BOOLEAN, { factory: this.basicColumnActionFactory }], [FieldMetadataType.DATE_TIME, { factory: this.basicColumnActionFactory }], [FieldMetadataType.DATE, { factory: this.basicColumnActionFactory }], diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.service.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.service.ts index c12c6cb71..d12ed2493 100644 --- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.service.ts @@ -24,13 +24,29 @@ export class WorkspaceMigrationService { public async getPendingMigrations( workspaceId: string, ): Promise { - return await this.workspaceMigrationRepository.find({ + const pendingMigrations = await this.workspaceMigrationRepository.find({ order: { createdAt: 'ASC', name: 'ASC' }, where: { appliedAt: IsNull(), workspaceId, }, }); + + const typeOrder = { delete: 1, update: 2, create: 3 }; + + const getType = (name: string) => + name.split('-')[1] as keyof typeof typeOrder; + + return pendingMigrations.sort((a, b) => { + if (a.createdAt.getTime() !== b.createdAt.getTime()) { + return a.createdAt.getTime() - b.createdAt.getTime(); + } + + return ( + (typeOrder[getType(a.name)] || 4) - (typeOrder[getType(b.name)] || 4) || + a.name.localeCompare(b.name) + ); + }); } /** diff --git a/packages/twenty-server/src/engine/twenty-orm/custom.workspace-entity.ts b/packages/twenty-server/src/engine/twenty-orm/custom.workspace-entity.ts index 56f9238d2..ec54a9c8b 100644 --- a/packages/twenty-server/src/engine/twenty-orm/custom.workspace-entity.ts +++ b/packages/twenty-server/src/engine/twenty-orm/custom.workspace-entity.ts @@ -3,17 +3,19 @@ import { RelationMetadataType, RelationOnDeleteAction, } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; -import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity'; -import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; -import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; -import { CUSTOM_OBJECT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; +import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { WorkspaceCustomObject } from 'src/engine/twenty-orm/decorators/workspace-custom-object.decorator'; import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; -import { WorkspaceCustomObject } from 'src/engine/twenty-orm/decorators/workspace-custom-object.decorator'; -import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { CUSTOM_OBJECT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity'; +import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; +import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; +import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity'; +import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; +import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; @WorkspaceCustomObject() export class CustomWorkspaceEntity extends BaseWorkspaceEntity { @@ -51,6 +53,32 @@ export class CustomWorkspaceEntity extends BaseWorkspaceEntity { @WorkspaceIsNullable() activityTargets: ActivityTargetWorkspaceEntity[]; + @WorkspaceRelation({ + standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.noteTargets, + label: 'Notes', + type: RelationMetadataType.ONE_TO_MANY, + description: (objectMetadata) => + `Notes tied to the ${objectMetadata.labelSingular}`, + icon: 'IconNotes', + inverseSideTarget: () => NoteTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @WorkspaceIsNullable() + noteTargets: NoteTargetWorkspaceEntity[]; + + @WorkspaceRelation({ + standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.taskTargets, + label: 'Tasks', + type: RelationMetadataType.ONE_TO_MANY, + description: (objectMetadata) => + `Tasks tied to the ${objectMetadata.labelSingular}`, + icon: 'IconCheckbox', + inverseSideTarget: () => TaskTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + @WorkspaceIsNullable() + taskTargets: TaskTargetWorkspaceEntity[]; + @WorkspaceRelation({ standardId: CUSTOM_OBJECT_STANDARD_FIELD_IDS.favorites, label: 'Favorites', diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/pipeline-step.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/pipeline-step.ts deleted file mode 100644 index bbf86f127..000000000 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/pipeline-step.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { EntityManager } from 'typeorm'; - -export const pipelineStepPrefillData = async ( - entityManager: EntityManager, - schemaName: string, -) => { - await entityManager - .createQueryBuilder() - .insert() - .into(`${schemaName}.pipelineStep`, ['name', 'color', 'position']) - .orIgnore() - .values([ - { - name: 'NEW', - color: 'red', - position: 0, - }, - { - name: 'SCREENING', - color: 'purple', - position: 1, - }, - { - name: 'MEETING', - color: 'sky', - position: 2, - }, - { - name: 'PROPOSAL', - color: 'turquoise', - position: 3, - }, - { - name: 'CUSTOMER', - color: 'yellow', - position: 4, - }, - ]) - .returning('*') - .execute(); -}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts deleted file mode 100644 index c81500e83..000000000 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { - BASE_OBJECT_STANDARD_FIELD_IDS, - COMPANY_STANDARD_FIELD_IDS, -} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; - -export const viewCompanyFields = ( - viewId: string, - objectMetadataMap: Record, -) => { - return [ - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ - COMPANY_STANDARD_FIELD_IDS.name - ], - viewId: viewId, - position: 0, - isVisible: true, - size: 180, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ - COMPANY_STANDARD_FIELD_IDS.domainName - ], - viewId: viewId, - position: 1, - isVisible: true, - size: 100, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ - COMPANY_STANDARD_FIELD_IDS.accountOwner - ], - viewId: viewId, - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ - BASE_OBJECT_STANDARD_FIELD_IDS.createdAt - ], - viewId: viewId, - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ - COMPANY_STANDARD_FIELD_IDS.employees - ], - viewId: viewId, - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ - COMPANY_STANDARD_FIELD_IDS.linkedinLink - ], - viewId: viewId, - position: 5, - isVisible: true, - size: 170, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ - COMPANY_STANDARD_FIELD_IDS.address - ], - viewId: viewId, - position: 6, - isVisible: true, - size: 170, - }, - ]; -}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts deleted file mode 100644 index baa08a95f..000000000 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; - -export const viewOpportunityFields = ( - viewId: string, - objectMetadataMap: Record, -) => { - return [ - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ - OPPORTUNITY_STANDARD_FIELD_IDS.name - ], - viewId: viewId, - position: 0, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ - OPPORTUNITY_STANDARD_FIELD_IDS.amount - ], - viewId: viewId, - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ - OPPORTUNITY_STANDARD_FIELD_IDS.closeDate - ], - viewId: viewId, - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ - OPPORTUNITY_STANDARD_FIELD_IDS.company - ], - viewId: viewId, - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ - OPPORTUNITY_STANDARD_FIELD_IDS.pointOfContact - ], - viewId: viewId, - position: 5, - isVisible: true, - size: 150, - }, - ]; -}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts deleted file mode 100644 index 16c7841f2..000000000 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { - BASE_OBJECT_STANDARD_FIELD_IDS, - PERSON_STANDARD_FIELD_IDS, -} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; - -export const viewPersonFields = ( - viewId: string, - objectMetadataMap: Record, -) => { - return [ - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.name - ], - viewId: viewId, - position: 0, - isVisible: true, - size: 210, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.email - ], - viewId: viewId, - position: 1, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.company - ], - viewId: viewId, - position: 2, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.phone - ], - viewId: viewId, - position: 3, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - BASE_OBJECT_STANDARD_FIELD_IDS.createdAt - ], - viewId: viewId, - position: 4, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.city - ], - viewId: viewId, - position: 5, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.jobTitle - ], - viewId: viewId, - position: 6, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.linkedinLink - ], - viewId: viewId, - position: 7, - isVisible: true, - size: 150, - }, - { - fieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ - PERSON_STANDARD_FIELD_IDS.xLink - ], - viewId: viewId, - position: 8, - isVisible: true, - size: 150, - }, - ]; -}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts index 2d157597f..2cd30b1a9 100644 --- a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/view.ts @@ -1,21 +1,42 @@ import { EntityManager } from 'typeorm'; +import { v4 } from 'uuid'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; -import { viewCompanyFields } from 'src/engine/workspace-manager/standard-objects-prefill-data/view-company-fields'; -import { viewOpportunityFields } from 'src/engine/workspace-manager/standard-objects-prefill-data/view-opportunity-fields'; -import { viewPersonFields } from 'src/engine/workspace-manager/standard-objects-prefill-data/view-person-fields'; -import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { activitiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/activities-all.view'; +import { companiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view'; +import { notesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view'; +import { opportunitiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/opportunities-all.view'; +import { opportunitiesByStageView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-by-stage.view'; +import { peopleAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/people-all.view'; +import { tasksAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view'; +import { tasksByStatusView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view'; export const viewPrefillData = async ( entityManager: EntityManager, schemaName: string, objectMetadataMap: Record, ) => { - const createdViews = await entityManager + const viewDefinitions = [ + await companiesAllView(objectMetadataMap), + await peopleAllView(objectMetadataMap), + await opportunitiesAllView(objectMetadataMap), + await opportunitiesByStageView(objectMetadataMap), + await activitiesAllView(objectMetadataMap), + await notesAllView(objectMetadataMap), + await tasksAllView(objectMetadataMap), + await tasksByStatusView(objectMetadataMap), + ]; + + const viewDefinitionsWithId = viewDefinitions.map((viewDefinition) => ({ + ...viewDefinition, + id: v4(), + })); + + await entityManager .createQueryBuilder() .insert() .into(`${schemaName}.view`, [ + 'id', 'name', 'objectMetadataId', 'type', @@ -24,74 +45,77 @@ export const viewPrefillData = async ( 'icon', 'kanbanFieldMetadataId', ]) - .values([ - { - name: 'All Companies', - objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.company].id, - type: 'table', - key: 'INDEX', - position: 0, - icon: 'IconBuildingSkyscraper', - kanbanFieldMetadataId: '', - }, - { - name: 'All People', - objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.person].id, - type: 'table', - key: 'INDEX', - position: 0, - icon: 'IconUser', - kanbanFieldMetadataId: '', - }, - { - name: 'All Opportunities', - objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].id, - type: 'table', - key: 'INDEX', - position: 0, - icon: 'IconTargetArrow', - kanbanFieldMetadataId: '', - }, - { - name: 'By Stage', - objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].id, - type: 'kanban', - key: null, - position: 1, - icon: 'IconLayoutKanban', - kanbanFieldMetadataId: - objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ - OPPORTUNITY_STANDARD_FIELD_IDS.stage - ], - }, - ]) + .values( + viewDefinitionsWithId.map( + ({ + id, + name, + objectMetadataId, + type, + key, + position, + icon, + kanbanFieldMetadataId, + }) => ({ + id, + name, + objectMetadataId, + type, + key, + position, + icon, + kanbanFieldMetadataId, + }), + ), + ) .returning('*') .execute(); - const viewIdMap = createdViews.raw.reduce((acc, view) => { - acc[view.name] = view.id; + for (const viewDefinition of viewDefinitionsWithId) { + if (viewDefinition.fields && viewDefinition.fields.length > 0) { + await entityManager + .createQueryBuilder() + .insert() + .into(`${schemaName}.viewField`, [ + 'fieldMetadataId', + 'position', + 'isVisible', + 'size', + 'viewId', + ]) + .values( + viewDefinition.fields.map((field) => ({ + fieldMetadataId: field.fieldMetadataId, + position: field.position, + isVisible: field.isVisible, + size: field.size, + viewId: viewDefinition.id, + })), + ) + .execute(); + } - return acc; - }, {}); - - await entityManager - .createQueryBuilder() - .insert() - .into(`${schemaName}.viewField`, [ - 'fieldMetadataId', - 'viewId', - 'position', - 'isVisible', - 'size', - ]) - .values([ - ...viewCompanyFields(viewIdMap['All Companies'], objectMetadataMap), - ...viewPersonFields(viewIdMap['All People'], objectMetadataMap), - ...viewOpportunityFields( - viewIdMap['All Opportunities'], - objectMetadataMap, - ), - ...viewOpportunityFields(viewIdMap['By Stage'], objectMetadataMap), - ]) - .execute(); + if (viewDefinition.filters && viewDefinition.filters.length > 0) { + await entityManager + .createQueryBuilder() + .insert() + .into(`${schemaName}.viewFilter`, [ + 'fieldMetadataId', + 'displayValue', + 'operand', + 'value', + 'viewId', + ]) + .values( + viewDefinition.filters.map((filter: any) => ({ + fieldMetadataId: filter.fieldMetadataId, + displayValue: filter.displayValue, + operand: filter.operand, + value: filter.value, + viewId: viewDefinition.id, + })), + ) + .execute(); + } + } }; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/activities-all.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/activities-all.view.ts new file mode 100644 index 000000000..8988b7606 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/activities-all.view.ts @@ -0,0 +1,71 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + ACTIVITY_STANDARD_FIELD_IDS, + BASE_OBJECT_STANDARD_FIELD_IDS, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const activitiesAllView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'All', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.activity].id, + type: 'table', + key: 'INDEX', + position: 1, + icon: 'IconList', + kanbanFieldMetadataId: '', + filters: [], + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.activity].fields[ + ACTIVITY_STANDARD_FIELD_IDS.title + ], + position: 0, + isVisible: true, + size: 210, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.activity].fields[ + ACTIVITY_STANDARD_FIELD_IDS.type + ], + position: 0, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.activity].fields[ + ACTIVITY_STANDARD_FIELD_IDS.body + ], + position: 0, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.activity].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.createdAt + ], + position: 0, + isVisible: true, + size: 150, + }, + /* + TODO: Add later, since we don't have real-time it probably doesn't work well? + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.activity].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt + ], + position: 0, + isVisible: true, + size: 210, + }, + */ + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view.ts new file mode 100644 index 000000000..c20772255 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view.ts @@ -0,0 +1,86 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + BASE_OBJECT_STANDARD_FIELD_IDS, + COMPANY_STANDARD_FIELD_IDS, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const companiesAllView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'All', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.company].id, + type: 'table', + key: 'INDEX', + position: 0, + icon: 'IconList', + kanbanFieldMetadataId: '', + filters: [], + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ + COMPANY_STANDARD_FIELD_IDS.name + ], + position: 0, + isVisible: true, + size: 180, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ + COMPANY_STANDARD_FIELD_IDS.domainName + ], + position: 1, + isVisible: true, + size: 100, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ + COMPANY_STANDARD_FIELD_IDS.accountOwner + ], + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.createdAt + ], + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ + COMPANY_STANDARD_FIELD_IDS.employees + ], + position: 4, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ + COMPANY_STANDARD_FIELD_IDS.linkedinLink + ], + position: 5, + isVisible: true, + size: 170, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.company].fields[ + COMPANY_STANDARD_FIELD_IDS.address + ], + position: 6, + isVisible: true, + size: 170, + }, + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view.ts new file mode 100644 index 000000000..e60512dcf --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view.ts @@ -0,0 +1,62 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + BASE_OBJECT_STANDARD_FIELD_IDS, + NOTE_STANDARD_FIELD_IDS, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const notesAllView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'All Notes', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.note].id, + type: 'table', + key: null, + position: 0, + icon: 'IconNotes', + kanbanFieldMetadataId: '', + filters: [], + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[ + NOTE_STANDARD_FIELD_IDS.title + ], + position: 0, + isVisible: true, + size: 210, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[ + NOTE_STANDARD_FIELD_IDS.body + ], + position: 0, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.createdAt + ], + position: 0, + isVisible: true, + size: 150, + }, + /* + TODO: Add later, since we don't have real-time it probably doesn't work well? + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.activity].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt + ], + position: 0, + isVisible: true, + size: 210, + }, + */ + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunities-all.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunities-all.view.ts new file mode 100644 index 000000000..47f68251d --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunities-all.view.ts @@ -0,0 +1,65 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const opportunitiesAllView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'All', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].id, + type: 'table', + key: 'INDEX', + position: 0, + icon: 'IconList', + kanbanFieldMetadataId: '', + filters: [], + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.name + ], + position: 0, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.amount + ], + position: 1, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.closeDate + ], + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.company + ], + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.pointOfContact + ], + position: 5, + isVisible: true, + size: 150, + }, + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-by-stage.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-by-stage.view.ts new file mode 100644 index 000000000..23f76456f --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-by-stage.view.ts @@ -0,0 +1,68 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const opportunitiesByStageView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'By Stage', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].id, + type: 'kanban', + key: null, + position: 1, + icon: 'IconLayoutKanban', + kanbanFieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.stage + ], + filters: [], + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.name + ], + position: 0, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.amount + ], + position: 1, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.closeDate + ], + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.company + ], + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.opportunity].fields[ + OPPORTUNITY_STANDARD_FIELD_IDS.pointOfContact + ], + position: 5, + isVisible: true, + size: 150, + }, + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/people-all.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/people-all.view.ts new file mode 100644 index 000000000..6f6903839 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/people-all.view.ts @@ -0,0 +1,104 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + BASE_OBJECT_STANDARD_FIELD_IDS, + PERSON_STANDARD_FIELD_IDS, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const peopleAllView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'All', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.person].id, + type: 'table', + key: 'INDEX', + position: 0, + icon: 'IconList', + kanbanFieldMetadataId: '', + filters: [], + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.name + ], + position: 0, + isVisible: true, + size: 210, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.email + ], + position: 1, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.company + ], + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.phone + ], + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.createdAt + ], + position: 4, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.city + ], + position: 5, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.jobTitle + ], + position: 6, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.linkedinLink + ], + position: 7, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.person].fields[ + PERSON_STANDARD_FIELD_IDS.xLink + ], + position: 8, + isVisible: true, + size: 150, + }, + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view.ts new file mode 100644 index 000000000..1ca193968 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view.ts @@ -0,0 +1,99 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + BASE_OBJECT_STANDARD_FIELD_IDS, + TASK_STANDARD_FIELD_IDS, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const tasksAllView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'All Tasks', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.task].id, + type: 'table', + key: null, + position: 0, + icon: 'IconCheckbox', + kanbanFieldMetadataId: '', + filters: [] /* [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.type + ], + displayValue: 'Task', + operand: 'is', + value: '["TASK"]', + }, + ],*/, + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.title + ], + position: 0, + isVisible: true, + size: 210, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.status + ], + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.dueAt + ], + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.assignee + ], + position: 4, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.body + ], + position: 5, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.createdAt + ], + position: 6, + isVisible: true, + size: 150, + }, + /* + TODO: Add later, since we don't have real-time it probably doesn't work well? + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt + ], + position: 0, + isVisible: true, + size: 210, + }, + */ + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view.ts new file mode 100644 index 000000000..fe392c181 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view.ts @@ -0,0 +1,93 @@ +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { + BASE_OBJECT_STANDARD_FIELD_IDS, + TASK_STANDARD_FIELD_IDS, +} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; + +export const tasksByStatusView = async ( + objectMetadataMap: Record, +) => { + return { + name: 'By status', + objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.task].id, + type: 'kanban', + key: null, + position: 0, + icon: 'IconLayoutKanban', + kanbanFieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.status + ], + filters: [] /* [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.type + ], + displayValue: 'Task', + operand: 'is', + value: '["TASK"]', + }, + ],*/, + fields: [ + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.title + ], + position: 0, + isVisible: true, + size: 210, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.status + ], + position: 2, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.dueAt + ], + position: 3, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + TASK_STANDARD_FIELD_IDS.assignee + ], + position: 4, + isVisible: true, + size: 150, + }, + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.createdAt + ], + position: 6, + isVisible: true, + size: 150, + }, + /* + TODO: Add later, since we don't have real-time it probably doesn't work well? + { + fieldMetadataId: + objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[ + BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt + ], + position: 0, + isVisible: true, + size: 210, + }, + */ + ], + }; +}; diff --git a/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-todo.view.ts b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-todo.view.ts new file mode 100644 index 000000000..70b786d12 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-todo.view.ts @@ -0,0 +1 @@ +// TODO diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts index d764bbc8d..adda57f20 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory.ts @@ -7,15 +7,15 @@ import { FieldMetadataType, } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; import { WorkspaceMigrationColumnActionType, WorkspaceMigrationEntity, WorkspaceMigrationTableAction, WorkspaceMigrationTableActionType, } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; -import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory'; -import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util'; +import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util'; export interface FieldMetadataUpdate { current: FieldMetadataEntity; @@ -60,17 +60,17 @@ export class WorkspaceMigrationFieldFactory { switch (action) { case WorkspaceMigrationBuilderAction.CREATE: - return this.createFieldMigration( + return await this.createFieldMigration( originalObjectMetadataMap, fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataEntity[], ); case WorkspaceMigrationBuilderAction.UPDATE: - return this.updateFieldMigration( + return await this.updateFieldMigration( originalObjectMetadataMap, fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataUpdate[], ); case WorkspaceMigrationBuilderAction.DELETE: - return this.deleteFieldMigration( + return await this.deleteFieldMigration( originalObjectMetadataMap, fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataEntity[], ); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts index c239462a2..5c7dd6026 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service.ts @@ -9,27 +9,27 @@ import { TableUnique, } from 'typeorm'; -import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service'; -import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; import { - WorkspaceMigrationTableAction, WorkspaceMigrationColumnAction, WorkspaceMigrationColumnActionType, + WorkspaceMigrationColumnAlter, WorkspaceMigrationColumnCreate, WorkspaceMigrationColumnCreateRelation, - WorkspaceMigrationColumnAlter, WorkspaceMigrationColumnDropRelation, - WorkspaceMigrationTableActionType, WorkspaceMigrationForeignTable, WorkspaceMigrationIndexAction, WorkspaceMigrationIndexActionType, + WorkspaceMigrationTableAction, + WorkspaceMigrationTableActionType, } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; -import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service'; +import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { WorkspaceMigrationEnumService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service'; import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util'; -import { customTableDefaultColumns } from './utils/custom-table-default-column.util'; import { WorkspaceMigrationTypeService } from './services/workspace-migration-type.service'; +import { customTableDefaultColumns } from './utils/custom-table-default-column.util'; @Injectable() export class WorkspaceMigrationRunnerService { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts index 8b24ac1a2..73de80046 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts @@ -40,6 +40,8 @@ export const ATTACHMENT_STANDARD_FIELD_IDS = { type: '20202020-a417-49b8-a40b-f6a7874caa0d', author: '20202020-6501-4ac5-a4ef-b2f8522ef6cd', activity: '20202020-b569-481b-a13f-9b94e47e54fe', + task: '20202020-51e5-4621-9cf8-215487951c4b', + note: '20202020-4f4b-4503-a6fc-6b982f3dffb5', person: '20202020-0158-4aa2-965c-5cdafe21ffa2', company: '20202020-ceab-4a28-b546-73b06b4c08d5', opportunity: '20202020-7374-499d-bea3-9354890755b5', @@ -127,6 +129,8 @@ export const COMPANY_STANDARD_FIELD_IDS = { people: '20202020-3213-4ddf-9494-6422bcff8d7c', accountOwner: '20202020-95b8-4e10-9881-edb5d4765f9d', activityTargets: '20202020-c2a5-4c9b-9d9a-582bcd57fbc8', + taskTargets: '20202020-cb17-4a61-8f8f-3be6730480de', + noteTargets: '20202020-bae0-4556-a74a-a9c686f77a88', opportunities: '20202020-add3-4658-8e23-d70dccb6d0ec', favorites: '20202020-4d1d-41ac-b13b-621631298d55', attachments: '20202020-c1b5-4120-b0f0-987ca401ed53', @@ -182,6 +186,8 @@ export const TIMELINE_ACTIVITY_STANDARD_FIELD_IDS = { person: '20202020-c414-45b9-a60a-ac27aa96229f', company: '20202020-04ad-4221-a744-7a8278a5ce21', opportunity: '20202020-7664-4a35-a3df-580d389fd527', + task: '20202020-b2f5-415c-9135-a31dfe49501b', + note: '20202020-ec55-4135-8da5-3a20badc0156', workflow: '20202020-9e59-4030-aa27-55abd676c3c8', custom: '20202020-4a71-41b0-9f83-9cdcca3f8b14', linkedRecordCachedName: '20202020-cfdb-4bef-bbce-a29f41230934', @@ -251,6 +257,23 @@ export const MESSAGE_STANDARD_FIELD_IDS = { messageChannelMessageAssociations: '20202020-3cef-43a3-82c6-50e7cfbc9ae4', }; +export const NOTE_STANDARD_FIELD_IDS = { + position: '20202020-368d-4dc2-943f-ed8a49c7fdfb', + title: '20202020-faeb-4c76-8ba6-ccbb0b4a965f', + body: '20202020-e63d-4e70-95be-a78cd9abe7ef', + noteTargets: '20202020-1f25-43fe-8b00-af212fdde823', + attachments: '20202020-4986-4c92-bf19-39934b149b16', + timelineActivities: '20202020-7030-42f8-929c-1a57b25d6bce', +}; + +export const NOTE_TARGET_STANDARD_FIELD_IDS = { + note: '20202020-57f3-4f50-9599-fc0f671df003', + person: '20202020-38ca-4aab-92f5-8a605ca2e4c5', + company: 'c500fbc0-d6f2-4982-a959-5a755431696c', + opportunity: '20202020-4e42-417a-a705-76581c9ade79', + custom: '20202020-3d12-4579-94ee-7117c1bad492', +}; + export const OPPORTUNITY_STANDARD_FIELD_IDS = { name: '20202020-8609-4f65-a2d9-44009eb422b5', amount: '20202020-583e-4642-8533-db761d5fa82f', @@ -262,6 +285,8 @@ export const OPPORTUNITY_STANDARD_FIELD_IDS = { company: '20202020-cbac-457e-b565-adece5fc815f', favorites: '20202020-a1c2-4500-aaae-83ba8a0e827a', activityTargets: '20202020-220a-42d6-8261-b2102d6eab35', + taskTargets: '20202020-59c0-4179-a208-4a255f04a5be', + noteTargets: '20202020-dd3f-42d5-a382-db58aabf43d3', attachments: '20202020-87c7-4118-83d6-2f4031005209', timelineActivities: '20202020-30e2-421f-96c7-19c69d1cf631', }; @@ -279,6 +304,8 @@ export const PERSON_STANDARD_FIELD_IDS = { company: '20202020-e2f3-448e-b34c-2d625f0025fd', pointOfContactForOpportunities: '20202020-911b-4a7d-b67b-918aa9a5b33a', activityTargets: '20202020-dee7-4b7f-b50a-1f50bd3be452', + taskTargets: '20202020-584b-4d3e-88b6-53ab1fa03c3a', + noteTargets: '20202020-c8fc-4258-8250-15905d3fcfec', favorites: '20202020-4073-4117-9cf1-203bcdc91cbd', attachments: '20202020-cd97-451f-87fa-bcb789bdbf3a', messageParticipants: '20202020-498e-4c61-8158-fa04f0638334', @@ -286,6 +313,26 @@ export const PERSON_STANDARD_FIELD_IDS = { timelineActivities: '20202020-a43e-4873-9c23-e522de906ce5', }; +export const TASK_STANDARD_FIELD_IDS = { + position: '20202020-7d47-4690-8a98-98b9a0c05dd8', + title: '20202020-b386-4cb7-aa5a-08d4a4d92680', + body: '20202020-ce13-43f4-8821-69388fe1fd26', + dueAt: '20202020-fd99-40da-951b-4cb9a352fce3', + status: '20202020-70bc-48f9-89c5-6aa730b151e0', + taskTargets: '20202020-de9c-4d0e-a452-713d4a3e5fc7', + attachments: '20202020-794d-4783-a8ff-cecdb15be139', + assignee: '20202020-065a-4f42-a906-e20422c1753f', + timelineActivities: '20202020-c778-4278-99ee-23a2837aee64', +}; + +export const TASK_TARGET_STANDARD_FIELD_IDS = { + task: '20202020-e881-457a-8758-74aaef4ae78a', + person: '20202020-c8a0-4e85-a016-87e2349cfbec', + company: '20202020-4703-4a4e-948c-487b0c60a92c', + opportunity: '20202020-6cb2-4c01-a9a5-aca3dbc11d41', + custom: '20202020-41c1-4c9a-8c75-be0971ef89af', +}; + export const VIEW_FIELD_STANDARD_FIELD_IDS = { fieldMetadataId: '20202020-135f-4c5b-b361-15f24870473c', isVisible: '20202020-e966-473c-9c18-f00d3347e0ba', @@ -360,6 +407,7 @@ export const WORKSPACE_MEMBER_STANDARD_FIELD_IDS = { userId: '20202020-75a9-4dfc-bf25-2e4b43e89820', authoredActivities: '20202020-f139-4f13-a82f-a65a8d290a74', assignedActivities: '20202020-5c97-42b6-8ca9-c07622cbb33f', + assignedTasks: '20202020-61dc-4a1c-99e8-38ebf8d2bbeb', favorites: '20202020-f3c1-4faf-b343-cf7681038757', accountOwnerForCompanies: '20202020-dc29-4bd4-a3c1-29eafa324bee', authoredAttachments: '20202020-000f-4947-917f-1b09851024fe', @@ -379,6 +427,8 @@ export const CUSTOM_OBJECT_STANDARD_FIELD_IDS = { name: '20202020-ba07-4ffd-ba63-009491f5749c', position: '20202020-c2bd-4e16-bb9a-c8b0411bf49d', activityTargets: '20202020-7f42-40ae-b96c-c8a61acc83bf', + noteTargets: '20202020-01fd-4f37-99dc-9427a444018a', + taskTargets: '20202020-0860-4566-b865-bff3c626c303', favorites: '20202020-a4a7-4686-b296-1c6c3482ee21', attachments: '20202020-8d59-46ca-b7b2-73d167712134', timelineActivities: '20202020-f1ef-4ba4-8f33-1a4577afa477', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts index 011f95e14..d0f4042b9 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids.ts @@ -26,8 +26,12 @@ export const STANDARD_OBJECT_IDS = { messageParticipant: '20202020-a433-4456-aa2d-fd9cb26b774a', messageThread: '20202020-849a-4c3e-84f5-a25a7d802271', message: '20202020-3f6b-4425-80ab-e468899ab4b2', + note: '20202020-0b00-45cd-b6f6-6cd806fc6804', + noteTarget: '20202020-fff0-4b44-be82-bda313884400', opportunity: '20202020-9549-49dd-b2b2-883999db8938', person: '20202020-e674-48e5-a542-72570eee7213', + task: '20202020-1ba1-48ba-bc83-ef7e5990ed10', + taskTarget: '20202020-5a9a-44e8-95df-771cd06d0fb1', timelineActivity: '20202020-6736-4337-b5c4-8b39fae325a5', viewField: '20202020-4d19-4655-95bf-b2a04cf206d4', viewFilter: '20202020-6fb6-4631-aded-b7d67e952ec8', diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts index a926b9525..d82e2bf69 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts @@ -2,24 +2,24 @@ import { Injectable, Logger } from '@nestjs/common'; import { EntityManager } from 'typeorm'; -import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; +import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; +import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; import { ComparatorAction, FieldComparatorResult, } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/comparator.interface'; -import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface'; -import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface'; +import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity'; -import { WorkspaceFieldComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator'; -import { WorkspaceMetadataUpdaterService } from 'src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service'; -import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; -import { WorkspaceMigrationFieldFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory'; -import { StandardFieldFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory'; import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity'; -import { computeStandardFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-fields.util'; +import { WorkspaceMigrationFieldFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory'; +import { WorkspaceFieldComparator } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/workspace-field.comparator'; +import { StandardFieldFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-field.factory'; +import { WorkspaceMetadataUpdaterService } from 'src/engine/workspace-manager/workspace-sync-metadata/services/workspace-metadata-updater.service'; import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects'; +import { WorkspaceSyncStorage } from 'src/engine/workspace-manager/workspace-sync-metadata/storage/workspace-sync.storage'; +import { computeStandardFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/compute-standard-fields.util'; import { mapObjectMetadataByUniqueIdentifier } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/sync-metadata.util'; @Injectable() @@ -81,11 +81,11 @@ export class WorkspaceSyncFieldMetadataService { this.logger.log('Generating migrations'); - const createFieldWorkspaceMigrations = + const deleteFieldWorkspaceMigrations = await this.workspaceMigrationFieldFactory.create( originalObjectMetadataCollection, - metadataFieldUpdaterResult.createdFieldMetadataCollection, - WorkspaceMigrationBuilderAction.CREATE, + storage.fieldMetadataDeleteCollection, + WorkspaceMigrationBuilderAction.DELETE, ); const updateFieldWorkspaceMigrations = @@ -95,19 +95,19 @@ export class WorkspaceSyncFieldMetadataService { WorkspaceMigrationBuilderAction.UPDATE, ); - const deleteFieldWorkspaceMigrations = + const createFieldWorkspaceMigrations = await this.workspaceMigrationFieldFactory.create( originalObjectMetadataCollection, - storage.fieldMetadataDeleteCollection, - WorkspaceMigrationBuilderAction.DELETE, + metadataFieldUpdaterResult.createdFieldMetadataCollection, + WorkspaceMigrationBuilderAction.CREATE, ); this.logger.log('Saving migrations'); return [ - ...createFieldWorkspaceMigrations, - ...updateFieldWorkspaceMigrations, ...deleteFieldWorkspaceMigrations, + ...updateFieldWorkspaceMigrations, + ...createFieldWorkspaceMigrations, ]; } diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts index b0f3ba663..9a42b4dd7 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-objects/index.ts @@ -16,8 +16,12 @@ import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/stan import { MessageParticipantWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-participant.workspace-entity'; import { MessageThreadWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-thread.workspace-entity'; import { MessageWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message.workspace-entity'; +import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity'; +import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.workspace-entity'; import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; +import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; +import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; import { AuditLogWorkspaceEntity } from 'src/modules/timeline/standard-objects/audit-log.workspace-entity'; import { BehavioralEventWorkspaceEntity } from 'src/modules/timeline/standard-objects/behavioral-event.workspace-entity'; import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; @@ -65,4 +69,16 @@ export const standardObjectMetadataDefinitions = [ MessageChannelWorkspaceEntity, MessageParticipantWorkspaceEntity, MessageChannelMessageAssociationWorkspaceEntity, + NoteWorkspaceEntity, + NoteTargetWorkspaceEntity, + OpportunityWorkspaceEntity, + PersonWorkspaceEntity, + TaskWorkspaceEntity, + TaskTargetWorkspaceEntity, + TimelineActivityWorkspaceEntity, + ViewFieldWorkspaceEntity, + ViewFilterWorkspaceEntity, + ViewSortWorkspaceEntity, + ViewWorkspaceEntity, + WebhookWorkspaceEntity, ]; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts index 4867e6331..4ef6a446e 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts @@ -144,6 +144,7 @@ export class WorkspaceSyncMetadataService { await queryRunner.commitTransaction(); // Execute migrations + this.logger.log('Executing pending migrations'); await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations( context.workspaceId, ); diff --git a/packages/twenty-server/src/modules/attachment/standard-objects/attachment.workspace-entity.ts b/packages/twenty-server/src/modules/attachment/standard-objects/attachment.workspace-entity.ts index 93c218515..cd23af305 100644 --- a/packages/twenty-server/src/modules/attachment/standard-objects/attachment.workspace-entity.ts +++ b/packages/twenty-server/src/modules/attachment/standard-objects/attachment.workspace-entity.ts @@ -18,8 +18,10 @@ import { ATTACHMENT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/work import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity'; import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity'; +import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.workspace-entity'; import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; +import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; @@ -91,6 +93,36 @@ export class AttachmentWorkspaceEntity extends BaseWorkspaceEntity { @WorkspaceJoinColumn('activity') activityId: string | null; + @WorkspaceRelation({ + standardId: ATTACHMENT_STANDARD_FIELD_IDS.task, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Task', + description: 'Attachment task', + icon: 'IconNotes', + inverseSideTarget: () => TaskWorkspaceEntity, + inverseSideFieldKey: 'attachments', + }) + @WorkspaceIsNullable() + task: Relation | null; + + @WorkspaceJoinColumn('task') + taskId: string | null; + + @WorkspaceRelation({ + standardId: ATTACHMENT_STANDARD_FIELD_IDS.note, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Note', + description: 'Attachment note', + icon: 'IconNotes', + inverseSideTarget: () => NoteWorkspaceEntity, + inverseSideFieldKey: 'attachments', + }) + @WorkspaceIsNullable() + note: Relation | null; + + @WorkspaceJoinColumn('note') + noteId: string | null; + @WorkspaceRelation({ standardId: ATTACHMENT_STANDARD_FIELD_IDS.person, type: RelationMetadataType.MANY_TO_ONE, diff --git a/packages/twenty-server/src/modules/company/standard-objects/company.workspace-entity.ts b/packages/twenty-server/src/modules/company/standard-objects/company.workspace-entity.ts index 4d4610aab..f31b1ef8d 100644 --- a/packages/twenty-server/src/modules/company/standard-objects/company.workspace-entity.ts +++ b/packages/twenty-server/src/modules/company/standard-objects/company.workspace-entity.ts @@ -22,8 +22,10 @@ import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-objects/activity-target.workspace-entity'; import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; +import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity'; import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; +import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; @@ -169,8 +171,31 @@ export class CompanyWorkspaceEntity extends BaseWorkspaceEntity { onDelete: RelationOnDeleteAction.CASCADE, }) @WorkspaceIsNullable() + @WorkspaceIsSystem() activityTargets: Relation; + @WorkspaceRelation({ + standardId: COMPANY_STANDARD_FIELD_IDS.taskTargets, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Tasks', + description: 'Tasks tied to the company', + icon: 'IconCheckbox', + inverseSideTarget: () => TaskTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + taskTargets: Relation; + + @WorkspaceRelation({ + standardId: COMPANY_STANDARD_FIELD_IDS.noteTargets, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Notes', + description: 'Notes tied to the company', + icon: 'IconNotes', + inverseSideTarget: () => NoteTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + noteTargets: Relation; + @WorkspaceRelation({ standardId: COMPANY_STANDARD_FIELD_IDS.opportunities, type: RelationMetadataType.ONE_TO_MANY, diff --git a/packages/twenty-server/src/modules/note/standard-objects/note-target.workspace-entity.ts b/packages/twenty-server/src/modules/note/standard-objects/note-target.workspace-entity.ts new file mode 100644 index 000000000..f4f260cea --- /dev/null +++ b/packages/twenty-server/src/modules/note/standard-objects/note-target.workspace-entity.ts @@ -0,0 +1,103 @@ +import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; + +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity'; +import { WorkspaceDynamicRelation } from 'src/engine/twenty-orm/decorators/workspace-dynamic-relation.decorator'; +import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; +import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; +import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; +import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator'; +import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; +import { NOTE_TARGET_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity'; +import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.workspace-entity'; +import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; +import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; + +@WorkspaceEntity({ + standardId: STANDARD_OBJECT_IDS.noteTarget, + namePlural: 'noteTargets', + labelSingular: 'Note Target', + labelPlural: 'Note Targets', + description: 'A note target', + icon: 'IconCheckbox', +}) +@WorkspaceIsSystem() +export class NoteTargetWorkspaceEntity extends BaseWorkspaceEntity { + @WorkspaceRelation({ + standardId: NOTE_TARGET_STANDARD_FIELD_IDS.note, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Note', + description: 'NoteTarget note', + icon: 'IconNotes', + inverseSideTarget: () => NoteWorkspaceEntity, + inverseSideFieldKey: 'noteTargets', + }) + @WorkspaceIsNullable() + note: Relation | null; + + @WorkspaceJoinColumn('note') + noteId: string | null; + + @WorkspaceRelation({ + standardId: NOTE_TARGET_STANDARD_FIELD_IDS.person, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Person', + description: 'NoteTarget person', + icon: 'IconUser', + inverseSideTarget: () => PersonWorkspaceEntity, + inverseSideFieldKey: 'noteTargets', + }) + @WorkspaceIsNullable() + person: Relation | null; + + @WorkspaceJoinColumn('person') + personId: string | null; + + @WorkspaceRelation({ + standardId: NOTE_TARGET_STANDARD_FIELD_IDS.company, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Company', + description: 'NoteTarget company', + icon: 'IconBuildingSkyscraper', + inverseSideTarget: () => CompanyWorkspaceEntity, + inverseSideFieldKey: 'noteTargets', + }) + @WorkspaceIsNullable() + company: Relation | null; + + @WorkspaceJoinColumn('company') + companyId: string | null; + + @WorkspaceRelation({ + standardId: NOTE_TARGET_STANDARD_FIELD_IDS.opportunity, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Opportunity', + description: 'NoteTarget opportunity', + icon: 'IconTargetArrow', + inverseSideTarget: () => OpportunityWorkspaceEntity, + inverseSideFieldKey: 'noteTargets', + }) + @WorkspaceIsNullable() + opportunity: Relation | null; + + @WorkspaceJoinColumn('opportunity') + opportunityId: string | null; + + @WorkspaceDynamicRelation({ + type: RelationMetadataType.MANY_TO_ONE, + argsFactory: (oppositeObjectMetadata) => ({ + standardId: NOTE_TARGET_STANDARD_FIELD_IDS.custom, + name: oppositeObjectMetadata.nameSingular, + label: oppositeObjectMetadata.labelSingular, + description: `NoteTarget ${oppositeObjectMetadata.labelSingular}`, + joinColumn: `${oppositeObjectMetadata.nameSingular}Id`, + icon: 'IconBuildingSkyscraper', + }), + inverseSideTarget: () => CustomWorkspaceEntity, + inverseSideFieldKey: 'noteTargets', + }) + custom: Relation; +} diff --git a/packages/twenty-server/src/modules/note/standard-objects/note.workspace-entity.ts b/packages/twenty-server/src/modules/note/standard-objects/note.workspace-entity.ts new file mode 100644 index 000000000..52ccc7a6e --- /dev/null +++ b/packages/twenty-server/src/modules/note/standard-objects/note.workspace-entity.ts @@ -0,0 +1,96 @@ +import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; + +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { + RelationMetadataType, + RelationOnDeleteAction, +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; +import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; +import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; +import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; +import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; +import { NOTE_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; +import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity'; +import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; + +@WorkspaceEntity({ + standardId: STANDARD_OBJECT_IDS.note, + namePlural: 'notes', + labelSingular: 'Note', + labelPlural: 'Notes', + description: 'A note', + icon: 'IconNotes', + labelIdentifierStandardId: NOTE_STANDARD_FIELD_IDS.title, +}) +export class NoteWorkspaceEntity extends BaseWorkspaceEntity { + @WorkspaceField({ + standardId: NOTE_STANDARD_FIELD_IDS.position, + type: FieldMetadataType.POSITION, + label: 'Position', + description: 'Note record position', + icon: 'IconHierarchy2', + }) + @WorkspaceIsSystem() + @WorkspaceIsNullable() + position: number | null; + + @WorkspaceField({ + standardId: NOTE_STANDARD_FIELD_IDS.title, + type: FieldMetadataType.TEXT, + label: 'Title', + description: 'Note title', + icon: 'IconNotes', + }) + title: string; + + @WorkspaceField({ + standardId: NOTE_STANDARD_FIELD_IDS.body, + type: FieldMetadataType.RICH_TEXT, + label: 'Body', + description: 'Note body', + icon: 'IconFilePencil', + }) + @WorkspaceIsNullable() + body: string | null; + + @WorkspaceRelation({ + standardId: NOTE_STANDARD_FIELD_IDS.noteTargets, + label: 'Targets', + description: 'Note targets', + icon: 'IconCheckbox', + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => NoteTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.SET_NULL, + }) + @WorkspaceIsNullable() + @WorkspaceIsSystem() + noteTargets: Relation; + + @WorkspaceRelation({ + standardId: NOTE_STANDARD_FIELD_IDS.attachments, + label: 'Attachments', + description: 'Note attachments', + icon: 'IconFileImport', + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => AttachmentWorkspaceEntity, + onDelete: RelationOnDeleteAction.SET_NULL, + }) + @WorkspaceIsNullable() + attachments: Relation; + + @WorkspaceRelation({ + standardId: NOTE_STANDARD_FIELD_IDS.timelineActivities, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Timeline Activities', + description: 'Timeline Activities linked to the note.', + icon: 'IconTimelineEvent', + inverseSideTarget: () => TimelineActivityWorkspaceEntity, + onDelete: RelationOnDeleteAction.SET_NULL, + }) + @WorkspaceIsNullable() + timelineActivities: Relation; +} diff --git a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.workspace-entity.ts b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.workspace-entity.ts index ae3ef4490..35ac579ee 100644 --- a/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.workspace-entity.ts +++ b/packages/twenty-server/src/modules/opportunity/standard-objects/opportunity.workspace-entity.ts @@ -21,7 +21,9 @@ import { ActivityTargetWorkspaceEntity } from 'src/modules/activity/standard-obj import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity'; import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; +import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity'; import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; +import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; @WorkspaceEntity({ @@ -152,8 +154,31 @@ export class OpportunityWorkspaceEntity extends BaseWorkspaceEntity { onDelete: RelationOnDeleteAction.CASCADE, }) @WorkspaceIsNullable() + @WorkspaceIsSystem() activityTargets: Relation; + @WorkspaceRelation({ + standardId: OPPORTUNITY_STANDARD_FIELD_IDS.taskTargets, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Tasks', + description: 'Tasks tied to the opportunity', + icon: 'IconCheckbox', + inverseSideTarget: () => TaskTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + taskTargets: Relation; + + @WorkspaceRelation({ + standardId: OPPORTUNITY_STANDARD_FIELD_IDS.noteTargets, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Notes', + description: 'Notes tied to the opportunity', + icon: 'IconNotes', + inverseSideTarget: () => NoteTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + noteTargets: Relation; + @WorkspaceRelation({ standardId: OPPORTUNITY_STANDARD_FIELD_IDS.attachments, type: RelationMetadataType.ONE_TO_MANY, diff --git a/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts b/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts index a876863e5..9c58ff333 100644 --- a/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts +++ b/packages/twenty-server/src/modules/person/standard-objects/person.workspace-entity.ts @@ -22,7 +22,9 @@ import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/co import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity'; import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; import { MessageParticipantWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-participant.workspace-entity'; +import { NoteTargetWorkspaceEntity } from 'src/modules/note/standard-objects/note-target.workspace-entity'; import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; +import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; @WorkspaceEntity({ @@ -159,8 +161,31 @@ export class PersonWorkspaceEntity extends BaseWorkspaceEntity { inverseSideTarget: () => ActivityTargetWorkspaceEntity, onDelete: RelationOnDeleteAction.CASCADE, }) + @WorkspaceIsSystem() activityTargets: Relation; + @WorkspaceRelation({ + standardId: PERSON_STANDARD_FIELD_IDS.taskTargets, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Tasks', + description: 'Tasks tied to the contact', + icon: 'IconCheckbox', + inverseSideTarget: () => TaskTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + taskTargets: Relation; + + @WorkspaceRelation({ + standardId: PERSON_STANDARD_FIELD_IDS.noteTargets, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Notes', + description: 'Notes tied to the contact', + icon: 'IconNotes', + inverseSideTarget: () => NoteTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.CASCADE, + }) + noteTargets: Relation; + @WorkspaceRelation({ standardId: PERSON_STANDARD_FIELD_IDS.favorites, type: RelationMetadataType.ONE_TO_MANY, diff --git a/packages/twenty-server/src/modules/task/standard-objects/task-target.workspace-entity.ts b/packages/twenty-server/src/modules/task/standard-objects/task-target.workspace-entity.ts new file mode 100644 index 000000000..8f9cac2ac --- /dev/null +++ b/packages/twenty-server/src/modules/task/standard-objects/task-target.workspace-entity.ts @@ -0,0 +1,103 @@ +import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; + +import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity'; +import { WorkspaceDynamicRelation } from 'src/engine/twenty-orm/decorators/workspace-dynamic-relation.decorator'; +import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; +import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; +import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; +import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator'; +import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; +import { TASK_TARGET_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity'; +import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; +import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; +import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; + +@WorkspaceEntity({ + standardId: STANDARD_OBJECT_IDS.taskTarget, + namePlural: 'taskTargets', + labelSingular: 'Task Target', + labelPlural: 'Task Targets', + description: 'An task target', + icon: 'IconCheckbox', +}) +@WorkspaceIsSystem() +export class TaskTargetWorkspaceEntity extends BaseWorkspaceEntity { + @WorkspaceRelation({ + standardId: TASK_TARGET_STANDARD_FIELD_IDS.task, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Task', + description: 'TaskTarget task', + icon: 'IconCheckbox', + inverseSideTarget: () => TaskWorkspaceEntity, + inverseSideFieldKey: 'taskTargets', + }) + @WorkspaceIsNullable() + task: Relation | null; + + @WorkspaceJoinColumn('task') + taskId: string | null; + + @WorkspaceRelation({ + standardId: TASK_TARGET_STANDARD_FIELD_IDS.person, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Person', + description: 'TaskTarget person', + icon: 'IconUser', + inverseSideTarget: () => PersonWorkspaceEntity, + inverseSideFieldKey: 'taskTargets', + }) + @WorkspaceIsNullable() + person: Relation | null; + + @WorkspaceJoinColumn('person') + personId: string | null; + + @WorkspaceRelation({ + standardId: TASK_TARGET_STANDARD_FIELD_IDS.company, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Company', + description: 'TaskTarget company', + icon: 'IconBuildingSkyscraper', + inverseSideTarget: () => CompanyWorkspaceEntity, + inverseSideFieldKey: 'taskTargets', + }) + @WorkspaceIsNullable() + company: Relation | null; + + @WorkspaceJoinColumn('company') + companyId: string | null; + + @WorkspaceRelation({ + standardId: TASK_TARGET_STANDARD_FIELD_IDS.opportunity, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Opportunity', + description: 'TaskTarget opportunity', + icon: 'IconTargetArrow', + inverseSideTarget: () => OpportunityWorkspaceEntity, + inverseSideFieldKey: 'taskTargets', + }) + @WorkspaceIsNullable() + opportunity: Relation | null; + + @WorkspaceJoinColumn('opportunity') + opportunityId: string | null; + + @WorkspaceDynamicRelation({ + type: RelationMetadataType.MANY_TO_ONE, + argsFactory: (oppositeObjectMetadata) => ({ + standardId: TASK_TARGET_STANDARD_FIELD_IDS.custom, + name: oppositeObjectMetadata.nameSingular, + label: oppositeObjectMetadata.labelSingular, + description: `TaskTarget ${oppositeObjectMetadata.labelSingular}`, + joinColumn: `${oppositeObjectMetadata.nameSingular}Id`, + icon: 'IconBuildingSkyscraper', + }), + inverseSideTarget: () => CustomWorkspaceEntity, + inverseSideFieldKey: 'taskTargets', + }) + custom: Relation; +} diff --git a/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts b/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts new file mode 100644 index 000000000..9688f05c3 --- /dev/null +++ b/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts @@ -0,0 +1,150 @@ +import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; + +import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { + RelationMetadataType, + RelationOnDeleteAction, +} from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; +import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; +import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; +import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; +import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; +import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator'; +import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; +import { TASK_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; +import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; +import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; +import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; + +@WorkspaceEntity({ + standardId: STANDARD_OBJECT_IDS.task, + namePlural: 'tasks', + labelSingular: 'Task', + labelPlural: 'Tasks', + description: 'A task', + icon: 'IconCheckbox', + labelIdentifierStandardId: TASK_STANDARD_FIELD_IDS.title, +}) +export class TaskWorkspaceEntity extends BaseWorkspaceEntity { + @WorkspaceField({ + standardId: TASK_STANDARD_FIELD_IDS.position, + type: FieldMetadataType.POSITION, + label: 'Position', + description: 'Task record position', + icon: 'IconHierarchy2', + }) + @WorkspaceIsSystem() + @WorkspaceIsNullable() + position: number | null; + + @WorkspaceField({ + standardId: TASK_STANDARD_FIELD_IDS.title, + type: FieldMetadataType.TEXT, + label: 'Title', + description: 'Task title', + icon: 'IconNotes', + }) + title: string; + + @WorkspaceField({ + standardId: TASK_STANDARD_FIELD_IDS.body, + type: FieldMetadataType.RICH_TEXT, + label: 'Body', + description: 'Task body', + icon: 'IconFilePencil', + }) + @WorkspaceIsNullable() + body: string | null; + + @WorkspaceField({ + standardId: TASK_STANDARD_FIELD_IDS.dueAt, + type: FieldMetadataType.DATE_TIME, + label: 'Due Date', + description: 'Task due date', + icon: 'IconCalendarEvent', + }) + @WorkspaceIsNullable() + dueAt: Date | null; + + @WorkspaceField({ + standardId: TASK_STANDARD_FIELD_IDS.status, + type: FieldMetadataType.SELECT, + label: 'Status', + description: 'Task status', + icon: 'IconCheck', + defaultValue: "'TODO'", + options: [ + { value: 'TODO', label: 'To do', position: 0, color: 'sky' }, + { + value: 'IN_PROGESS', + label: 'In progress', + position: 1, + color: 'purple', + }, + { + value: 'DONE', + label: 'Done', + position: 1, + color: 'green', + }, + ], + }) + @WorkspaceIsNullable() + status: string | null; + + @WorkspaceRelation({ + standardId: TASK_STANDARD_FIELD_IDS.taskTargets, + label: 'Targets', + description: 'Task targets', + icon: 'IconCheckbox', + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => TaskTargetWorkspaceEntity, + onDelete: RelationOnDeleteAction.SET_NULL, + }) + @WorkspaceIsNullable() + @WorkspaceIsSystem() + taskTargets: Relation; + + @WorkspaceRelation({ + standardId: TASK_STANDARD_FIELD_IDS.attachments, + label: 'Attachments', + description: 'Task attachments', + icon: 'IconFileImport', + type: RelationMetadataType.ONE_TO_MANY, + inverseSideTarget: () => AttachmentWorkspaceEntity, + onDelete: RelationOnDeleteAction.SET_NULL, + }) + @WorkspaceIsNullable() + attachments: Relation; + + @WorkspaceRelation({ + standardId: TASK_STANDARD_FIELD_IDS.assignee, + label: 'Assignee', + description: 'Task assignee', + icon: 'IconUserCircle', + type: RelationMetadataType.MANY_TO_ONE, + inverseSideTarget: () => WorkspaceMemberWorkspaceEntity, + inverseSideFieldKey: 'assignedTasks', + onDelete: RelationOnDeleteAction.SET_NULL, + }) + @WorkspaceIsNullable() + assignee: Relation | null; + + @WorkspaceJoinColumn('assignee') + assigneeId: string | null; + + @WorkspaceRelation({ + standardId: TASK_STANDARD_FIELD_IDS.timelineActivities, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Timeline Activities', + description: 'Timeline Activities linked to the task.', + icon: 'IconTimelineEvent', + inverseSideTarget: () => TimelineActivityWorkspaceEntity, + onDelete: RelationOnDeleteAction.SET_NULL, + }) + @WorkspaceIsNullable() + timelineActivities: Relation; +} diff --git a/packages/twenty-server/src/modules/timeline/jobs/upsert-timeline-activity-from-internal-event.job.ts b/packages/twenty-server/src/modules/timeline/jobs/upsert-timeline-activity-from-internal-event.job.ts index 5abcb2e10..ada03bf13 100644 --- a/packages/twenty-server/src/modules/timeline/jobs/upsert-timeline-activity-from-internal-event.job.ts +++ b/packages/twenty-server/src/modules/timeline/jobs/upsert-timeline-activity-from-internal-event.job.ts @@ -1,11 +1,11 @@ import { ObjectRecordBaseEvent } from 'src/engine/integrations/event-emitter/types/object-record.base.event'; -import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; -import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository'; -import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; -import { TimelineActivityService } from 'src/modules/timeline/services/timeline-activity.service'; +import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator'; import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator'; import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; -import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator'; +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { TimelineActivityService } from 'src/modules/timeline/services/timeline-activity.service'; +import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository'; +import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; @Processor(MessageQueue.entityEventsToDbQueue) export class UpsertTimelineActivityFromInternalEvent { @@ -37,8 +37,8 @@ export class UpsertTimelineActivityFromInternalEvent { // We ignore every that is not a LinkedObject or a Business Object if ( data.objectMetadata.isSystem && - data.objectMetadata.nameSingular !== 'activityTarget' && - data.objectMetadata.nameSingular !== 'activity' + data.objectMetadata.nameSingular !== 'noteTarget' && + data.objectMetadata.nameSingular !== 'taskTarget' ) { return; } diff --git a/packages/twenty-server/src/modules/timeline/services/timeline-activity.service.ts b/packages/twenty-server/src/modules/timeline/services/timeline-activity.service.ts index eee199b10..b3b32ef3b 100644 --- a/packages/twenty-server/src/modules/timeline/services/timeline-activity.service.ts +++ b/packages/twenty-server/src/modules/timeline/services/timeline-activity.service.ts @@ -21,13 +21,18 @@ export class TimelineActivityService { private readonly workspaceDataSourceService: WorkspaceDataSourceService, ) {} + private targetObjects: Record = { + note: 'noteTarget', + task: 'taskTarget', + }; + async upsertEvent(event: ObjectRecordBaseEvent) { const events = await this.transformEvent(event); if (!events || events.length === 0) return; for (const event of events) { - return await this.timelineActivityRepository.upsertOne( + await this.timelineActivityRepository.upsertOne( event.name, event.properties, event.objectName ?? event.objectMetadata.nameSingular, @@ -44,12 +49,21 @@ export class TimelineActivityService { private async transformEvent( event: ObjectRecordBaseEvent, ): Promise { + if (['note', 'task'].includes(event.objectMetadata.nameSingular)) { + const linkedObjects = await this.handleLinkedObjects(event); + + // 2 timelines, one for the linked object and one for the task/note + if (linkedObjects?.length > 0) return [...linkedObjects, event]; + } + if ( - ['activity', 'messageParticipant', 'activityTarget'].includes( + ['noteTarget', 'taskTarget', 'messageParticipant'].includes( event.objectMetadata.nameSingular, ) ) { - return await this.handleLinkedObjects(event); + const linkedObjects = await this.handleLinkedObjects(event); + + return linkedObjects; } return [event]; @@ -61,10 +75,17 @@ export class TimelineActivityService { ); switch (event.objectMetadata.nameSingular) { - case 'activityTarget': - return this.processActivityTarget(event, dataSourceSchema); - case 'activity': - return this.processActivity(event, dataSourceSchema); + case 'noteTarget': + return this.processActivityTarget(event, dataSourceSchema, 'note'); + case 'taskTarget': + return this.processActivityTarget(event, dataSourceSchema, 'task'); + case 'note': + case 'task': + return this.processActivity( + event, + dataSourceSchema, + event.objectMetadata.nameSingular, + ); default: return []; } @@ -73,17 +94,18 @@ export class TimelineActivityService { private async processActivity( event: ObjectRecordBaseEvent, dataSourceSchema: string, + activityType: string, ) { const activityTargets = await this.workspaceDataSourceService.executeRawQuery( - `SELECT * FROM ${dataSourceSchema}."activityTarget" - WHERE "activityId" = $1`, + `SELECT * FROM ${dataSourceSchema}."${this.targetObjects[activityType]}" + WHERE "${activityType}Id" = $1`, [event.recordId], event.workspaceId, ); const activity = await this.workspaceDataSourceService.executeRawQuery( - `SELECT * FROM ${dataSourceSchema}."activity" + `SELECT * FROM ${dataSourceSchema}."${activityType}" WHERE "id" = $1`, [event.recordId], event.workspaceId, @@ -96,7 +118,10 @@ export class TimelineActivityService { .map((activityTarget) => { const targetColumn: string[] = Object.entries(activityTarget) .map(([columnName, columnValue]: [string, string]) => { - if (columnName === 'activityId' || !columnName.endsWith('Id')) + if ( + columnName === activityType + 'Id' || + !columnName.endsWith('Id') + ) return; if (columnValue === null) return; @@ -108,7 +133,7 @@ export class TimelineActivityService { return { ...event, - name: activity[0].type.toLowerCase() + '.' + event.name.split('.')[1], + name: 'linked-' + event.name, objectName: targetColumn[0].replace(/Id$/, ''), recordId: activityTarget[targetColumn[0]], linkedRecordCachedName: activity[0].title, @@ -122,10 +147,11 @@ export class TimelineActivityService { private async processActivityTarget( event: ObjectRecordBaseEvent, dataSourceSchema: string, + activityType: string, ) { const activityTarget = await this.workspaceDataSourceService.executeRawQuery( - `SELECT * FROM ${dataSourceSchema}."activityTarget" + `SELECT * FROM ${dataSourceSchema}."${this.targetObjects[activityType]}" WHERE "id" = $1`, [event.recordId], event.workspaceId, @@ -134,7 +160,7 @@ export class TimelineActivityService { if (activityTarget.length === 0) return; const activity = await this.workspaceDataSourceService.executeRawQuery( - `SELECT * FROM ${dataSourceSchema}."activity" + `SELECT * FROM ${dataSourceSchema}."${activityType}" WHERE "id" = $1`, [activityTarget[0].activityId], event.workspaceId, @@ -143,12 +169,13 @@ export class TimelineActivityService { if (activity.length === 0) return; const activityObjectMetadataId = event.objectMetadata.fields.find( - (field) => field.name === 'activity', + (field) => field.name === activityType, )?.toRelationMetadata?.fromObjectMetadataId; const targetColumn: string[] = Object.entries(activityTarget[0]) .map(([columnName, columnValue]: [string, string]) => { - if (columnName === 'activityId' || !columnName.endsWith('Id')) return; + if (columnName === activityType + 'Id' || !columnName.endsWith('Id')) + return; if (columnValue === null) return; return columnName; @@ -160,7 +187,7 @@ export class TimelineActivityService { return [ { ...event, - name: activity[0].type.toLowerCase() + '.' + event.name.split('.')[1], + name: 'linked-' + event.name, properties: {}, objectName: targetColumn[0].replace(/Id$/, ''), recordId: activityTarget[0][targetColumn[0]], diff --git a/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts b/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts index c5fef9897..de4cfc6de 100644 --- a/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts +++ b/packages/twenty-server/src/modules/timeline/standard-objects/timeline-activity.workspace-entity.ts @@ -17,8 +17,10 @@ import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-re import { TIMELINE_ACTIVITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity'; +import { NoteWorkspaceEntity } from 'src/modules/note/standard-objects/note.workspace-entity'; import { OpportunityWorkspaceEntity } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity'; import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; +import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; @@ -153,6 +155,36 @@ export class TimelineActivityWorkspaceEntity extends BaseWorkspaceEntity { @WorkspaceJoinColumn('opportunity') opportunityId: string | null; + @WorkspaceRelation({ + standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.note, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Note', + description: 'Event note', + icon: 'IconTargetArrow', + inverseSideTarget: () => NoteWorkspaceEntity, + inverseSideFieldKey: 'timelineActivities', + }) + @WorkspaceIsNullable() + note: Relation | null; + + @WorkspaceJoinColumn('note') + noteId: string | null; + + @WorkspaceRelation({ + standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.task, + type: RelationMetadataType.MANY_TO_ONE, + label: 'Task', + description: 'Event task', + icon: 'IconTargetArrow', + inverseSideTarget: () => TaskWorkspaceEntity, + inverseSideFieldKey: 'timelineActivities', + }) + @WorkspaceIsNullable() + task: Relation | null; + + @WorkspaceJoinColumn('task') + taskId: string | null; + @WorkspaceRelation({ standardId: TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workflow, type: RelationMetadataType.MANY_TO_ONE, diff --git a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts index bb19b0566..212250153 100644 --- a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts +++ b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts @@ -26,6 +26,7 @@ import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/com import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; import { MessageParticipantWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-participant.workspace-entity'; +import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity'; import { AuditLogWorkspaceEntity } from 'src/modules/timeline/standard-objects/audit-log.workspace-entity'; import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; @@ -146,6 +147,18 @@ export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity { }) assignedActivities: Relation; + @WorkspaceRelation({ + standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.assignedTasks, + type: RelationMetadataType.ONE_TO_MANY, + label: 'Assigned tasks', + description: 'Tasks assigned to the workspace member', + icon: 'IconCheckbox', + inverseSideTarget: () => TaskWorkspaceEntity, + inverseSideFieldKey: 'assignee', + onDelete: RelationOnDeleteAction.SET_NULL, + }) + assignedTasks: Relation; + @WorkspaceRelation({ standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.favorites, type: RelationMetadataType.ONE_TO_MANY, diff --git a/packages/twenty-ui/src/display/icon/components/TablerIcons.ts b/packages/twenty-ui/src/display/icon/components/TablerIcons.ts index a73785be8..0d404d41b 100644 --- a/packages/twenty-ui/src/display/icon/components/TablerIcons.ts +++ b/packages/twenty-ui/src/display/icon/components/TablerIcons.ts @@ -1,5 +1,4 @@ /* eslint-disable no-restricted-imports */ -export type { TablerIconsProps } from '@tabler/icons-react'; export { Icon123, IconAlertCircle, @@ -11,9 +10,9 @@ export { IconArrowDown, IconArrowLeft, IconArrowRight, - IconArrowsVertical, IconArrowUp, IconArrowUpRight, + IconArrowsVertical, IconAt, IconBaselineDensitySmall, IconBell, @@ -39,8 +38,8 @@ export { IconChevronDown, IconChevronLeft, IconChevronRight, - IconChevronsRight, IconChevronUp, + IconChevronsRight, IconCircleDot, IconCircleOff, IconCirclePlus, @@ -72,12 +71,14 @@ export { IconDotsVertical, IconDownload, IconEditCircle, + IconExternalLink, IconEye, IconEyeOff, IconFile, IconFileCheck, IconFileExport, IconFileImport, + IconFilePencil, IconFileText, IconFileUpload, IconFileZip, @@ -120,6 +121,7 @@ export { IconMessage, IconMinus, IconMoneybag, + IconMoodSmile, IconMouse2, IconNotes, IconNumbers, @@ -167,6 +169,7 @@ export { IconVideo, IconWand, IconWorld, - IconX, - IconMoodSmile, + IconX } from '@tabler/icons-react'; +export type { TablerIconsProps } from '@tabler/icons-react'; +