From 5f604a503a0b968aba097abe8b58469aa4125c29 Mon Sep 17 00:00:00 2001 From: Weiko Date: Fri, 24 Apr 2026 16:35:56 +0200 Subject: [PATCH] backfill widget position from gridPosition (phase 1 of gridPosition removal) (#20032) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Context Phase 1 of removing the legacy `gridPosition` field from `PageLayoutWidget` in favor of the new `position` discriminated union (`grid` / `vertical-list` / `canvas`). This PR is purely additive — `gridPosition` is still required and read everywhere; we just guarantee that every widget now also has a non-null `position` so a follow-up PR can drop `gridPosition` cleanly. ## Changes - **Slow instance command** `BackfillPageLayoutWidgetPositionSlowInstanceCommand` (2.1.0): for every `core.pageLayoutWidget` row where `position IS NULL`, copies `gridPosition` into `position` with `layoutMode: 'GRID'`. Historically only grid widgets used `gridPosition`, so a single SQL update covers every existing row. - **`PageLayoutDuplicationService`**: when duplicating a widget, also forwards `originalWidget.position` (was previously only forwarding `gridPosition`). - **Frontend default layouts** (10 `Default*PageLayout.ts` files): added a `position` sibling to every widget, matching the parent tab's `layoutMode` — `VERTICAL_LIST` widgets get `{ layoutMode, index }`, `CANVAS` widgets get `{ layoutMode }` Screenshot 2026-04-24 at 16 23 17 --- .../src/metadata/generated/schema.graphql | 2 +- .../src/metadata/generated/schema.ts | 2 ++ .../src/generated-metadata/graphql.ts | 1 + .../DefaultCompanyRecordPageLayout.ts | 29 +++++++++++++++++ .../DefaultMessageThreadRecordPageLayout.ts | 5 +++ .../constants/DefaultNoteRecordPageLayout.ts | 23 +++++++++++++ .../DefaultOpportunityRecordPageLayout.ts | 29 +++++++++++++++++ .../DefaultPersonRecordPageLayout.ts | 29 +++++++++++++++++ .../constants/DefaultRecordPageLayout.ts | 21 ++++++++++++ .../constants/DefaultTaskRecordPageLayout.ts | 23 +++++++++++++ .../constants/DefaultWorkflowPageLayout.ts | 4 +++ .../constants/DefaultWorkflowRunPageLayout.ts | 9 ++++++ .../DefaultWorkflowVersionPageLayout.ts | 9 ++++++ ...00-backfill-page-layout-widget-position.ts | 32 +++++++++++++++++++ .../instance-commands.constant.ts | 2 ++ .../inputs/create-page-layout-widget.input.ts | 6 +++- ...update-page-layout-widget-with-id.input.ts | 5 ++- .../inputs/update-page-layout-widget.input.ts | 6 +++- .../dtos/page-layout-widget.dto.ts | 6 +++- .../page-layout-duplication.service.ts | 1 + 20 files changed, 239 insertions(+), 5 deletions(-) create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/2-1/2-1-instance-command-slow-1795000002000-backfill-page-layout-widget-position.ts diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index ffeef02597..864853139e 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -925,7 +925,7 @@ type PageLayoutWidget { title: String! type: WidgetType! objectMetadataId: UUID - gridPosition: GridPosition! + gridPosition: GridPosition! @deprecated(reason: "Use `position` instead. Will be removed in a future release.") position: PageLayoutWidgetPosition configuration: WidgetConfiguration! conditionalDisplay: JSON diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index d5090bd58e..2427a6d4f3 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -702,6 +702,7 @@ export interface PageLayoutWidget { title: Scalars['String'] type: WidgetType objectMetadataId?: Scalars['UUID'] + /** @deprecated Use `position` instead. Will be removed in a future release. */ gridPosition: GridPosition position?: PageLayoutWidgetPosition configuration: WidgetConfiguration @@ -3589,6 +3590,7 @@ export interface PageLayoutWidgetGenqlSelection{ title?: boolean | number type?: boolean | number objectMetadataId?: boolean | number + /** @deprecated Use `position` instead. Will be removed in a future release. */ gridPosition?: GridPositionGenqlSelection position?: PageLayoutWidgetPositionGenqlSelection configuration?: WidgetConfigurationGenqlSelection diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index d7ec938a27..e14a7659d5 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -3846,6 +3846,7 @@ export type PageLayoutWidget = { configuration: WidgetConfiguration; createdAt: Scalars['DateTime']; deletedAt?: Maybe; + /** @deprecated Use `position` instead. Will be removed in a future release. */ gridPosition: GridPosition; id: Scalars['UUID']; isActive: Scalars['Boolean']; diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts index 58310d961e..60e0376f02 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultCompanyRecordPageLayout.ts @@ -47,6 +47,11 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -88,6 +93,10 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -129,6 +138,10 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -170,6 +183,10 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -211,6 +228,10 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -252,6 +273,10 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -293,6 +318,10 @@ export const DEFAULT_COMPANY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultMessageThreadRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultMessageThreadRecordPageLayout.ts index 6c1c38ec13..2096c45847 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultMessageThreadRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultMessageThreadRecordPageLayout.ts @@ -47,6 +47,11 @@ export const DEFAULT_MESSAGE_THREAD_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts index c0a8751822..976576d4d6 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultNoteRecordPageLayout.ts @@ -47,6 +47,11 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, // Note: Configuration is null by default. For testing purposes, // use useTempNoteFieldsConfiguration() hook at runtime to get // a configuration with actual field metadata IDs from the backend. @@ -75,6 +80,11 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 1, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -123,6 +133,11 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -171,6 +186,10 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -212,6 +231,10 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts index 74fcf69be2..6c22428aa7 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultOpportunityRecordPageLayout.ts @@ -47,6 +47,11 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -88,6 +93,10 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -129,6 +138,10 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -170,6 +183,10 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -211,6 +228,10 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -252,6 +273,10 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -293,6 +318,10 @@ export const DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts index 8f3794249f..4c542bd241 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultPersonRecordPageLayout.ts @@ -47,6 +47,11 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -88,6 +93,10 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -129,6 +138,10 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -170,6 +183,10 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -211,6 +228,10 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -252,6 +273,10 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -293,6 +318,10 @@ export const DEFAULT_PERSON_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts index 0d19d557e5..26d5ec3ed3 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultRecordPageLayout.ts @@ -47,6 +47,11 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -88,6 +93,10 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -129,6 +138,10 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -170,6 +183,10 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -211,6 +228,10 @@ export const DEFAULT_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts index fa2fd34b34..4b2fafb37f 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultTaskRecordPageLayout.ts @@ -47,6 +47,11 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -72,6 +77,11 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 1, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -120,6 +130,11 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -168,6 +183,10 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -209,6 +228,10 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = { rowSpan: 6, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowPageLayout.ts index 5a2feb8296..9d520d6b4f 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowPageLayout.ts @@ -52,6 +52,10 @@ export const DEFAULT_WORKFLOW_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts index 824798945d..85dc69f8f2 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowRunPageLayout.ts @@ -53,6 +53,11 @@ export const DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -95,6 +100,10 @@ export const DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts index 508c551ec9..acebb4239d 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/DefaultWorkflowVersionPageLayout.ts @@ -53,6 +53,11 @@ export const DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetVerticalListPosition', + layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST, + index: 0, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, @@ -95,6 +100,10 @@ export const DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT: PageLayout = { rowSpan: 12, columnSpan: 12, }, + position: { + __typename: 'PageLayoutWidgetCanvasPosition', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + }, configuration: { __typename: 'FieldsConfiguration', configurationType: WidgetConfigurationType.FIELDS, diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-1/2-1-instance-command-slow-1795000002000-backfill-page-layout-widget-position.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-1/2-1-instance-command-slow-1795000002000-backfill-page-layout-widget-position.ts new file mode 100644 index 0000000000..d5fde18130 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-1/2-1-instance-command-slow-1795000002000-backfill-page-layout-widget-position.ts @@ -0,0 +1,32 @@ +import { DataSource, QueryRunner } from 'typeorm'; + +import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator'; +import { SlowInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/slow-instance-command.interface'; + +@RegisteredInstanceCommand('2.1.0', 1795000002000, { type: 'slow' }) +export class BackfillPageLayoutWidgetPositionSlowInstanceCommand + implements SlowInstanceCommand +{ + async runDataMigration(dataSource: DataSource): Promise { + await dataSource.query( + `UPDATE "core"."pageLayoutWidget" + SET "position" = jsonb_build_object( + 'layoutMode', 'GRID', + 'row', "gridPosition"->'row', + 'column', "gridPosition"->'column', + 'rowSpan', "gridPosition"->'rowSpan', + 'columnSpan', "gridPosition"->'columnSpan' + ) + WHERE "position" IS NULL + AND "gridPosition" IS NOT NULL`, + ); + } + + public async up(_queryRunner: QueryRunner): Promise { + return; + } + + public async down(_queryRunner: QueryRunner): Promise { + return; + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts index 1ff661851d..6d5a4c6469 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts @@ -16,6 +16,7 @@ import { AddGlobalObjectContextToCommandMenuItemAvailabilityTypeFastInstanceComm import { AddPageLayoutIdToCommandMenuItemFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-23/1-23-instance-command-fast-1776168404836-add-page-layout-id-to-command-menu-item'; import { AddConditionalAvailabilityExpressionToPageLayoutWidgetFastInstanceCommand } from 'src/database/commands/upgrade-version-command/1-23/1-23-instance-command-fast-1775654781000-add-conditional-availability-expression-to-page-layout-widget'; import { AddIsPreInstalledToApplicationRegistrationFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-0/2-0-instance-command-fast-1776886452831-add-is-pre-installed-to-application-registration'; +import { BackfillPageLayoutWidgetPositionSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-1/2-1-instance-command-slow-1795000002000-backfill-page-layout-widget-position'; export const INSTANCE_COMMANDS = [ AddViewFieldGroupIdIndexOnViewFieldFastInstanceCommand, @@ -34,4 +35,5 @@ export const INSTANCE_COMMANDS = [ AddPageLayoutIdToCommandMenuItemFastInstanceCommand, AddConditionalAvailabilityExpressionToPageLayoutWidgetFastInstanceCommand, AddIsPreInstalledToApplicationRegistrationFastInstanceCommand, + BackfillPageLayoutWidgetPositionSlowInstanceCommand, ]; diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/create-page-layout-widget.input.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/create-page-layout-widget.input.ts index 4ab1bfb4ad..7ca393110f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/create-page-layout-widget.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/create-page-layout-widget.input.ts @@ -39,7 +39,11 @@ export class CreatePageLayoutWidgetInput { @IsOptional() objectMetadataId?: string | null; - @Field(() => GridPositionInput, { nullable: false }) + @Field(() => GridPositionInput, { + nullable: false, + deprecationReason: + 'Use `position` instead. Will be removed in a future release.', + }) @ValidateNested() @Type(() => GridPositionInput) gridPosition: GridPositionInput; diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget-with-id.input.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget-with-id.input.ts index 056b19127e..d31331ef94 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget-with-id.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget-with-id.input.ts @@ -48,7 +48,10 @@ export class UpdatePageLayoutWidgetWithIdInput { @IsOptional() objectMetadataId: string | null; - @Field(() => GridPositionInput) + @Field(() => GridPositionInput, { + deprecationReason: + 'Use `position` instead. Will be removed in a future release.', + }) @ValidateNested() @Type(() => GridPositionInput) @IsNotEmpty() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget.input.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget.input.ts index e35aee1592..661c9a29ea 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/inputs/update-page-layout-widget.input.ts @@ -42,7 +42,11 @@ export class UpdatePageLayoutWidgetInput { @IsOptional() objectMetadataId?: string | null; - @Field(() => GridPositionInput, { nullable: true }) + @Field(() => GridPositionInput, { + nullable: true, + deprecationReason: + 'Use `position` instead. Will be removed in a future release.', + }) @ValidateNested() @Type(() => GridPositionInput) @IsOptional() diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/page-layout-widget.dto.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/page-layout-widget.dto.ts index 99cd6a4c98..dd19cadf96 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/page-layout-widget.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/page-layout-widget.dto.ts @@ -56,7 +56,11 @@ export class PageLayoutWidgetDTO { @Field(() => UUIDScalarType, { nullable: true }) objectMetadataId?: string; - @Field(() => GridPositionDTO, { nullable: false }) + @Field(() => GridPositionDTO, { + nullable: false, + deprecationReason: + 'Use `position` instead. Will be removed in a future release.', + }) gridPosition: GridPositionDTO; @Field(() => PageLayoutWidgetPositionUnion, { nullable: true }) diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts index 22e28a4461..69cd25eabb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts @@ -325,6 +325,7 @@ export class PageLayoutDuplicationService { createPageLayoutWidgetInput: { title: originalWidget.title, gridPosition: originalWidget.gridPosition, + position: originalWidget.position ?? undefined, type: originalWidget.type, objectMetadataId: originalWidget.objectMetadataId, configuration: originalWidget.configuration,