chore: remove IS_DASHBOARD_V2_ENABLED feature flag (#19079)

## Summary
- Remove the `IS_DASHBOARD_V2_ENABLED` feature flag from the codebase
- Dashboard V2 features (gauge charts, line charts, pie charts) are now
always enabled
- Remove the validator gate that blocked gauge chart creation/update
without the flag
- Clean up all related code: seed data, dev-seeder service, widget
seeds, and test mocks
This commit is contained in:
Charles Bochet
2026-03-29 10:45:54 +02:00
committed by GitHub
parent e8cb086b64
commit 28de34cf20
11 changed files with 20 additions and 117 deletions
@@ -29,7 +29,6 @@ const getFieldId = (
export const getPageLayoutWidgetDataSeeds = (
workspaceId: string,
objectMetadataItems: ObjectMetadataEntity[],
isDashboardV2Enabled: boolean,
): SeederFlatPageLayoutWidget[] => {
const opportunityObject = objectMetadataItems.find(
(obj) =>
@@ -524,9 +523,10 @@ export const getPageLayoutWidgetDataSeeds = (
} satisfies SeederFlatPageLayoutWidget,
].filter(isDefined);
const v2Widgets = isDashboardV2Enabled
? getPageLayoutWidgetDataSeedsV2(workspaceId, objectMetadataItems)
: [];
const v2Widgets = getPageLayoutWidgetDataSeedsV2(
workspaceId,
objectMetadataItems,
);
return [...v1Widgets, ...v2Widgets];
};
@@ -45,11 +45,6 @@ export const seedFeatureFlags = async ({
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IS_DASHBOARD_V2_ENABLED,
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED,
workspaceId: workspaceId,
@@ -11,20 +11,17 @@ export const seedPageLayoutWidgets = async ({
schemaName,
workspaceId,
objectMetadataItems,
isDashboardV2Enabled,
workspaceCustomApplicationId,
}: {
dataSource: DataSource;
schemaName: string;
workspaceId: string;
objectMetadataItems: ObjectMetadataEntity[];
isDashboardV2Enabled: boolean;
workspaceCustomApplicationId: string;
}) => {
const widgetSeeds = getPageLayoutWidgetDataSeeds(
workspaceId,
objectMetadataItems,
isDashboardV2Enabled,
);
const pageLayoutWidgets = widgetSeeds.map((widget) => {
@@ -2,7 +2,6 @@ import { Injectable, Logger } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FeatureFlagKey } from 'twenty-shared/types';
import { DataSource } from 'typeorm';
import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service';
@@ -146,15 +145,11 @@ export class DevSeederService {
relations: { fields: true },
});
const isDashboardV2Enabled =
featureFlagsMap[FeatureFlagKey.IS_DASHBOARD_V2_ENABLED] ?? false;
await seedPageLayoutWidgets({
dataSource: this.coreDataSource,
schemaName: 'core',
workspaceId,
objectMetadataItems,
isDashboardV2Enabled,
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
});
@@ -3,7 +3,6 @@ import { Injectable } from '@nestjs/common';
import { msg, t } from '@lingui/core/macro';
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
import {
FeatureFlagKey,
PageLayoutTabLayoutMode,
PageLayoutWidgetPosition,
type GridPosition,
@@ -13,8 +12,6 @@ import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { FlatPageLayoutWidgetTypeValidatorService } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
import { PageLayoutTabExceptionCode } from 'src/engine/metadata-modules/page-layout-tab/exceptions/page-layout-tab.exception';
import { GraphType } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-type.enum';
import { WidgetType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-type.enum';
import { PageLayoutWidgetExceptionCode } from 'src/engine/metadata-modules/page-layout-widget/exceptions/page-layout-widget.exception';
import { validatePageLayoutWidgetGridPosition } from 'src/engine/metadata-modules/page-layout-widget/utils/validate-page-layout-widget-grid-position.util';
import { validatePageLayoutWidgetVerticalListPosition } from 'src/engine/metadata-modules/page-layout-widget/utils/validate-page-layout-widget-vertical-list-position.util';
@@ -44,9 +41,6 @@ export class FlatPageLayoutWidgetValidatorService {
}: FlatEntityUpdateValidationArgs<
typeof ALL_METADATA_NAME.pageLayoutWidget
>): Promise<FailedFlatEntityValidation<'pageLayoutWidget', 'update'>> {
const isDashboardV2Enabled =
featureFlagsMap[FeatureFlagKey.IS_DASHBOARD_V2_ENABLED] ?? false;
const existingFlatPageLayoutWidget = findFlatEntityByUniversalIdentifier({
universalIdentifier,
flatEntityMaps:
@@ -104,15 +98,6 @@ export class FlatPageLayoutWidgetValidatorService {
validationResult.errors.push(...positionErrors);
const featureFlagErrors = this.validateFeatureFlags({
type: updatedFlatPageLayoutWidget.type,
configuration: updatedFlatPageLayoutWidget.universalConfiguration,
widgetTitle: updatedFlatPageLayoutWidget.title,
isDashboardV2Enabled,
});
validationResult.errors.push(...featureFlagErrors);
const typeSpecificityErrors =
this.flatPageLayoutWidgetTypeValidatorService.validateFlatPageLayoutWidgetTypeSpecificitiesForUpdate(
{
@@ -176,9 +161,6 @@ export class FlatPageLayoutWidgetValidatorService {
}: UniversalFlatEntityValidationArgs<
typeof ALL_METADATA_NAME.pageLayoutWidget
>): Promise<FailedFlatEntityValidation<'pageLayoutWidget', 'create'>> {
const isDashboardV2Enabled =
featureFlagsMap[FeatureFlagKey.IS_DASHBOARD_V2_ENABLED] ?? false;
const validationResult = getEmptyFlatEntityValidationError({
flatEntityMinimalInformation: {
universalIdentifier: flatPageLayoutWidgetToValidate.universalIdentifier,
@@ -236,15 +218,6 @@ export class FlatPageLayoutWidgetValidatorService {
validationResult.errors.push(...positionErrors);
const featureFlagErrors = this.validateFeatureFlags({
type: flatPageLayoutWidgetToValidate.type,
configuration: flatPageLayoutWidgetToValidate.universalConfiguration,
widgetTitle: flatPageLayoutWidgetToValidate.title,
isDashboardV2Enabled,
});
validationResult.errors.push(...featureFlagErrors);
const typeSpecificityErrors =
this.flatPageLayoutWidgetTypeValidatorService.validateFlatPageLayoutWidgetTypeSpecificitiesForCreation(
{
@@ -282,47 +255,6 @@ export class FlatPageLayoutWidgetValidatorService {
return validateWidgetGridPosition(gridPosition, widgetTitle);
}
private validateFeatureFlags({
type,
configuration,
widgetTitle,
isDashboardV2Enabled,
}: {
type: WidgetType | undefined;
configuration: { configurationType?: unknown } | null | undefined;
widgetTitle: string;
isDashboardV2Enabled: boolean;
}): FlatEntityValidationError[] {
if (!isDefined(type) || !isDefined(configuration)) {
return [];
}
if (type !== WidgetType.GRAPH) {
return [];
}
const graphConfiguration = configuration as {
configurationType?: GraphType;
};
if (
graphConfiguration.configurationType === GraphType.GAUGE_CHART &&
!isDashboardV2Enabled
) {
const chartType = graphConfiguration.configurationType;
return [
{
code: PageLayoutWidgetExceptionCode.INVALID_PAGE_LAYOUT_WIDGET_DATA,
message: t`Invalid configuration for widget "${widgetTitle}": Chart type ${chartType} requires IS_DASHBOARD_V2_ENABLED feature flag`,
userFriendlyMessage: msg`This chart type requires the Dashboard V2 feature to be enabled`,
},
];
}
return [];
}
private validatePosition({
position,
pageLayoutTab,