Create Dashboard Workspace Entity (#14112)

Closes https://github.com/twentyhq/core-team-issues/issues/1392

- Added a workspace gate on the entity for the feature flag
`IS_PAGE_LAYOUT_ENABLED`
This commit is contained in:
Raphaël Bosi
2025-08-27 18:20:06 +02:00
committed by GitHub
parent e449e69f4c
commit c5f7dc9e6e
10 changed files with 134 additions and 0 deletions
@@ -3,6 +3,7 @@ import { type ViewFilterOperand as SharedViewFilterOperand } from 'twenty-shared
import { type DataSource, type QueryRunner } from 'typeorm';
import { v4 } from 'uuid';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { ViewFieldEntity } from 'src/engine/core-modules/view/entities/view-field.entity';
import { ViewFilterEntity } from 'src/engine/core-modules/view/entities/view-filter.entity';
import { ViewGroupEntity } from 'src/engine/core-modules/view/entities/view-group.entity';
@@ -13,6 +14,7 @@ import { ViewType } from 'src/engine/core-modules/view/enums/view-type.enum';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
import { companiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view';
import { dashboardsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/dashboards-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 { opportunitiesTableByStageView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-table-by-stage.view';
@@ -30,6 +32,7 @@ export const prefillCoreViews = async (
dataSource: DataSource,
workspaceId: string,
objectMetadataItems: ObjectMetadataEntity[],
featureFlags?: Record<string, boolean>,
): Promise<ViewEntity[]> => {
const views = [
companiesAllView(objectMetadataItems, true),
@@ -45,6 +48,10 @@ export const prefillCoreViews = async (
workflowRunsAllView(objectMetadataItems, true),
];
if (featureFlags?.[FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED]) {
views.push(dashboardsAllView(objectMetadataItems, true));
}
const queryRunner = dataSource.createQueryRunner();
await queryRunner.connect();
@@ -1,10 +1,12 @@
import { v4 } from 'uuid';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
import { companiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view';
import { customAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/custom-all.view';
import { dashboardsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/dashboards-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';
@@ -20,6 +22,7 @@ export const prefillViews = async (
entityManager: WorkspaceEntityManager,
schemaName: string,
objectMetadataItems: ObjectMetadataEntity[],
featureFlags?: Record<string, boolean>,
) => {
const customObjectMetadataItems = objectMetadataItems.filter(
(item) => item.isCustom,
@@ -44,6 +47,10 @@ export const prefillViews = async (
...customViews,
];
if (featureFlags?.[FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED]) {
views.push(dashboardsAllView(objectMetadataItems));
}
return createWorkspaceViews(entityManager, schemaName, views);
};
@@ -13,6 +13,7 @@ export const standardObjectsPrefillData = async (
mainDataSource: DataSource,
schemaName: string,
objectMetadataItems: ObjectMetadataEntity[],
featureFlags?: Record<string, boolean>,
) => {
mainDataSource.transaction(async (entityManager: WorkspaceEntityManager) => {
await prefillCompanies(entityManager, schemaName);
@@ -25,6 +26,7 @@ export const standardObjectsPrefillData = async (
entityManager,
schemaName,
objectMetadataItems,
featureFlags,
);
await prefillWorkspaceFavorites(
@@ -0,0 +1,63 @@
import { msg } from '@lingui/core/macro';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import {
BASE_OBJECT_STANDARD_FIELD_IDS,
DASHBOARD_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 dashboardsAllView = (
objectMetadataItems: ObjectMetadataEntity[],
useCoreNaming = false,
) => {
const dashboardObjectMetadata = objectMetadataItems.find(
(object) => object.standardId === STANDARD_OBJECT_IDS.dashboard,
);
if (!dashboardObjectMetadata) {
throw new Error('Dashboard object metadata not found');
}
return {
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Dashboards',
objectMetadataId: dashboardObjectMetadata.id ?? '',
type: 'table',
key: 'INDEX',
position: 0,
icon: 'IconLayoutDashboard',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
fieldMetadataId:
dashboardObjectMetadata.fields.find(
(field) => field.standardId === DASHBOARD_STANDARD_FIELD_IDS.title,
)?.id ?? '',
position: 0,
isVisible: true,
size: 200,
},
{
fieldMetadataId:
dashboardObjectMetadata.fields.find(
(field) =>
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
)?.id ?? '',
position: 1,
isVisible: true,
size: 150,
},
{
fieldMetadataId:
dashboardObjectMetadata.fields.find(
(field) =>
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt,
)?.id ?? '',
position: 2,
isVisible: true,
size: 150,
},
],
};
};