Add Dashboard in Lab, make Calendar available out of lab (#15560)

As per title!
This commit is contained in:
Charles Bochet
2025-11-03 15:40:26 +01:00
committed by GitHub
parent b32ab35db9
commit 20576f2ee7
18 changed files with 51 additions and 131 deletions
@@ -1255,10 +1255,6 @@ export enum FeatureFlagKey {
IS_AIRTABLE_INTEGRATION_ENABLED = 'IS_AIRTABLE_INTEGRATION_ENABLED',
IS_AI_ENABLED = 'IS_AI_ENABLED',
IS_APPLICATION_ENABLED = 'IS_APPLICATION_ENABLED',
IS_CALENDAR_VIEW_ENABLED = 'IS_CALENDAR_VIEW_ENABLED',
IS_CORE_VIEW_ENABLED = 'IS_CORE_VIEW_ENABLED',
IS_CORE_VIEW_SYNCING_ENABLED = 'IS_CORE_VIEW_SYNCING_ENABLED',
IS_DYNAMIC_SEARCH_FIELDS_ENABLED = 'IS_DYNAMIC_SEARCH_FIELDS_ENABLED',
IS_EMAILING_DOMAIN_ENABLED = 'IS_EMAILING_DOMAIN_ENABLED',
IS_IMAP_SMTP_CALDAV_ENABLED = 'IS_IMAP_SMTP_CALDAV_ENABLED',
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
@@ -1268,7 +1264,6 @@ export enum FeatureFlagKey {
IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
IS_RECORD_PAGE_LAYOUT_ENABLED = 'IS_RECORD_PAGE_LAYOUT_ENABLED',
IS_RELATION_CONNECT_ENABLED = 'IS_RELATION_CONNECT_ENABLED',
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED',
IS_WORKFLOW_RUN_STOPPAGE_ENABLED = 'IS_WORKFLOW_RUN_STOPPAGE_ENABLED',
@@ -1219,10 +1219,6 @@ export enum FeatureFlagKey {
IS_AIRTABLE_INTEGRATION_ENABLED = 'IS_AIRTABLE_INTEGRATION_ENABLED',
IS_AI_ENABLED = 'IS_AI_ENABLED',
IS_APPLICATION_ENABLED = 'IS_APPLICATION_ENABLED',
IS_CALENDAR_VIEW_ENABLED = 'IS_CALENDAR_VIEW_ENABLED',
IS_CORE_VIEW_ENABLED = 'IS_CORE_VIEW_ENABLED',
IS_CORE_VIEW_SYNCING_ENABLED = 'IS_CORE_VIEW_SYNCING_ENABLED',
IS_DYNAMIC_SEARCH_FIELDS_ENABLED = 'IS_DYNAMIC_SEARCH_FIELDS_ENABLED',
IS_EMAILING_DOMAIN_ENABLED = 'IS_EMAILING_DOMAIN_ENABLED',
IS_IMAP_SMTP_CALDAV_ENABLED = 'IS_IMAP_SMTP_CALDAV_ENABLED',
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
@@ -1232,7 +1228,6 @@ export enum FeatureFlagKey {
IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
IS_RECORD_PAGE_LAYOUT_ENABLED = 'IS_RECORD_PAGE_LAYOUT_ENABLED',
IS_RELATION_CONNECT_ENABLED = 'IS_RELATION_CONNECT_ENABLED',
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED',
IS_WORKFLOW_RUN_STOPPAGE_ENABLED = 'IS_WORKFLOW_RUN_STOPPAGE_ENABLED',
@@ -6,12 +6,17 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { coreViewsState } from '@/views/states/coreViewState';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { useFeatureFlagsMap } from '@/workspace/hooks/useFeatureFlagsMap';
import { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import {
FeatureFlagKey,
FieldMetadataType,
} from '~/generated-metadata/graphql';
import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData';
export const useWorkspaceFavorites = () => {
const featureFlags = useFeatureFlagsMap();
const { workspaceFavorites } = usePrefetchedFavoritesData();
const coreViews = useRecoilValue(coreViewsState);
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
@@ -33,7 +38,17 @@ export const useWorkspaceFavorites = () => {
[favoriteObjectMetadataItem.fields],
);
const views = coreViews.map(convertCoreViewToView);
const [dashboardObjectMetadataId] = objectMetadataItems
.filter((item) => item.nameSingular === CoreObjectNameSingular.Dashboard)
.map((item) => item.id);
const views = coreViews
.map(convertCoreViewToView)
.filter(
(view) =>
featureFlags[FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED] === true ||
view.objectMetadataId !== dashboardObjectMetadataId,
);
const sortedWorkspaceFavorites = useMemo(
() =>
@@ -76,7 +91,6 @@ export const useWorkspaceFavorites = () => {
);
return {
workspaceFavorites: sortedWorkspaceFavorites,
workspaceFavoritesObjectMetadataItems:
activeNonSystemObjectMetadataItemsInWorkspaceFavorites,
};
@@ -21,7 +21,6 @@ import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
import { useGetAvailableFieldsForCalendar } from '@/views/view-picker/hooks/useGetAvailableFieldsForCalendar';
import { useGetAvailableFieldsForKanban } from '@/views/view-picker/hooks/useGetAvailableFieldsForKanban';
import { useFeatureFlagsMap } from '@/workspace/hooks/useFeatureFlagsMap';
import { useLingui } from '@lingui/react/macro';
import { useCallback } from 'react';
import { useRecoilValue } from 'recoil';
@@ -38,7 +37,7 @@ import {
OverflowingTextWithTooltip,
} from 'twenty-ui/display';
import { MenuItem, MenuItemSelect, MenuItemToggle } from 'twenty-ui/navigation';
import { FeatureFlagKey, ViewCalendarLayout } from '~/generated/graphql';
import { ViewCalendarLayout } from '~/generated/graphql';
export const ObjectOptionsDropdownLayoutContent = () => {
const { t } = useLingui();
@@ -113,14 +112,10 @@ export const ObjectOptionsDropdownLayoutContent = () => {
const isDefaultView = currentView?.key === 'INDEX';
const nbsp = '\u00A0';
const featureFlags = useFeatureFlagsMap();
const hasCalendarViewEnabled =
featureFlags[FeatureFlagKey.IS_CALENDAR_VIEW_ENABLED];
const selectableItemIdArray = [
ViewType.Table,
...(isDefaultView ? [] : [ViewType.Kanban]),
...(!isDefaultView && hasCalendarViewEnabled ? [ViewType.Calendar] : []),
...(!isDefaultView ? [ViewType.Calendar] : []),
ViewOpenRecordInType.SIDE_PANEL,
...(currentView?.type === ViewType.Kanban ? ['Group'] : []),
...(currentView?.type === ViewType.Calendar
@@ -172,22 +167,20 @@ export const ObjectOptionsDropdownLayoutContent = () => {
}}
/>
</SelectableListItem>
{hasCalendarViewEnabled && (
<SelectableListItem
itemId={ViewType.Calendar}
onEnter={() => {
setAndPersistViewType(ViewType.Calendar);
}}
>
<MenuItemSelect
LeftIcon={viewTypeIconMapping(ViewType.Calendar)}
text={t`Calendar`}
selected={currentView?.type === ViewType.Calendar}
focused={selectedItemId === ViewType.Calendar}
onClick={handleSelectCalendarViewType}
/>
</SelectableListItem>
)}
<SelectableListItem
itemId={ViewType.Calendar}
onEnter={() => {
setAndPersistViewType(ViewType.Calendar);
}}
>
<MenuItemSelect
LeftIcon={viewTypeIconMapping(ViewType.Calendar)}
text={t`Calendar`}
selected={currentView?.type === ViewType.Calendar}
focused={selectedItemId === ViewType.Calendar}
onClick={handleSelectCalendarViewType}
/>
</SelectableListItem>
<SelectableListItem
itemId={ViewType.Kanban}
onEnter={() => {
@@ -108,7 +108,7 @@ describe('evaluateTabVisibility', () => {
evaluateTabVisibility(
{
...baseConfig,
ifFeaturesDisabled: [FeatureFlagKey.IS_CALENDAR_VIEW_ENABLED],
ifFeaturesDisabled: [FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED],
},
baseContext,
),
@@ -121,7 +121,7 @@ describe('evaluateTabVisibility', () => {
currentWorkspace: {
featureFlags: [
{ key: FeatureFlagKey.IS_AI_ENABLED, value: true },
{ key: FeatureFlagKey.IS_CALENDAR_VIEW_ENABLED, value: true },
{ key: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED, value: true },
],
},
};
@@ -129,7 +129,7 @@ describe('evaluateTabVisibility', () => {
evaluateTabVisibility(
{
...baseConfig,
ifFeaturesDisabled: [FeatureFlagKey.IS_CALENDAR_VIEW_ENABLED],
ifFeaturesDisabled: [FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED],
},
ctx,
),
@@ -4,8 +4,8 @@ import { useLabPublicFeatureFlags } from '@/settings/lab/hooks/useLabPublicFeatu
import styled from '@emotion/styled';
import { useState } from 'react';
import { useRecoilValue } from 'recoil';
import { type FeatureFlagKey } from '~/generated/graphql';
import { Card } from 'twenty-ui/layout';
import { type FeatureFlagKey } from '~/generated/graphql';
const StyledCardGrid = styled.div`
display: grid;
@@ -36,11 +36,9 @@ import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states
import { viewPickerKanbanFieldMetadataIdComponentState } from '@/views/view-picker/states/viewPickerKanbanFieldMetadataIdComponentState';
import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState';
import { viewPickerTypeComponentState } from '@/views/view-picker/states/viewPickerTypeComponentState';
import { useFeatureFlagsMap } from '@/workspace/hooks/useFeatureFlagsMap';
import { useLingui } from '@lingui/react/macro';
import { useMemo, useState } from 'react';
import { IconX } from 'twenty-ui/display';
import { FeatureFlagKey } from '~/generated/graphql';
const StyledFieldAvailableContainer = styled.div`
color: ${({ theme }) => theme.font.color.light};
@@ -93,16 +91,6 @@ export const ViewPickerContentCreateMode = () => {
const { availableFieldsForKanban } = useGetAvailableFieldsForKanban();
const { availableFieldsForCalendar } = useGetAvailableFieldsForCalendar();
const featureFlags = useFeatureFlagsMap();
const hasCalendarViewEnabled =
featureFlags[FeatureFlagKey.IS_CALENDAR_VIEW_ENABLED];
const viewPickerTypeOptions = VIEW_PICKER_TYPE_SELECT_OPTIONS.filter(
(option) => {
return option.value !== ViewType.Calendar || hasCalendarViewEnabled;
},
);
useHotkeysOnFocusedElement({
keys: [Key.Enter],
@@ -187,7 +175,7 @@ export const ViewPickerContentCreateMode = () => {
setViewPickerIsDirty(true);
setViewPickerType(value);
}}
options={viewPickerTypeOptions.map((option) => ({
options={VIEW_PICKER_TYPE_SELECT_OPTIONS.map((option) => ({
...option,
label: t(option.label),
}))}
@@ -32,11 +32,11 @@ export const PUBLIC_FEATURE_FLAGS: PublicFeatureFlag[] = [
},
},
{
key: FeatureFlagKey.IS_CALENDAR_VIEW_ENABLED,
key: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
metadata: {
label: 'Calendar View',
description: 'View and manage calendar events',
imagePath: 'https://twenty.com/images/lab/is-calendar-view-enabled.png',
label: 'Dashboards',
description: 'Enable dashboards',
imagePath: 'https://twenty.com/images/lab/is-dashboards-enabled.png',
},
},
{
@@ -8,16 +8,11 @@ export enum FeatureFlagKey {
IS_APPLICATION_ENABLED = 'IS_APPLICATION_ENABLED',
IS_IMAP_SMTP_CALDAV_ENABLED = 'IS_IMAP_SMTP_CALDAV_ENABLED',
IS_MORPH_RELATION_ENABLED = 'IS_MORPH_RELATION_ENABLED',
IS_RELATION_CONNECT_ENABLED = 'IS_RELATION_CONNECT_ENABLED',
IS_CORE_VIEW_SYNCING_ENABLED = 'IS_CORE_VIEW_SYNCING_ENABLED',
IS_CORE_VIEW_ENABLED = 'IS_CORE_VIEW_ENABLED',
IS_WORKSPACE_MIGRATION_V2_ENABLED = 'IS_WORKSPACE_MIGRATION_V2_ENABLED',
IS_PAGE_LAYOUT_ENABLED = 'IS_PAGE_LAYOUT_ENABLED',
IS_RECORD_PAGE_LAYOUT_ENABLED = 'IS_RECORD_PAGE_LAYOUT_ENABLED',
IS_MESSAGE_FOLDER_CONTROL_ENABLED = 'IS_MESSAGE_FOLDER_CONTROL_ENABLED',
IS_CALENDAR_VIEW_ENABLED = 'IS_CALENDAR_VIEW_ENABLED',
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
IS_EMAILING_DOMAIN_ENABLED = 'IS_EMAILING_DOMAIN_ENABLED',
IS_DYNAMIC_SEARCH_FIELDS_ENABLED = 'IS_DYNAMIC_SEARCH_FIELDS_ENABLED',
IS_WORKFLOW_RUN_STOPPAGE_ENABLED = 'IS_WORKFLOW_RUN_STOPPAGE_ENABLED',
}
@@ -131,17 +131,12 @@ describe('WorkspaceEntityManager', () => {
IS_APPLICATION_ENABLED: false,
IS_IMAP_SMTP_CALDAV_ENABLED: false,
IS_MORPH_RELATION_ENABLED: false,
IS_RELATION_CONNECT_ENABLED: false,
IS_CORE_VIEW_SYNCING_ENABLED: false,
IS_CORE_VIEW_ENABLED: false,
IS_WORKSPACE_MIGRATION_V2_ENABLED: false,
IS_PAGE_LAYOUT_ENABLED: false,
IS_RECORD_PAGE_LAYOUT_ENABLED: false,
IS_MESSAGE_FOLDER_CONTROL_ENABLED: false,
IS_CALENDAR_VIEW_ENABLED: false,
IS_PUBLIC_DOMAIN_ENABLED: false,
IS_EMAILING_DOMAIN_ENABLED: false,
IS_DYNAMIC_SEARCH_FIELDS_ENABLED: false,
IS_WORKFLOW_RUN_STOPPAGE_ENABLED: false,
},
eventEmitterService: {
@@ -162,17 +157,12 @@ describe('WorkspaceEntityManager', () => {
IS_APPLICATION_ENABLED: false,
IS_IMAP_SMTP_CALDAV_ENABLED: false,
IS_MORPH_RELATION_ENABLED: false,
IS_RELATION_CONNECT_ENABLED: false,
IS_CORE_VIEW_SYNCING_ENABLED: false,
IS_CORE_VIEW_ENABLED: false,
IS_WORKSPACE_MIGRATION_V2_ENABLED: false,
IS_PAGE_LAYOUT_ENABLED: false,
IS_RECORD_PAGE_LAYOUT_ENABLED: false,
IS_MESSAGE_FOLDER_CONTROL_ENABLED: false,
IS_CALENDAR_VIEW_ENABLED: false,
IS_PUBLIC_DOMAIN_ENABLED: false,
IS_EMAILING_DOMAIN_ENABLED: false,
IS_DYNAMIC_SEARCH_FIELDS_ENABLED: false,
},
permissionsPerRoleId: {},
} as WorkspaceDataSource;
@@ -71,11 +71,6 @@ export const seedFeatureFlags = async (
workspaceId: workspaceId,
value: false,
},
{
key: FeatureFlagKey.IS_CALENDAR_VIEW_ENABLED,
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IS_PUBLIC_DOMAIN_ENABLED,
workspaceId: workspaceId,
@@ -86,11 +81,6 @@ export const seedFeatureFlags = async (
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IS_DYNAMIC_SEARCH_FIELDS_ENABLED,
workspaceId: workspaceId,
value: false,
},
])
.execute();
};
@@ -112,7 +112,7 @@ type RecordSeedConfig = {
// Organize seeds into dependency batches for parallel insertion
const getRecordSeedsBatches = (
workspaceId: string,
featureFlags?: Record<FeatureFlagKey, boolean>,
_featureFlags?: Record<FeatureFlagKey, boolean>,
): RecordSeedConfig[][] => {
// Batch 1: No dependencies
const batch1: RecordSeedConfig[] = [
@@ -140,15 +140,11 @@ const getRecordSeedsBatches = (
pgColumns: CONNECTED_ACCOUNT_DATA_SEED_COLUMNS,
recordSeeds: CONNECTED_ACCOUNT_DATA_SEEDS,
},
...(featureFlags?.[FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED]
? [
{
tableName: 'dashboard',
pgColumns: DASHBOARD_DATA_SEED_COLUMNS,
recordSeeds: getDashboardDataSeeds(workspaceId),
},
]
: []),
{
tableName: 'dashboard',
pgColumns: DASHBOARD_DATA_SEED_COLUMNS,
recordSeeds: getDashboardDataSeeds(workspaceId),
},
];
// Batch 3: Depends on company and connectedAccount
@@ -2,7 +2,6 @@ import { isString } from '@sniptt/guards';
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 { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
@@ -41,7 +40,6 @@ export const prefillCoreViews = async ({
coreDataSource,
workspaceId,
objectMetadataItems,
featureFlags,
workspaceSchemaName,
}: PrefillCoreViewsArgs): Promise<ViewEntity[]> => {
const views = [
@@ -58,9 +56,7 @@ export const prefillCoreViews = async ({
workflowRunsAllView(objectMetadataItems, true),
];
if (featureFlags?.[FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED]) {
views.push(dashboardsAllView(objectMetadataItems, true));
}
views.push(dashboardsAllView(objectMetadataItems, true));
const queryRunner = coreDataSource.createQueryRunner();
@@ -1,7 +1,6 @@
import { type EntityManager } from 'typeorm';
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 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';
@@ -22,7 +21,7 @@ export const prefillViews = async (
entityManager: EntityManager,
schemaName: string,
objectMetadataItems: ObjectMetadataEntity[],
featureFlags?: Record<string, boolean>,
_featureFlags?: Record<string, boolean>,
) => {
const customObjectMetadataItems = objectMetadataItems.filter(
(item) => item.isCustom,
@@ -47,9 +46,7 @@ export const prefillViews = async (
...customViews,
];
if (featureFlags?.[FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED]) {
views.push(dashboardsAllView(objectMetadataItems));
}
views.push(dashboardsAllView(objectMetadataItems));
return createWorkspaceViews(entityManager, schemaName, views);
};
@@ -5,14 +5,12 @@ import { RelationOnDeleteAction } from 'src/engine/metadata-modules/field-metada
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';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
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 { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator';
import { WorkspaceIsFieldUIReadOnly } from 'src/engine/twenty-orm/decorators/workspace-is-field-ui-readonly.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';
@@ -246,16 +244,10 @@ export class AttachmentWorkspaceEntity extends BaseWorkspaceEntity {
inverseSideFieldKey: 'attachments',
onDelete: RelationOnDeleteAction.CASCADE,
})
@WorkspaceGate({
featureFlag: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
})
@WorkspaceIsNullable()
dashboard: Relation<DashboardWorkspaceEntity> | null;
@WorkspaceJoinColumn('dashboard')
@WorkspaceGate({
featureFlag: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
})
dashboardId: string | null;
@WorkspaceRelation({
@@ -5,7 +5,6 @@ import { RelationOnDeleteAction } from 'src/engine/metadata-modules/field-metada
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';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
@@ -13,7 +12,6 @@ import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceFieldIndex } from 'src/engine/twenty-orm/decorators/workspace-field-index.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator';
import { WorkspaceIsFieldUIReadOnly } from 'src/engine/twenty-orm/decorators/workspace-is-field-ui-readonly.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSearchable } from 'src/engine/twenty-orm/decorators/workspace-is-searchable.decorator';
@@ -45,9 +43,6 @@ export const SEARCH_FIELDS_FOR_DASHBOARD: FieldTypeAndNameMetadata[] = [
icon: STANDARD_OBJECT_ICONS.dashboard,
labelIdentifierStandardId: DASHBOARD_STANDARD_FIELD_IDS.title,
})
@WorkspaceGate({
featureFlag: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
})
@WorkspaceIsSearchable()
export class DashboardWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
@@ -4,14 +4,12 @@ import { FieldMetadataType } 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';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-on-delete-action.type';
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 { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.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';
@@ -223,16 +221,10 @@ export class FavoriteWorkspaceEntity extends BaseWorkspaceEntity {
inverseSideFieldKey: 'favorites',
onDelete: RelationOnDeleteAction.CASCADE,
})
@WorkspaceGate({
featureFlag: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
})
@WorkspaceIsNullable()
dashboard: Relation<DashboardWorkspaceEntity> | null;
@WorkspaceJoinColumn('dashboard')
@WorkspaceGate({
featureFlag: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
})
dashboardId: string;
@WorkspaceField({
@@ -5,13 +5,11 @@ import { RelationOnDeleteAction } from 'src/engine/metadata-modules/field-metada
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';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
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 { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.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';
@@ -256,16 +254,10 @@ export class TimelineActivityWorkspaceEntity extends BaseWorkspaceEntity {
inverseSideFieldKey: 'timelineActivities',
onDelete: RelationOnDeleteAction.SET_NULL,
})
@WorkspaceGate({
featureFlag: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
})
@WorkspaceIsNullable()
dashboard: Relation<DashboardWorkspaceEntity> | null;
@WorkspaceJoinColumn('dashboard')
@WorkspaceGate({
featureFlag: FeatureFlagKey.IS_PAGE_LAYOUT_ENABLED,
})
dashboardId: string | null;
@WorkspaceDynamicRelation({