Compare commits

...

2 Commits

Author SHA1 Message Date
Charles Bochet c616713435 Add import scheduled status to messaging sync (#16058)
We have introduced to new syncStage statuses:
`messageChannel.MESSAGES_IMPORT_SCHEDULED` and
`calendarChannel.CALENDAR_EVENTS_IMPORT_SCHEDULED`

We need to make sure all existing workspaces have it
2025-11-25 15:28:48 +01:00
Raphaël Bosi 859c948d01 Fix page layout widget deletion (#16035)
With the new side panel, we are able to delete a widget with the side
panel still open. This caused the app to crash because we threw when the
widget id wasn't defined.

This PR fixes this by closing the side panel in the delete action and by
returning null instead of throwing.

## Before



https://github.com/user-attachments/assets/092bfe62-82dc-4d83-9967-1cc753ecf55e



## After


https://github.com/user-attachments/assets/8bed6cc5-961b-4112-8cf5-e587865d14da
2025-11-25 14:08:39 +01:00
10 changed files with 384 additions and 37 deletions
@@ -3,11 +3,11 @@ import { CommandMenuAIChatThreadsPage } from '@/command-menu/pages/AIChatThreads
import { CommandMenuAskAIPage } from '@/command-menu/pages/ask-ai/components/CommandMenuAskAIPage';
import { CommandMenuCalendarEventPage } from '@/command-menu/pages/calendar-event/components/CommandMenuCalendarEventPage';
import { CommandMenuMessageThreadPage } from '@/command-menu/pages/message-thread/components/CommandMenuMessageThreadPage';
import { CommandMenuPageLayoutChartSettings } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutChartSettings';
import { CommandMenuPageLayoutGraphFilter } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutGraphFilter';
import { CommandMenuPageLayoutGraphTypeSelect } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutGraphTypeSelect';
import { CommandMenuPageLayoutIframeSettings } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutIframeSettings';
import { CommandMenuPageLayoutWidgetTypeSelect } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutWidgetTypeSelect';
import { CommandMenuPageLayoutTabSettings } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutTabSettings';
import { CommandMenuPageLayoutWidgetTypeSelect } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutWidgetTypeSelect';
import { CommandMenuMergeRecordPage } from '@/command-menu/pages/record-page/components/CommandMenuMergeRecordPage';
import { CommandMenuRecordPage } from '@/command-menu/pages/record-page/components/CommandMenuRecordPage';
import { CommandMenuEditRichTextPage } from '@/command-menu/pages/rich-text-page/components/CommandMenuEditRichTextPage';
@@ -48,7 +48,7 @@ export const COMMAND_MENU_PAGES_CONFIG = new Map<
],
[
CommandMenuPages.PageLayoutGraphTypeSelect,
<CommandMenuPageLayoutGraphTypeSelect />,
<CommandMenuPageLayoutChartSettings />,
],
[
CommandMenuPages.PageLayoutGraphFilter,
@@ -14,7 +14,7 @@ const StyledContainer = styled.div`
height: 100%;
`;
export const CommandMenuPageLayoutGraphTypeSelect = () => {
export const CommandMenuPageLayoutChartSettings = () => {
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
const draftPageLayout = useRecoilComponentValue(
@@ -27,21 +27,12 @@ export const CommandMenuPageLayoutGraphTypeSelect = () => {
pageLayoutId,
);
if (!isDefined(pageLayoutEditingWidgetId)) {
throw new Error('Widget ID must be present while editing the widget');
}
const widgetInEditMode = draftPageLayout.tabs
.flatMap((tab) => tab.widgets)
.find((widget) => widget.id === pageLayoutEditingWidgetId);
if (!isDefined(widgetInEditMode)) {
throw new Error(
`Widget with ID ${pageLayoutEditingWidgetId} not found in page layout`,
);
}
if (
!isDefined(widgetInEditMode) ||
!isDefined(widgetInEditMode.configuration) ||
!('graphType' in widgetInEditMode.configuration)
) {
@@ -1,10 +1,11 @@
import { ChartFiltersSettings } from '@/command-menu/pages/page-layout/components/ChartFiltersSettings';
import { usePageLayoutIdFromContextStoreTargetedRecord } from '@/command-menu/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord';
import { isChartWidget } from '@/command-menu/pages/page-layout/utils/isChartWidget';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
export const CommandMenuPageLayoutGraphFilter = () => {
@@ -24,28 +25,27 @@ export const CommandMenuPageLayoutGraphFilter = () => {
.flatMap((tab) => tab.widgets)
.find((widget) => widget.id === pageLayoutEditingWidgetId);
if (!isDefined(widgetInEditMode)) {
throw new Error(
`Widget with ID ${pageLayoutEditingWidgetId} not found in page layout`,
);
}
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
if (!isDefined(widgetInEditMode?.objectMetadataId)) {
throw new Error('No data source in chart');
}
const { objectMetadataItem } = useObjectMetadataItemById({
objectId: widgetInEditMode.objectMetadataId,
});
if (!isDefined(pageLayoutEditingWidgetId)) {
throw new Error('Widget ID must be present while editing the widget');
}
if (!isChartWidget(widgetInEditMode)) {
if (
!isDefined(widgetInEditMode) ||
!isDefined(widgetInEditMode.objectMetadataId) ||
!isChartWidget(widgetInEditMode)
) {
return null;
}
const objectMetadataItem = objectMetadataItems.find(
(objectMetadataItem) =>
objectMetadataItem.id === widgetInEditMode?.objectMetadataId,
);
if (!isDefined(objectMetadataItem)) {
throw new Error(
`Object metadata item not found for id ${widgetInEditMode?.objectMetadataId}`,
);
}
return (
<>
<ChartFiltersSettings
@@ -1,3 +1,4 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
@@ -24,9 +25,13 @@ export const useDeletePageLayoutWidget = (pageLayoutIdFromProps?: string) => {
pageLayoutId,
);
const { closeCommandMenu } = useCommandMenu();
const deletePageLayoutWidget = useRecoilCallback(
({ snapshot, set }) =>
(widgetId: string) => {
closeCommandMenu();
const pageLayoutDraft = snapshot
.getLoadable(pageLayoutDraftState)
.getValue();
@@ -53,7 +58,7 @@ export const useDeletePageLayoutWidget = (pageLayoutIdFromProps?: string) => {
}));
}
},
[pageLayoutCurrentLayoutsState, pageLayoutDraftState],
[closeCommandMenu, pageLayoutCurrentLayoutsState, pageLayoutDraftState],
);
return { deletePageLayoutWidget };
@@ -0,0 +1,165 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Command } from 'nest-commander';
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
import { Repository } from 'typeorm';
import {
ActiveOrSuspendedWorkspacesMigrationCommandRunner,
type RunOnWorkspaceArgs,
} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { type FieldMetadataComplexOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { FieldMetadataServiceV2 } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service-v2';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { CALENDAR_CHANNEL_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { CalendarChannelSyncStage } from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
@Command({
name: 'upgrade:1-12:add-calendar-events-import-scheduled-sync-stage',
description:
'Add CALENDAR_EVENTS_IMPORT_SCHEDULED sync stage to calendar channel syncStage field',
})
export class AddCalendarEventsImportScheduledSyncStageCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
constructor(
@InjectRepository(WorkspaceEntity)
protected readonly workspaceRepository: Repository<WorkspaceEntity>,
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
@InjectRepository(ObjectMetadataEntity)
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
@InjectRepository(FieldMetadataEntity)
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
private readonly fieldMetadataService: FieldMetadataServiceV2,
) {
super(workspaceRepository, twentyORMGlobalManager);
}
override async runOnWorkspace({
workspaceId,
options,
}: RunOnWorkspaceArgs): Promise<void> {
this.logger.log(
`Adding CALENDAR_EVENTS_IMPORT_SCHEDULED sync stage for workspace ${workspaceId}`,
);
const calendarChannelObject = await this.objectMetadataRepository.findOne({
where: {
standardId: STANDARD_OBJECT_IDS.calendarChannel,
workspaceId,
},
});
if (!calendarChannelObject) {
this.logger.log(
`CalendarChannel object not found for workspace ${workspaceId}, skipping enum migration`,
);
return;
}
const syncStageField = await this.fieldMetadataRepository.findOne({
where: {
standardId: CALENDAR_CHANNEL_STANDARD_FIELD_IDS.syncStage,
objectMetadataId: calendarChannelObject.id,
workspaceId,
},
});
if (!syncStageField) {
this.logger.log(
`CalendarChannel syncStage field not found for workspace ${workspaceId}, skipping field metadata update`,
);
return;
}
const fieldOptions = (syncStageField.options ||
[]) as FieldMetadataComplexOption[];
const hasCalendarEventsImportScheduled = fieldOptions.some(
(option) =>
option.value ===
CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_SCHEDULED,
);
if (hasCalendarEventsImportScheduled) {
this.logger.log(
`CalendarChannel syncStage field metadata already has CALENDAR_EVENTS_IMPORT_SCHEDULED for workspace ${workspaceId}`,
);
return;
}
if (options.dryRun) {
this.logger.log(
`Would add CALENDAR_EVENTS_IMPORT_SCHEDULED sync stage for workspace ${workspaceId}`,
);
return;
}
await this.fieldMetadataService.updateOneField({
updateFieldInput: {
id: syncStageField.id,
options: [
{
value: CalendarChannelSyncStage.CALENDAR_EVENT_LIST_FETCH_PENDING,
label: 'Calendar event list fetch pending',
position: 0,
color: 'blue',
},
{
value: CalendarChannelSyncStage.CALENDAR_EVENT_LIST_FETCH_SCHEDULED,
label: 'Calendar event list fetch scheduled',
position: 1,
color: 'green',
},
{
value: CalendarChannelSyncStage.CALENDAR_EVENT_LIST_FETCH_ONGOING,
label: 'Calendar event list fetch ongoing',
position: 2,
color: 'orange',
},
{
value: CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_PENDING,
label: 'Calendar events import pending',
position: 3,
color: 'blue',
},
{
value: CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_SCHEDULED,
label: 'Calendar events import scheduled',
position: 4,
color: 'green',
},
{
value: CalendarChannelSyncStage.CALENDAR_EVENTS_IMPORT_ONGOING,
label: 'Calendar events import ongoing',
position: 5,
color: 'orange',
},
{
value: CalendarChannelSyncStage.FAILED,
label: 'Failed',
position: 6,
color: 'red',
},
{
value: CalendarChannelSyncStage.PENDING_CONFIGURATION,
label: 'Pending configuration',
position: 9,
color: 'gray',
},
],
},
workspaceId,
isSystemBuild: true,
});
this.logger.log(
`Successfully added CALENDAR_EVENTS_IMPORT_SCHEDULED sync stage for workspace ${workspaceId}`,
);
}
}
@@ -0,0 +1,164 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Command } from 'nest-commander';
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
import { Repository } from 'typeorm';
import {
ActiveOrSuspendedWorkspacesMigrationCommandRunner,
type RunOnWorkspaceArgs,
} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { type FieldMetadataComplexOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { FieldMetadataServiceV2 } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service-v2';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { MESSAGE_CHANNEL_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { MessageChannelSyncStage } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
@Command({
name: 'upgrade:1-12:add-messages-import-scheduled-sync-stage',
description:
'Add MESSAGES_IMPORT_SCHEDULED sync stage to message channel syncStage field',
})
export class AddMessagesImportScheduledSyncStageCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
constructor(
@InjectRepository(WorkspaceEntity)
protected readonly workspaceRepository: Repository<WorkspaceEntity>,
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
@InjectRepository(ObjectMetadataEntity)
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
@InjectRepository(FieldMetadataEntity)
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
private readonly fieldMetadataService: FieldMetadataServiceV2,
) {
super(workspaceRepository, twentyORMGlobalManager);
}
override async runOnWorkspace({
workspaceId,
options,
}: RunOnWorkspaceArgs): Promise<void> {
this.logger.log(
`Adding MESSAGES_IMPORT_SCHEDULED sync stage for workspace ${workspaceId}`,
);
const messageChannelObject = await this.objectMetadataRepository.findOne({
where: {
standardId: STANDARD_OBJECT_IDS.messageChannel,
workspaceId,
},
});
if (!messageChannelObject) {
this.logger.log(
`MessageChannel object not found for workspace ${workspaceId}, skipping enum migration`,
);
return;
}
const syncStageField = await this.fieldMetadataRepository.findOne({
where: {
standardId: MESSAGE_CHANNEL_STANDARD_FIELD_IDS.syncStage,
objectMetadataId: messageChannelObject.id,
workspaceId,
},
});
if (!syncStageField) {
this.logger.log(
`MessageChannel syncStage field not found for workspace ${workspaceId}, skipping field metadata update`,
);
return;
}
const fieldOptions = (syncStageField.options ||
[]) as FieldMetadataComplexOption[];
const hasMessagesImportScheduled = fieldOptions.some(
(option) =>
option.value === MessageChannelSyncStage.MESSAGES_IMPORT_SCHEDULED,
);
if (hasMessagesImportScheduled) {
this.logger.log(
`MessageChannel syncStage field metadata already has MESSAGES_IMPORT_SCHEDULED for workspace ${workspaceId}`,
);
return;
}
if (options.dryRun) {
this.logger.log(
`Would add MESSAGES_IMPORT_SCHEDULED sync stage for workspace ${workspaceId}`,
);
return;
}
await this.fieldMetadataService.updateOneField({
updateFieldInput: {
id: syncStageField.id,
options: [
{
value: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING,
label: 'Messages list fetch pending',
position: 0,
color: 'blue',
},
{
value: MessageChannelSyncStage.MESSAGE_LIST_FETCH_SCHEDULED,
label: 'Messages list fetch scheduled',
position: 1,
color: 'green',
},
{
value: MessageChannelSyncStage.MESSAGE_LIST_FETCH_ONGOING,
label: 'Messages list fetch ongoing',
position: 2,
color: 'orange',
},
{
value: MessageChannelSyncStage.MESSAGES_IMPORT_PENDING,
label: 'Messages import pending',
position: 3,
color: 'blue',
},
{
value: MessageChannelSyncStage.MESSAGES_IMPORT_SCHEDULED,
label: 'Messages import scheduled',
position: 4,
color: 'green',
},
{
value: MessageChannelSyncStage.MESSAGES_IMPORT_ONGOING,
label: 'Messages import ongoing',
position: 5,
color: 'orange',
},
{
value: MessageChannelSyncStage.FAILED,
label: 'Failed',
position: 6,
color: 'red',
},
{
value: MessageChannelSyncStage.PENDING_CONFIGURATION,
label: 'Pending configuration',
position: 7,
color: 'gray',
},
],
},
workspaceId,
isSystemBuild: true,
});
this.logger.log(
`Successfully added MESSAGES_IMPORT_SCHEDULED sync stage for workspace ${workspaceId}`,
);
}
}
@@ -1,25 +1,39 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AddCalendarEventsImportScheduledSyncStageCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-add-calendar-events-import-scheduled-sync-stage.command';
import { AddMessagesImportScheduledSyncStageCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-add-messages-import-scheduled-sync-stage.command';
import { CreateWorkspaceCustomApplicationCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-create-workspace-custom-application.command';
import { SetStandardApplicationNotUninstallableCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-set-standard-application-not-uninstallable.command';
import { WorkspaceCustomApplicationIdNonNullableCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-workspace-custom-application-id-non-nullable-migration.command';
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
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 { WorkspaceSchemaManagerModule } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.module';
@Module({
imports: [
TypeOrmModule.forFeature([WorkspaceEntity]),
TypeOrmModule.forFeature([
WorkspaceEntity,
ObjectMetadataEntity,
FieldMetadataEntity,
]),
WorkspaceSchemaManagerModule,
ApplicationModule,
FieldMetadataModule,
],
providers: [
AddCalendarEventsImportScheduledSyncStageCommand,
AddMessagesImportScheduledSyncStageCommand,
CreateWorkspaceCustomApplicationCommand,
SetStandardApplicationNotUninstallableCommand,
WorkspaceCustomApplicationIdNonNullableCommand,
],
exports: [
AddCalendarEventsImportScheduledSyncStageCommand,
AddMessagesImportScheduledSyncStageCommand,
CreateWorkspaceCustomApplicationCommand,
SetStandardApplicationNotUninstallableCommand,
WorkspaceCustomApplicationIdNonNullableCommand,
@@ -21,6 +21,8 @@ import { RegenerateSearchVectorsCommand } from 'src/database/commands/upgrade-ve
import { CleanOrphanedRoleTargetsCommand } from 'src/database/commands/upgrade-version-command/1-11/1-11-clean-orphaned-role-targets.command';
import { CleanOrphanedUserWorkspacesCommand } from 'src/database/commands/upgrade-version-command/1-11/1-11-clean-orphaned-user-workspaces.command';
import { CreateTwentyStandardApplicationCommand } from 'src/database/commands/upgrade-version-command/1-11/1-11-create-twenty-standard-application.command';
import { AddCalendarEventsImportScheduledSyncStageCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-add-calendar-events-import-scheduled-sync-stage.command';
import { AddMessagesImportScheduledSyncStageCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-add-messages-import-scheduled-sync-stage.command';
import { CreateWorkspaceCustomApplicationCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-create-workspace-custom-application.command';
import { SetStandardApplicationNotUninstallableCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-set-standard-application-not-uninstallable.command';
import { WorkspaceCustomApplicationIdNonNullableCommand } from 'src/database/commands/upgrade-version-command/1-12/1-12-workspace-custom-application-id-non-nullable-migration.command';
@@ -84,6 +86,8 @@ export class UpgradeCommand extends UpgradeCommandRunner {
protected readonly createTwentyStandardApplicationCommand: CreateTwentyStandardApplicationCommand,
protected readonly createWorkspaceCustomApplicationCommand: CreateWorkspaceCustomApplicationCommand,
protected readonly workspaceCustomApplicationIdNonNullableCommand: WorkspaceCustomApplicationIdNonNullableCommand,
protected readonly addMessagesImportScheduledSyncStageCommand: AddMessagesImportScheduledSyncStageCommand,
protected readonly addCalendarEventsImportScheduledSyncStageCommand: AddCalendarEventsImportScheduledSyncStageCommand,
) {
super(
workspaceRepository,
@@ -143,6 +147,8 @@ export class UpgradeCommand extends UpgradeCommandRunner {
beforeSyncMetadata: [
this.createWorkspaceCustomApplicationCommand,
this.workspaceCustomApplicationIdNonNullableCommand,
this.addMessagesImportScheduledSyncStageCommand,
this.addCalendarEventsImportScheduledSyncStageCommand,
],
afterSyncMetadata: [this.setStandardApplicationNotUninstallableCommand],
};
@@ -146,9 +146,11 @@ export class FieldMetadataServiceV2 extends TypeOrmQueryService<FieldMetadataEnt
async updateOneField({
updateFieldInput,
workspaceId,
isSystemBuild = false,
}: {
updateFieldInput: Omit<UpdateFieldInput, 'workspaceId'>;
workspaceId: string;
isSystemBuild?: boolean;
}): Promise<FlatFieldMetadata> {
const {
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
@@ -256,7 +258,7 @@ export class FieldMetadataServiceV2 extends TypeOrmQueryService<FieldMetadataEnt
}),
},
buildOptions: {
isSystemBuild: false,
isSystemBuild,
inferDeletionFromMissingEntities: {
index: true,
viewGroup: true,
@@ -1,8 +1,8 @@
import { registerEnumType } from '@nestjs/graphql';
import { msg } from '@lingui/core/macro';
import { FieldMetadataType, RelationOnDeleteAction } from 'twenty-shared/types';
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
import { FieldMetadataType, RelationOnDeleteAction } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';