Update pageLayout* data models for backend recordPageLayout refactor (#17446)
<img width="814" height="356" alt="Screenshot 2026-01-26 at 16 09 27" src="https://github.com/user-attachments/assets/91d95a1d-cc33-4bf0-a63e-4d1815030983" />
This commit is contained in:
@@ -3355,6 +3355,7 @@ export type PageInfo = {
|
||||
export type PageLayout = {
|
||||
__typename?: 'PageLayout';
|
||||
createdAt: Scalars['DateTime'];
|
||||
defaultTabToFocusOnMobileAndSidePanelId?: Maybe<Scalars['UUID']>;
|
||||
deletedAt?: Maybe<Scalars['DateTime']>;
|
||||
id: Scalars['UUID'];
|
||||
name: Scalars['String'];
|
||||
@@ -3368,7 +3369,9 @@ export type PageLayoutTab = {
|
||||
__typename?: 'PageLayoutTab';
|
||||
createdAt: Scalars['DateTime'];
|
||||
deletedAt?: Maybe<Scalars['DateTime']>;
|
||||
icon?: Maybe<Scalars['String']>;
|
||||
id: Scalars['UUID'];
|
||||
layoutMode?: Maybe<PageLayoutTabLayoutMode>;
|
||||
pageLayoutId: Scalars['UUID'];
|
||||
position: Scalars['Float'];
|
||||
title: Scalars['String'];
|
||||
@@ -3376,6 +3379,12 @@ export type PageLayoutTab = {
|
||||
widgets?: Maybe<Array<PageLayoutWidget>>;
|
||||
};
|
||||
|
||||
export enum PageLayoutTabLayoutMode {
|
||||
CANVAS = 'CANVAS',
|
||||
GRID = 'GRID',
|
||||
VERTICAL_LIST = 'VERTICAL_LIST'
|
||||
}
|
||||
|
||||
export enum PageLayoutType {
|
||||
DASHBOARD = 'DASHBOARD',
|
||||
RECORD_INDEX = 'RECORD_INDEX',
|
||||
@@ -3384,6 +3393,7 @@ export enum PageLayoutType {
|
||||
|
||||
export type PageLayoutWidget = {
|
||||
__typename?: 'PageLayoutWidget';
|
||||
conditionalDisplay?: Maybe<Scalars['JSON']>;
|
||||
configuration: WidgetConfiguration;
|
||||
createdAt: Scalars['DateTime'];
|
||||
deletedAt?: Maybe<Scalars['DateTime']>;
|
||||
|
||||
@@ -3237,6 +3237,7 @@ export type PageInfo = {
|
||||
export type PageLayout = {
|
||||
__typename?: 'PageLayout';
|
||||
createdAt: Scalars['DateTime'];
|
||||
defaultTabToFocusOnMobileAndSidePanelId?: Maybe<Scalars['UUID']>;
|
||||
deletedAt?: Maybe<Scalars['DateTime']>;
|
||||
id: Scalars['UUID'];
|
||||
name: Scalars['String'];
|
||||
@@ -3250,7 +3251,9 @@ export type PageLayoutTab = {
|
||||
__typename?: 'PageLayoutTab';
|
||||
createdAt: Scalars['DateTime'];
|
||||
deletedAt?: Maybe<Scalars['DateTime']>;
|
||||
icon?: Maybe<Scalars['String']>;
|
||||
id: Scalars['UUID'];
|
||||
layoutMode?: Maybe<PageLayoutTabLayoutMode>;
|
||||
pageLayoutId: Scalars['UUID'];
|
||||
position: Scalars['Float'];
|
||||
title: Scalars['String'];
|
||||
@@ -3258,6 +3261,12 @@ export type PageLayoutTab = {
|
||||
widgets?: Maybe<Array<PageLayoutWidget>>;
|
||||
};
|
||||
|
||||
export enum PageLayoutTabLayoutMode {
|
||||
CANVAS = 'CANVAS',
|
||||
GRID = 'GRID',
|
||||
VERTICAL_LIST = 'VERTICAL_LIST'
|
||||
}
|
||||
|
||||
export enum PageLayoutType {
|
||||
DASHBOARD = 'DASHBOARD',
|
||||
RECORD_INDEX = 'RECORD_INDEX',
|
||||
@@ -3266,6 +3275,7 @@ export enum PageLayoutType {
|
||||
|
||||
export type PageLayoutWidget = {
|
||||
__typename?: 'PageLayoutWidget';
|
||||
conditionalDisplay?: Maybe<Scalars['JSON']>;
|
||||
configuration: WidgetConfiguration;
|
||||
createdAt: Scalars['DateTime'];
|
||||
deletedAt?: Maybe<Scalars['DateTime']>;
|
||||
|
||||
@@ -2,11 +2,14 @@ import { type PageLayoutTabLayoutMode } from '@/page-layout/types/PageLayoutTabL
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { type PageLayoutTab as PageLayoutTabGenerated } from '~/generated/graphql';
|
||||
|
||||
export type PageLayoutTab = Omit<PageLayoutTabGenerated, 'widgets'> & {
|
||||
export type PageLayoutTab = Omit<
|
||||
PageLayoutTabGenerated,
|
||||
'widgets' | 'layoutMode'
|
||||
> & {
|
||||
widgets: PageLayoutWidget[];
|
||||
/**
|
||||
* Only available behind IS_RECORD_PAGE_LAYOUT_ENABLED for now.
|
||||
*/
|
||||
layoutMode?: PageLayoutTabLayoutMode;
|
||||
icon?: string;
|
||||
icon?: string | null;
|
||||
};
|
||||
|
||||
@@ -9,11 +9,14 @@ export const transformPageLayout = (
|
||||
...pageLayout,
|
||||
tabs: (pageLayout.tabs ?? [])
|
||||
.toSorted((a, b) => a.position - b.position)
|
||||
.map(
|
||||
(tab): PageLayoutTab => ({
|
||||
...tab,
|
||||
.map((tab): PageLayoutTab => {
|
||||
// TODO: remove this once the frontend consumes the new type
|
||||
const { layoutMode: _layoutMode, ...tabWithoutLayoutMode } = tab;
|
||||
|
||||
return {
|
||||
...tabWithoutLayoutMode,
|
||||
widgets: tab.widgets ?? [],
|
||||
}),
|
||||
),
|
||||
};
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
import { type MigrationInterface, type QueryRunner } from 'typeorm';
|
||||
|
||||
export class UpdatePageLayoutForRecordPageLayout1769679579382
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'UpdatePageLayoutForRecordPageLayout1769679579382';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayout" ADD "defaultTabToFocusOnMobileAndSidePanelId" uuid`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayoutTab" ADD "icon" character varying`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TYPE "core"."pageLayoutTab_layoutmode_enum" AS ENUM('GRID', 'VERTICAL_LIST', 'CANVAS')`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayoutTab" ADD "layoutMode" "core"."pageLayoutTab_layoutmode_enum" NOT NULL DEFAULT 'GRID'`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayoutWidget" ADD "conditionalDisplay" jsonb`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayout" ADD CONSTRAINT "FK_747fbc25827bdcb9e35cc68a990" FOREIGN KEY ("defaultTabToFocusOnMobileAndSidePanelId") REFERENCES "core"."pageLayoutTab"("id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayout" DROP CONSTRAINT "FK_747fbc25827bdcb9e35cc68a990"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayoutWidget" DROP COLUMN "conditionalDisplay"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayoutTab" DROP COLUMN "layoutMode"`,
|
||||
);
|
||||
await queryRunner.query(`DROP TYPE "core"."pageLayoutTab_layoutmode_enum"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayoutTab" DROP COLUMN "icon"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."pageLayout" DROP COLUMN "defaultTabToFocusOnMobileAndSidePanelId"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
+5
@@ -306,6 +306,11 @@ export const ALL_METADATA_RELATIONS = {
|
||||
foreignKey: 'objectMetadataId',
|
||||
},
|
||||
application: null,
|
||||
defaultTabToFocusOnMobileAndSidePanel: {
|
||||
metadataName: 'pageLayoutTab',
|
||||
flatEntityForeignKeyAggregator: null,
|
||||
foreignKey: 'defaultTabToFocusOnMobileAndSidePanelId',
|
||||
},
|
||||
},
|
||||
oneToMany: {
|
||||
tabs: { metadataName: 'pageLayoutTab' },
|
||||
|
||||
+1
@@ -62,6 +62,7 @@ export const ALL_METADATA_REQUIRED_METADATA_FOR_VALIDATION = {
|
||||
},
|
||||
pageLayout: {
|
||||
objectMetadata: true,
|
||||
pageLayoutTab: true,
|
||||
},
|
||||
pageLayoutTab: {
|
||||
pageLayout: true,
|
||||
|
||||
+1
-1
@@ -9,13 +9,13 @@ exports[`sortMetadataNamesChildrenFirst should return metadata names sorted with
|
||||
"viewField",
|
||||
"commandMenuItem",
|
||||
"index",
|
||||
"pageLayout",
|
||||
"roleTarget",
|
||||
"rowLevelPermissionPredicateGroup",
|
||||
"viewGroup",
|
||||
"agent",
|
||||
"frontComponent",
|
||||
"logicFunction",
|
||||
"pageLayout",
|
||||
"pageLayoutTab",
|
||||
"skill",
|
||||
"view",
|
||||
|
||||
+3
@@ -1,3 +1,4 @@
|
||||
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
|
||||
import { trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -36,5 +37,7 @@ export const fromCreatePageLayoutTabInputToFlatPageLayoutTabToCreate = ({
|
||||
universalIdentifier: pageLayoutTabId,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
widgetIds: [],
|
||||
icon: null,
|
||||
layoutMode: PageLayoutTabLayoutMode.GRID,
|
||||
};
|
||||
};
|
||||
|
||||
+2
@@ -46,6 +46,8 @@ export const transformPageLayoutTabEntityToFlatPageLayoutTab = ({
|
||||
universalIdentifier: pageLayoutTabEntity.universalIdentifier,
|
||||
applicationId: pageLayoutTabEntity.applicationId,
|
||||
widgetIds: pageLayoutTabEntity.widgets.map((widget) => widget.id),
|
||||
icon: pageLayoutTabEntity.icon,
|
||||
layoutMode: pageLayoutTabEntity.layoutMode,
|
||||
__universal: {
|
||||
universalIdentifier: pageLayoutTabEntity.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
|
||||
+1
@@ -44,5 +44,6 @@ export const fromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreate = ({
|
||||
gridPosition: createPageLayoutWidgetInput.gridPosition,
|
||||
configuration: createPageLayoutWidgetInput.configuration,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
conditionalDisplay: null,
|
||||
};
|
||||
};
|
||||
|
||||
+2
@@ -87,6 +87,8 @@ export const fromPageLayoutWidgetEntityToFlatPageLayoutWidget = ({
|
||||
objectMetadataUniversalIdentifier,
|
||||
gridPosition: pageLayoutWidgetEntityWithoutRelations.gridPosition,
|
||||
configuration: configurationWithUniversalIdentifiers,
|
||||
conditionalDisplay:
|
||||
pageLayoutWidgetEntityWithoutRelations.conditionalDisplay,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
+3
@@ -70,6 +70,8 @@ export class WorkspaceFlatPageLayoutMapCacheService extends WorkspaceCacheProvid
|
||||
createIdToUniversalIdentifierMap(applications);
|
||||
const objectMetadataIdToUniversalIdentifierMap =
|
||||
createIdToUniversalIdentifierMap(objectMetadatas);
|
||||
const pageLayoutTabIdToUniversalIdentifierMap =
|
||||
createIdToUniversalIdentifierMap(pageLayoutTabs);
|
||||
|
||||
const flatPageLayoutMaps = createEmptyFlatEntityMaps();
|
||||
|
||||
@@ -81,6 +83,7 @@ export class WorkspaceFlatPageLayoutMapCacheService extends WorkspaceCacheProvid
|
||||
},
|
||||
applicationIdToUniversalIdentifierMap,
|
||||
objectMetadataIdToUniversalIdentifierMap,
|
||||
pageLayoutTabIdToUniversalIdentifierMap,
|
||||
});
|
||||
|
||||
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
|
||||
|
||||
+1
@@ -37,5 +37,6 @@ export const fromCreatePageLayoutInputToFlatPageLayoutToCreate = ({
|
||||
universalIdentifier: pageLayoutId,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
tabIds: [],
|
||||
defaultTabToFocusOnMobileAndSidePanelId: null,
|
||||
};
|
||||
};
|
||||
|
||||
+21
@@ -11,6 +11,7 @@ export const transformPageLayoutEntityToFlatPageLayout = ({
|
||||
entity: pageLayoutEntity,
|
||||
applicationIdToUniversalIdentifierMap,
|
||||
objectMetadataIdToUniversalIdentifierMap,
|
||||
pageLayoutTabIdToUniversalIdentifierMap,
|
||||
}: FromEntityToFlatEntityArgs<'pageLayout'>): FlatPageLayout => {
|
||||
const applicationUniversalIdentifier =
|
||||
applicationIdToUniversalIdentifierMap.get(pageLayoutEntity.applicationId);
|
||||
@@ -38,6 +39,23 @@ export const transformPageLayoutEntityToFlatPageLayout = ({
|
||||
}
|
||||
}
|
||||
|
||||
let defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier: string | null =
|
||||
null;
|
||||
|
||||
if (isDefined(pageLayoutEntity.defaultTabToFocusOnMobileAndSidePanelId)) {
|
||||
defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier =
|
||||
pageLayoutTabIdToUniversalIdentifierMap.get(
|
||||
pageLayoutEntity.defaultTabToFocusOnMobileAndSidePanelId,
|
||||
) ?? null;
|
||||
|
||||
if (!isDefined(defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`PageLayoutTab with id ${pageLayoutEntity.defaultTabToFocusOnMobileAndSidePanelId} not found for pageLayout ${pageLayoutEntity.id}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
createdAt: pageLayoutEntity.createdAt.toISOString(),
|
||||
deletedAt: pageLayoutEntity.deletedAt?.toISOString() ?? null,
|
||||
@@ -50,6 +68,8 @@ export const transformPageLayoutEntityToFlatPageLayout = ({
|
||||
universalIdentifier: pageLayoutEntity.universalIdentifier,
|
||||
applicationId: pageLayoutEntity.applicationId,
|
||||
tabIds: pageLayoutEntity.tabs.map((tab) => tab.id),
|
||||
defaultTabToFocusOnMobileAndSidePanelId:
|
||||
pageLayoutEntity.defaultTabToFocusOnMobileAndSidePanelId,
|
||||
__universal: {
|
||||
universalIdentifier: pageLayoutEntity.universalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
@@ -57,6 +77,7 @@ export const transformPageLayoutEntityToFlatPageLayout = ({
|
||||
tabUniversalIdentifiers: pageLayoutEntity.tabs.map(
|
||||
(tab) => tab.universalIdentifier,
|
||||
),
|
||||
defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
+15
-1
@@ -1,10 +1,15 @@
|
||||
import { Field, Float, ObjectType } from '@nestjs/graphql';
|
||||
import { Field, Float, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { PageLayoutWidgetDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/page-layout-widget.dto';
|
||||
|
||||
registerEnumType(PageLayoutTabLayoutMode, {
|
||||
name: 'PageLayoutTabLayoutMode',
|
||||
});
|
||||
|
||||
@ObjectType('PageLayoutTab')
|
||||
export class PageLayoutTabDTO {
|
||||
@IDField(() => UUIDScalarType)
|
||||
@@ -22,6 +27,15 @@ export class PageLayoutTabDTO {
|
||||
@Field(() => [PageLayoutWidgetDTO], { nullable: true })
|
||||
widgets?: PageLayoutWidgetDTO[] | null;
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
icon?: string | null;
|
||||
|
||||
@Field(() => PageLayoutTabLayoutMode, {
|
||||
nullable: true, // Not nullable in the database, but we need to make it nullable here until the frontend consumes the new type
|
||||
defaultValue: PageLayoutTabLayoutMode.GRID,
|
||||
})
|
||||
layoutMode: PageLayoutTabLayoutMode;
|
||||
|
||||
@Field()
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
+12
@@ -1,5 +1,6 @@
|
||||
import { ObjectType } from '@nestjs/graphql';
|
||||
|
||||
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
@@ -52,6 +53,17 @@ export class PageLayoutTabEntity
|
||||
})
|
||||
widgets: Relation<PageLayoutWidgetEntity[]>;
|
||||
|
||||
@Column({ nullable: true, type: 'varchar' })
|
||||
icon: string | null;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: Object.values(PageLayoutTabLayoutMode),
|
||||
nullable: false,
|
||||
default: PageLayoutTabLayoutMode.GRID,
|
||||
})
|
||||
layoutMode: PageLayoutTabLayoutMode;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
+5
@@ -1,6 +1,8 @@
|
||||
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
import { PageLayoutWidgetConditionalDisplay } from 'twenty-shared/types';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { WidgetConfiguration } from 'src/engine/metadata-modules/page-layout-widget/dtos/widget-configuration.interface';
|
||||
@@ -47,6 +49,9 @@ export class PageLayoutWidgetDTO {
|
||||
@Field(() => WidgetConfiguration, { nullable: false })
|
||||
configuration: AllPageLayoutWidgetConfiguration;
|
||||
|
||||
@Field(() => GraphQLJSON, { nullable: true })
|
||||
conditionalDisplay?: PageLayoutWidgetConditionalDisplay | null;
|
||||
|
||||
@Field()
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
+4
@@ -1,5 +1,6 @@
|
||||
import { ObjectType } from '@nestjs/graphql';
|
||||
|
||||
import { PageLayoutWidgetConditionalDisplay } from 'twenty-shared/types';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
@@ -70,6 +71,9 @@ export class PageLayoutWidgetEntity<
|
||||
@JoinColumn({ name: 'objectMetadataId' })
|
||||
objectMetadata: Relation<ObjectMetadataEntity> | null;
|
||||
|
||||
@Column({ type: 'jsonb', nullable: true })
|
||||
conditionalDisplay: JsonbProperty<PageLayoutWidgetConditionalDisplay | null>;
|
||||
|
||||
@Column({ type: 'jsonb', nullable: false })
|
||||
gridPosition: JsonbProperty<GridPosition>;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
import { SerializedRelation } from 'twenty-shared/types';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { PageLayoutTabDTO } from 'src/engine/metadata-modules/page-layout-tab/dtos/page-layout-tab.dto';
|
||||
@@ -28,6 +29,9 @@ export class PageLayoutDTO {
|
||||
@Field(() => [PageLayoutTabDTO], { nullable: true })
|
||||
tabs?: PageLayoutTabDTO[] | null;
|
||||
|
||||
@Field(() => UUIDScalarType, { nullable: true })
|
||||
defaultTabToFocusOnMobileAndSidePanelId?: SerializedRelation;
|
||||
|
||||
@Field()
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
+10
@@ -59,6 +59,16 @@ export class PageLayoutEntity
|
||||
})
|
||||
tabs: Relation<PageLayoutTabEntity[]>;
|
||||
|
||||
@Column({ nullable: true, type: 'uuid' })
|
||||
defaultTabToFocusOnMobileAndSidePanelId: string | null;
|
||||
|
||||
@ManyToOne(() => PageLayoutTabEntity, {
|
||||
onDelete: 'SET NULL',
|
||||
nullable: true,
|
||||
})
|
||||
@JoinColumn({ name: 'defaultTabToFocusOnMobileAndSidePanelId' })
|
||||
defaultTabToFocusOnMobileAndSidePanel: Relation<PageLayoutTabEntity> | null;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
+4
@@ -1,5 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
|
||||
import { computeDiffBetweenObjects, isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -236,6 +237,8 @@ export class PageLayoutUpdateService {
|
||||
universalIdentifier: tabId,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
widgetIds: [],
|
||||
icon: null,
|
||||
layoutMode: PageLayoutTabLayoutMode.GRID,
|
||||
};
|
||||
},
|
||||
);
|
||||
@@ -392,6 +395,7 @@ export class PageLayoutUpdateService {
|
||||
deletedAt: null,
|
||||
universalIdentifier: widgetId,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
conditionalDisplay: null,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
+3
@@ -9,6 +9,7 @@ export const fromFlatPageLayoutToPageLayoutDto = (
|
||||
updatedAt,
|
||||
deletedAt,
|
||||
tabIds: _tabIds,
|
||||
defaultTabToFocusOnMobileAndSidePanelId,
|
||||
...rest
|
||||
} = flatPageLayout;
|
||||
|
||||
@@ -17,5 +18,7 @@ export const fromFlatPageLayoutToPageLayoutDto = (
|
||||
createdAt: new Date(createdAt),
|
||||
updatedAt: new Date(updatedAt),
|
||||
deletedAt: deletedAt ? new Date(deletedAt) : null,
|
||||
defaultTabToFocusOnMobileAndSidePanelId:
|
||||
defaultTabToFocusOnMobileAndSidePanelId ?? undefined,
|
||||
};
|
||||
};
|
||||
|
||||
+3
@@ -1,4 +1,5 @@
|
||||
import { isDefined } from 'class-validator';
|
||||
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
|
||||
|
||||
import { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type';
|
||||
import { STANDARD_PAGE_LAYOUTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-page-layout.constant';
|
||||
@@ -64,5 +65,7 @@ export const createStandardPageLayoutTabFlatMetadata = <
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
deletedAt: null,
|
||||
icon: null,
|
||||
layoutMode: PageLayoutTabLayoutMode.GRID,
|
||||
};
|
||||
};
|
||||
|
||||
+1
@@ -87,5 +87,6 @@ export const createStandardPageLayoutWidgetFlatMetadata = <
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
deletedAt: null,
|
||||
conditionalDisplay: null,
|
||||
};
|
||||
};
|
||||
|
||||
+1
@@ -41,5 +41,6 @@ export const createStandardPageLayoutFlatMetadata = ({
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
deletedAt: null,
|
||||
defaultTabToFocusOnMobileAndSidePanelId: null,
|
||||
};
|
||||
};
|
||||
|
||||
+2
@@ -798,6 +798,8 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatObjectMetadataMaps:
|
||||
optimisticAllFlatEntityMaps.flatObjectMetadataMaps,
|
||||
flatPageLayoutTabMaps:
|
||||
optimisticAllFlatEntityMaps.flatPageLayoutTabMaps,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
|
||||
+1
@@ -42,6 +42,7 @@ export const ALL_JSONB_PROPERTIES_BY_METADATA_NAME = {
|
||||
pageLayoutWidget: {
|
||||
gridPosition: 'gridPosition',
|
||||
configuration: 'configuration',
|
||||
conditionalDisplay: 'conditionalDisplay',
|
||||
},
|
||||
commandMenuItem: {},
|
||||
navigationMenuItem: {},
|
||||
|
||||
@@ -129,6 +129,8 @@ export { ObjectRecordGroupByDateGranularity } from './ObjectRecordGroupByDateGra
|
||||
export type { ObjectsPermissions } from './ObjectsPermissions';
|
||||
export type { ObjectsPermissionsByRoleId } from './ObjectsPermissionsByRoleId';
|
||||
export type { OrderBy } from './OrderBy';
|
||||
export { PageLayoutTabLayoutMode } from './page-layout/PageLayoutTabLayoutMode';
|
||||
export type { PageLayoutWidgetConditionalDisplay } from './page-layout/PageLayoutWidgetConditionalDisplay';
|
||||
export type { PartialFieldMetadataItem } from './PartialFieldMetadataItem';
|
||||
export type { PartialFieldMetadataItemOption } from './PartialFieldMetadataOption';
|
||||
export type { QueryCursorDirection } from './QueryCursorDirection';
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export enum PageLayoutTabLayoutMode {
|
||||
GRID = 'GRID',
|
||||
VERTICAL_LIST = 'VERTICAL_LIST',
|
||||
CANVAS = 'CANVAS',
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// TODO: Loose typing for now. Add proper typing once product is clear.
|
||||
export type PageLayoutWidgetConditionalDisplay = object;
|
||||
Reference in New Issue
Block a user