diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidget.tsx b/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidget.tsx
index aa801e675d..50e8137265 100644
--- a/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidget.tsx
+++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidget.tsx
@@ -1,20 +1,11 @@
-import { WidgetSkeletonLoader } from '@/page-layout/widgets/components/WidgetSkeletonLoader';
+import { PageLayoutWidgetInvalidConfigDisplay } from '@/page-layout/widgets/components/PageLayoutWidgetInvalidConfigDisplay';
import { GraphWidgetAggregateChartRenderer } from '@/page-layout/widgets/graph/graph-widget-aggregate-chart/components/GraphWidgetAggregateChartRenderer';
import { GraphWidgetBarChartRenderer } from '@/page-layout/widgets/graph/graph-widget-bar-chart/components/GraphWidgetBarChartRenderer';
import { GraphWidgetLineChartRenderer } from '@/page-layout/widgets/graph/graph-widget-line-chart/components/GraphWidgetLineChartRenderer';
import { GraphWidgetPieChartRenderer } from '@/page-layout/widgets/graph/graph-widget-pie-chart/components/GraphWidgetPieChartRenderer';
import { useCurrentWidget } from '@/page-layout/widgets/hooks/useCurrentWidget';
-import { lazy, Suspense } from 'react';
import { WidgetConfigurationType } from '~/generated-metadata/graphql';
-const GraphWidgetGaugeChart = lazy(() =>
- import(
- '@/page-layout/widgets/graph/graph-widget-gauge-chart/components/GraphWidgetGaugeChart'
- ).then((module) => ({
- default: module.GraphWidgetGaugeChart,
- })),
-);
-
export const GraphWidget = () => {
const widget = useCurrentWidget();
@@ -24,31 +15,6 @@ export const GraphWidget = () => {
case WidgetConfigurationType.AGGREGATE_CHART:
return ;
- case WidgetConfigurationType.GAUGE_CHART: {
- const gaugeData = {
- value: 0.7,
- min: 0,
- max: 1,
- label: 'Progress',
- };
-
- return (
- }>
-
-
- );
- }
-
case WidgetConfigurationType.PIE_CHART:
return ;
@@ -58,6 +24,9 @@ export const GraphWidget = () => {
case WidgetConfigurationType.LINE_CHART:
return ;
+ case WidgetConfigurationType.GAUGE_CHART:
+ return ;
+
default:
return null;
}
diff --git a/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/ChartTypeSelectionSection.tsx b/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/ChartTypeSelectionSection.tsx
index 49cb5235c5..6812a8fb98 100644
--- a/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/ChartTypeSelectionSection.tsx
+++ b/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/ChartTypeSelectionSection.tsx
@@ -12,7 +12,6 @@ const graphTypeOptions = [
GraphType.LINE,
GraphType.PIE,
GraphType.AGGREGATE,
- GraphType.GAUGE,
];
const StyledChartTypeSelectionContainer = styled.div`
diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-3/2-3-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-3/2-3-upgrade-version-command.module.ts
index d31a0b8e16..970e79870c 100644
--- a/packages/twenty-server/src/database/commands/upgrade-version-command/2-3/2-3-upgrade-version-command.module.ts
+++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-3/2-3-upgrade-version-command.module.ts
@@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module';
import { DropMessageDirectionFieldCommand } from 'src/database/commands/upgrade-version-command/2-3/2-3-workspace-command-1777400000000-drop-message-direction-field.command';
import { BackfillImageIdentifierFieldMetadataIdCommand } from 'src/database/commands/upgrade-version-command/2-3/2-3-workspace-command-1777920000000-backfill-image-identifier-field-metadata-id.command';
+import { DeleteGaugeWidgetsCommand } from 'src/database/commands/upgrade-version-command/2-3/2-3-workspace-command-1798000000000-delete-gauge-widgets.command';
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
@@ -17,6 +18,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
providers: [
DropMessageDirectionFieldCommand,
BackfillImageIdentifierFieldMetadataIdCommand,
+ DeleteGaugeWidgetsCommand,
],
})
export class V2_3_UpgradeVersionCommandModule {}
diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-3/2-3-workspace-command-1798000000000-delete-gauge-widgets.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-3/2-3-workspace-command-1798000000000-delete-gauge-widgets.command.ts
new file mode 100644
index 0000000000..56b4aebce2
--- /dev/null
+++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-3/2-3-workspace-command-1798000000000-delete-gauge-widgets.command.ts
@@ -0,0 +1,98 @@
+import { Command } from 'nest-commander';
+import { isDefined } from 'twenty-shared/utils';
+
+import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner';
+import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service';
+import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner';
+import { ApplicationService } from 'src/engine/core-modules/application/application.service';
+import { RegisteredWorkspaceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-workspace-command.decorator';
+import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
+import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
+import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
+
+@RegisteredWorkspaceCommand('2.3.0', 1798000000000)
+@Command({
+ name: 'upgrade:2-3:delete-gauge-widgets',
+ description:
+ 'Delete all GAUGE_CHART page layout widgets — gauge support has been removed',
+})
+export class DeleteGaugeWidgetsCommand extends ActiveOrSuspendedWorkspaceCommandRunner {
+ constructor(
+ protected readonly workspaceIteratorService: WorkspaceIteratorService,
+ private readonly applicationService: ApplicationService,
+ private readonly workspaceCacheService: WorkspaceCacheService,
+ private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
+ ) {
+ super(workspaceIteratorService);
+ }
+
+ override async runOnWorkspace({
+ workspaceId,
+ options,
+ }: RunOnWorkspaceArgs): Promise {
+ const isDryRun = options.dryRun ?? false;
+
+ const { flatPageLayoutWidgetMaps } =
+ await this.workspaceCacheService.getOrRecompute(workspaceId, [
+ 'flatPageLayoutWidgetMaps',
+ ]);
+
+ const gaugeWidgets = Object.values(
+ flatPageLayoutWidgetMaps.byUniversalIdentifier,
+ )
+ .filter(isDefined)
+ .filter(
+ (widget) =>
+ widget.universalConfiguration.configurationType ===
+ WidgetConfigurationType.GAUGE_CHART,
+ );
+
+ if (gaugeWidgets.length === 0) {
+ this.logger.log(`No gauge widgets in workspace ${workspaceId}`);
+
+ return;
+ }
+
+ if (isDryRun) {
+ this.logger.log(
+ `[DRY RUN] Would delete ${gaugeWidgets.length} gauge widget(s) in workspace ${workspaceId}`,
+ );
+
+ return;
+ }
+
+ const { twentyStandardFlatApplication } =
+ await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
+ { workspaceId },
+ );
+
+ const result =
+ await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
+ {
+ allFlatEntityOperationByMetadataName: {
+ pageLayoutWidget: {
+ flatEntityToCreate: [],
+ flatEntityToDelete: gaugeWidgets,
+ flatEntityToUpdate: [],
+ },
+ },
+ workspaceId,
+ applicationUniversalIdentifier:
+ twentyStandardFlatApplication.universalIdentifier,
+ },
+ );
+
+ if (result.status === 'fail') {
+ this.logger.error(
+ `Failed to delete gauge widgets in workspace ${workspaceId}:\n${JSON.stringify(result, null, 2)}`,
+ );
+ throw new Error(
+ `Failed to delete gauge widgets for workspace ${workspaceId}`,
+ );
+ }
+
+ this.logger.log(
+ `Deleted ${gaugeWidgets.length} gauge widget(s) for workspace ${workspaceId}`,
+ );
+ }
+}
diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/constants/page-layout-widget-seeds.constant.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/constants/page-layout-widget-seeds.constant.ts
index b493f8f50e..51e2370b39 100644
--- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/constants/page-layout-widget-seeds.constant.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/constants/page-layout-widget-seeds.constant.ts
@@ -11,7 +11,6 @@ export const PAGE_LAYOUT_WIDGET_SEEDS = {
CUSTOMER_COMPANIES_BY_SIZE: 'CUSTOMER_COMPANIES_BY_SIZE_WIDGET',
CUSTOMER_ANNUAL_RECURRING_REVENUE: 'CUSTOMER_ANNUAL_RECURRING_REVENUE_WIDGET',
CUSTOMER_REVENUE_DISTRIBUTION: 'CUSTOMER_REVENUE_DISTRIBUTION_WIDGET',
- CUSTOMER_AVERAGE_ARR: 'CUSTOMER_AVERAGE_ARR_WIDGET',
CUSTOMER_LINKEDIN_COUNT: 'CUSTOMER_LINKEDIN_COUNT_WIDGET',
CUSTOMER_LINKEDIN_DISTRIBUTION: 'CUSTOMER_LINKEDIN_DISTRIBUTION_WIDGET',
diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/get-page-layout-widget-data-seeds-v2.util.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/get-page-layout-widget-data-seeds-v2.util.ts
index a6da5c3d9c..79153954d2 100644
--- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/get-page-layout-widget-data-seeds-v2.util.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/get-page-layout-widget-data-seeds-v2.util.ts
@@ -168,40 +168,6 @@ export const getPageLayoutWidgetDataSeedsV2 = (
} satisfies SeederFlatPageLayoutWidget)
: null,
- // GAUGE chart: Average ARR (Customer Analytics)
- isDefined(companyArrFieldId)
- ? ({
- id: generateSeedId(
- workspaceId,
- PAGE_LAYOUT_WIDGET_SEEDS.CUSTOMER_AVERAGE_ARR,
- ),
- pageLayoutTabId: generateSeedId(
- workspaceId,
- PAGE_LAYOUT_TAB_SEEDS.CUSTOMER_ANALYTICS,
- ),
- title: 'Average ARR',
- type: WidgetType.GRAPH,
- gridPosition: { row: 0, column: 7, rowSpan: 6, columnSpan: 5 },
- position: {
- layoutMode: PageLayoutTabLayoutMode.GRID,
- row: 0,
- column: 7,
- rowSpan: 6,
- columnSpan: 5,
- },
- configuration: {
- configurationType: WidgetConfigurationType.GAUGE_CHART,
- aggregateFieldMetadataId: companyArrFieldId,
- aggregateOperation: AggregateOperations.AVG,
- displayDataLabel: true,
- timezone: 'UTC',
- firstDayOfTheWeek: CalendarStartDay.MONDAY,
- },
- objectMetadataId: companyObject?.id ?? null,
- overrides: null,
- } satisfies SeederFlatPageLayoutWidget)
- : null,
-
// PIE chart: Companies by LinkedIn (Customer Overview)
isDefined(companyIdFieldId) && isDefined(companyLinkedinLinkFieldId)
? ({