diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/BarLineChartConvertibleFields.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/BarLineChartConvertibleFields.ts index 2d6d93e7fe..c27e7c26bf 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/BarLineChartConvertibleFields.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/BarLineChartConvertibleFields.ts @@ -4,6 +4,7 @@ import { } from '~/generated-metadata/graphql'; export type BarLineChartConvertibleFields = { + aggregateFieldMetadataId?: string; primaryAxisGroupByFieldMetadataId?: string; primaryAxisGroupBySubFieldName?: string | null; primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null; diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/PieChartConvertibleFields.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/PieChartConvertibleFields.ts index 9196403d00..77c079db2d 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/PieChartConvertibleFields.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/types/PieChartConvertibleFields.ts @@ -4,6 +4,7 @@ import { } from '~/generated-metadata/graphql'; export type PieChartConvertibleFields = { + aggregateFieldMetadataId?: string; groupByFieldMetadataId?: string; groupBySubFieldName?: string | null; dateGranularity?: ObjectRecordGroupByDateGranularity | null; diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertBarOrLineChartConfigToPieChart.test.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertBarOrLineChartConfigToPieChart.test.ts index d13967a9eb..bf5adb294d 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertBarOrLineChartConfigToPieChart.test.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertBarOrLineChartConfigToPieChart.test.ts @@ -19,6 +19,9 @@ describe('convertBarOrLineChartConfigToPieChart', () => { TEST_BAR_CHART_CONFIGURATION.primaryAxisGroupBySubFieldName, dateGranularity: TEST_BAR_CHART_CONFIGURATION.primaryAxisDateGranularity, orderBy: TEST_BAR_CHART_CONFIGURATION.primaryAxisOrderBy, + splitMultiValueFields: TEST_BAR_CHART_CONFIGURATION.splitMultiValueFields, + aggregateFieldMetadataId: + TEST_BAR_CHART_CONFIGURATION.aggregateFieldMetadataId, }); }); @@ -34,6 +37,10 @@ describe('convertBarOrLineChartConfigToPieChart', () => { TEST_LINE_CHART_CONFIGURATION.primaryAxisGroupBySubFieldName, dateGranularity: TEST_LINE_CHART_CONFIGURATION.primaryAxisDateGranularity, orderBy: TEST_LINE_CHART_CONFIGURATION.primaryAxisOrderBy, + splitMultiValueFields: + TEST_LINE_CHART_CONFIGURATION.splitMultiValueFields, + aggregateFieldMetadataId: + TEST_LINE_CHART_CONFIGURATION.aggregateFieldMetadataId, }); }); diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertPieChartConfigToBarOrLineChart.test.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertPieChartConfigToBarOrLineChart.test.ts index 66714158c3..8c9a6c3340 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertPieChartConfigToBarOrLineChart.test.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/__tests__/convertPieChartConfigToBarOrLineChart.test.ts @@ -12,12 +12,15 @@ describe('convertPieChartConfigToBarOrLineChart', () => { ); expect(result).toEqual({ + aggregateFieldMetadataId: + TEST_PIE_CHART_CONFIGURATION.aggregateFieldMetadataId, primaryAxisGroupByFieldMetadataId: TEST_PIE_CHART_CONFIGURATION.groupByFieldMetadataId, primaryAxisGroupBySubFieldName: TEST_PIE_CHART_CONFIGURATION.groupBySubFieldName, primaryAxisDateGranularity: TEST_PIE_CHART_CONFIGURATION.dateGranularity, primaryAxisOrderBy: TEST_PIE_CHART_CONFIGURATION.orderBy, + splitMultiValueFields: TEST_PIE_CHART_CONFIGURATION.splitMultiValueFields, }); }); @@ -33,10 +36,13 @@ describe('convertPieChartConfigToBarOrLineChart', () => { const result = convertPieChartConfigToBarOrLineChart(minimalPieConfig); expect(result).toEqual({ + aggregateFieldMetadataId: + TEST_PIE_CHART_CONFIGURATION.aggregateFieldMetadataId, primaryAxisGroupByFieldMetadataId: undefined, primaryAxisGroupBySubFieldName: null, primaryAxisDateGranularity: null, primaryAxisOrderBy: null, + splitMultiValueFields: TEST_PIE_CHART_CONFIGURATION.splitMultiValueFields, }); }); diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertBarOrLineChartConfigToPieChart.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertBarOrLineChartConfigToPieChart.ts index f78c3d7e89..0b7e76eb08 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertBarOrLineChartConfigToPieChart.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertBarOrLineChartConfigToPieChart.ts @@ -15,6 +15,7 @@ export const convertBarOrLineChartConfigToPieChart = ( } return { + aggregateFieldMetadataId: configuration.aggregateFieldMetadataId, groupByFieldMetadataId: configuration.primaryAxisGroupByFieldMetadataId, groupBySubFieldName: configuration.primaryAxisGroupBySubFieldName, dateGranularity: configuration.primaryAxisDateGranularity, diff --git a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertPieChartConfigToBarOrLineChart.ts b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertPieChartConfigToBarOrLineChart.ts index 6b006ca9ee..deac52765b 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertPieChartConfigToBarOrLineChart.ts +++ b/packages/twenty-front/src/modules/command-menu/pages/page-layout/utils/convertPieChartConfigToBarOrLineChart.ts @@ -10,6 +10,7 @@ export const convertPieChartConfigToBarOrLineChart = ( } return { + aggregateFieldMetadataId: configuration.aggregateFieldMetadataId, primaryAxisGroupByFieldMetadataId: configuration.groupByFieldMetadataId, primaryAxisGroupBySubFieldName: configuration.groupBySubFieldName, primaryAxisDateGranularity: configuration.dateGranularity, diff --git a/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetRenderer.tsx b/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetRenderer.tsx index 7cbe823e26..574aea62e1 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetRenderer.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/components/WidgetRenderer.tsx @@ -179,6 +179,11 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => { {hasAccess ? ( 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 f75dc84fbe..dd8d8334c2 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,14 +1,10 @@ -import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById'; -import { PageLayoutWidgetNoDataDisplay } from '@/page-layout/widgets/components/PageLayoutWidgetNoDataDisplay'; import { WidgetSkeletonLoader } from '@/page-layout/widgets/components/WidgetSkeletonLoader'; import { GraphWidgetAggregateChartRenderer } from '@/page-layout/widgets/graph/graphWidgetAggregateChart/components/GraphWidgetAggregateChartRenderer'; import { GraphWidgetBarChartRenderer } from '@/page-layout/widgets/graph/graphWidgetBarChart/components/GraphWidgetBarChartRenderer'; import { GraphWidgetLineChartRenderer } from '@/page-layout/widgets/graph/graphWidgetLineChart/components/GraphWidgetLineChartRenderer'; import { GraphWidgetPieChartRenderer } from '@/page-layout/widgets/graph/graphWidgetPieChart/components/GraphWidgetPieChartRenderer'; -import { areChartConfigurationFieldsValidForQuery } from '@/page-layout/widgets/graph/utils/areChartConfigurationFieldsValidForQuery'; import { useCurrentWidget } from '@/page-layout/widgets/hooks/useCurrentWidget'; import { lazy, Suspense } from 'react'; -import { isDefined } from 'twenty-shared/utils'; import { WidgetConfigurationType } from '~/generated-metadata/graphql'; const GraphWidgetGaugeChart = lazy(() => @@ -19,26 +15,9 @@ const GraphWidgetGaugeChart = lazy(() => })), ); -export type GraphWidgetProps = { - objectMetadataId: string; -}; - -export const GraphWidget = ({ objectMetadataId }: GraphWidgetProps) => { +export const GraphWidget = () => { const widget = useCurrentWidget(); - const { objectMetadataItem } = useObjectMetadataItemById({ - objectId: objectMetadataId, - }); - - const hasValidConfiguration = areChartConfigurationFieldsValidForQuery( - widget.configuration, - objectMetadataItem, - ); - - if (!isDefined(widget.configuration) || !hasValidConfiguration) { - return ; - } - const configurationType = widget.configuration?.configurationType; switch (configurationType) { diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidgetRenderer.tsx b/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidgetRenderer.tsx index 2028b0fd6e..5451d39a8e 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidgetRenderer.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/components/GraphWidgetRenderer.tsx @@ -1,6 +1,7 @@ import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget'; import { PageLayoutWidgetNoDataDisplay } from '@/page-layout/widgets/components/PageLayoutWidgetNoDataDisplay'; import { GraphWidget } from '@/page-layout/widgets/graph/components/GraphWidget'; +import { hasMinimalRequiredConfigForGraph } from '@/page-layout/widgets/graph/utils/hasMinimalRequiredConfigForGraph'; import { isDefined } from 'twenty-shared/utils'; type GraphWidgetRendererProps = { @@ -8,13 +9,13 @@ type GraphWidgetRendererProps = { }; export const GraphWidgetRenderer = ({ widget }: GraphWidgetRendererProps) => { - if (!isDefined(widget.configuration)) { + if ( + !isDefined(widget.configuration) || + !isDefined(widget.objectMetadataId) || + !hasMinimalRequiredConfigForGraph(widget.configuration) + ) { return ; } - if (!isDefined(widget.objectMetadataId)) { - return ; - } - - return ; + return ; }; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/__tests__/areChartConfigurationFieldsValidForQuery.test.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/__tests__/areChartConfigurationFieldsValidForQuery.test.ts deleted file mode 100644 index 3c84828063..0000000000 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/__tests__/areChartConfigurationFieldsValidForQuery.test.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { - AggregateOperations, - FieldMetadataType, - WidgetConfigurationType, - type AggregateChartConfiguration, -} from '~/generated-metadata/graphql'; - -import { areChartConfigurationFieldsValidForQuery } from '@/page-layout/widgets/graph/utils/areChartConfigurationFieldsValidForQuery'; - -describe('areChartConfigurationFieldsValidForQuery', () => { - const createMockObjectMetadataItem = ( - fields: Array<{ - id: string; - type: FieldMetadataType; - options?: Array<{ value: string; label: string }>; - }>, - ): ObjectMetadataItem => - ({ - id: 'object-1', - nameSingular: 'opportunity', - namePlural: 'opportunities', - fields: fields.map((f) => ({ - id: f.id, - name: f.id, - type: f.type, - label: f.id, - options: f.options, - })), - }) as ObjectMetadataItem; - - const createAggregateConfig = (ratioAggregateConfig?: { - fieldMetadataId: string; - optionValue: string; - }): AggregateChartConfiguration => ({ - __typename: 'AggregateChartConfiguration', - configurationType: WidgetConfigurationType.AGGREGATE_CHART, - aggregateFieldMetadataId: 'aggregate-field', - aggregateOperation: AggregateOperations.COUNT, - ratioAggregateConfig: ratioAggregateConfig ?? null, - }); - - describe('AggregateChartConfiguration with ratioAggregateConfig', () => { - it('should return true when ratioAggregateConfig is undefined', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig(undefined), - objectMetadataItem, - ); - - expect(result).toBe(true); - }); - - it('should return false when ratio field does not exist', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'non-existent-field', - optionValue: 'true', - }), - objectMetadataItem, - ); - - expect(result).toBe(false); - }); - - it('should return true for BOOLEAN field with "true" optionValue', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - { id: 'boolean-field', type: FieldMetadataType.BOOLEAN }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'boolean-field', - optionValue: 'true', - }), - objectMetadataItem, - ); - - expect(result).toBe(true); - }); - - it('should return true for BOOLEAN field with "false" optionValue', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - { id: 'boolean-field', type: FieldMetadataType.BOOLEAN }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'boolean-field', - optionValue: 'false', - }), - objectMetadataItem, - ); - - expect(result).toBe(true); - }); - - it('should return false for BOOLEAN field with invalid optionValue', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - { id: 'boolean-field', type: FieldMetadataType.BOOLEAN }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'boolean-field', - optionValue: 'invalid', - }), - objectMetadataItem, - ); - - expect(result).toBe(false); - }); - - it('should return true for SELECT field with valid option', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - { - id: 'select-field', - type: FieldMetadataType.SELECT, - options: [ - { value: 'WON', label: 'Won' }, - { value: 'LOST', label: 'Lost' }, - ], - }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'select-field', - optionValue: 'WON', - }), - objectMetadataItem, - ); - - expect(result).toBe(true); - }); - - it('should return false for SELECT field with invalid option', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - { - id: 'select-field', - type: FieldMetadataType.SELECT, - options: [ - { value: 'WON', label: 'Won' }, - { value: 'LOST', label: 'Lost' }, - ], - }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'select-field', - optionValue: 'INVALID_OPTION', - }), - objectMetadataItem, - ); - - expect(result).toBe(false); - }); - - it('should return true for MULTI_SELECT field with valid option', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - { - id: 'multiselect-field', - type: FieldMetadataType.MULTI_SELECT, - options: [ - { value: 'urgent', label: 'Urgent' }, - { value: 'important', label: 'Important' }, - ], - }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'multiselect-field', - optionValue: 'urgent', - }), - objectMetadataItem, - ); - - expect(result).toBe(true); - }); - - it('should return false for unsupported field type with ratioConfig', () => { - const objectMetadataItem = createMockObjectMetadataItem([ - { id: 'aggregate-field', type: FieldMetadataType.NUMBER }, - { id: 'text-field', type: FieldMetadataType.TEXT }, - ]); - - const result = areChartConfigurationFieldsValidForQuery( - createAggregateConfig({ - fieldMetadataId: 'text-field', - optionValue: 'some-value', - }), - objectMetadataItem, - ); - - expect(result).toBe(false); - }); - }); -}); diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/areChartConfigurationFieldsValidForQuery.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/areChartConfigurationFieldsValidForQuery.ts deleted file mode 100644 index 101191718b..0000000000 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/areChartConfigurationFieldsValidForQuery.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { isString } from '@sniptt/guards'; - -import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget'; -import { isDefined } from 'twenty-shared/utils'; -import { - FieldMetadataType, - type RatioAggregateConfig, -} from '~/generated-metadata/graphql'; - -const fieldExists = ( - fieldId: string | undefined | null, - objectMetadataItem: ObjectMetadataItem, -): boolean => { - if (!isDefined(fieldId)) { - return false; - } - - return objectMetadataItem.fields.some((field) => field.id === fieldId); -}; - -const isRatioConfigValid = ( - ratioConfig: RatioAggregateConfig | null | undefined, - objectMetadataItem: ObjectMetadataItem, -): boolean => { - if (!isDefined(ratioConfig)) { - return true; - } - - const field = objectMetadataItem.fields.find( - (f) => f.id === ratioConfig.fieldMetadataId, - ); - - if (!isDefined(field)) { - return false; - } - - if (field.type === FieldMetadataType.BOOLEAN) { - return ( - ratioConfig.optionValue === 'true' || ratioConfig.optionValue === 'false' - ); - } - - if ( - field.type === FieldMetadataType.SELECT || - field.type === FieldMetadataType.MULTI_SELECT - ) { - const options = field.options ?? []; - return options.some((option) => option.value === ratioConfig.optionValue); - } - - return false; -}; - -export const areChartConfigurationFieldsValidForQuery = ( - configuration: PageLayoutWidget['configuration'], - objectMetadataItem?: ObjectMetadataItem | null, -): boolean => { - if (!isDefined(configuration)) { - return false; - } - - if (!isDefined(objectMetadataItem) || !isDefined(objectMetadataItem.fields)) { - return false; - } - - switch (configuration.__typename) { - case 'BarChartConfiguration': - case 'LineChartConfiguration': - return ( - fieldExists( - configuration.aggregateFieldMetadataId, - objectMetadataItem, - ) && - fieldExists( - configuration.primaryAxisGroupByFieldMetadataId, - objectMetadataItem, - ) && - (!isDefined(configuration.secondaryAxisGroupByFieldMetadataId) || - fieldExists( - configuration.secondaryAxisGroupByFieldMetadataId, - objectMetadataItem, - )) - ); - - case 'PieChartConfiguration': - return ( - fieldExists( - configuration.aggregateFieldMetadataId, - objectMetadataItem, - ) && - fieldExists(configuration.groupByFieldMetadataId, objectMetadataItem) - ); - - case 'AggregateChartConfiguration': - return ( - fieldExists( - configuration.aggregateFieldMetadataId, - objectMetadataItem, - ) && - isRatioConfigValid( - configuration.ratioAggregateConfig, - objectMetadataItem, - ) - ); - - case 'GaugeChartConfiguration': - return fieldExists( - configuration.aggregateFieldMetadataId, - objectMetadataItem, - ); - - case 'IframeConfiguration': - return isString(configuration.url) && configuration.url.trim().length > 0; - - default: - return false; - } -}; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/hasMinimalRequiredConfigForGraph.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/hasMinimalRequiredConfigForGraph.ts new file mode 100644 index 0000000000..824718233a --- /dev/null +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/utils/hasMinimalRequiredConfigForGraph.ts @@ -0,0 +1,35 @@ +import { isWidgetConfigurationOfType } from '@/command-menu/pages/page-layout/utils/isWidgetConfigurationOfType'; +import { type FieldConfiguration } from '@/page-layout/types/FieldConfiguration'; +import { type FieldsConfiguration } from '@/page-layout/types/FieldsConfiguration'; +import { isDefined } from 'twenty-shared/utils'; +import { type WidgetConfiguration } from '~/generated-metadata/graphql'; + +export const hasMinimalRequiredConfigForGraph = ( + configuration: WidgetConfiguration | FieldsConfiguration | FieldConfiguration, +): boolean => { + if ( + isWidgetConfigurationOfType(configuration, 'BarChartConfiguration') || + isWidgetConfigurationOfType(configuration, 'LineChartConfiguration') + ) { + return ( + isDefined(configuration.aggregateFieldMetadataId) && + isDefined(configuration.primaryAxisGroupByFieldMetadataId) + ); + } + + if (isWidgetConfigurationOfType(configuration, 'PieChartConfiguration')) { + return ( + isDefined(configuration.aggregateFieldMetadataId) && + isDefined(configuration.groupByFieldMetadataId) + ); + } + + if ( + isWidgetConfigurationOfType(configuration, 'AggregateChartConfiguration') || + isWidgetConfigurationOfType(configuration, 'GaugeChartConfiguration') + ) { + return isDefined(configuration.aggregateFieldMetadataId); + } + + return false; +}; diff --git a/packages/twenty-front/src/testing/mock-data/widget-configurations.ts b/packages/twenty-front/src/testing/mock-data/widget-configurations.ts index 68fd09e627..e7b56732f0 100644 --- a/packages/twenty-front/src/testing/mock-data/widget-configurations.ts +++ b/packages/twenty-front/src/testing/mock-data/widget-configurations.ts @@ -32,6 +32,7 @@ export const TEST_BAR_CHART_CONFIGURATION: TypedBarChartConfiguration = { primaryAxisOrderBy: GraphOrderBy.FIELD_ASC, displayDataLabel: true, axisNameDisplay: AxisNameDisplay.NONE, + splitMultiValueFields: false, }; export const TEST_BAR_CHART_CONFIGURATION_HORIZONTAL: TypedBarChartConfiguration = @@ -50,6 +51,7 @@ export const TEST_LINE_CHART_CONFIGURATION: TypedLineChartConfiguration = { primaryAxisDateGranularity: ObjectRecordGroupByDateGranularity.DAY, displayDataLabel: true, axisNameDisplay: AxisNameDisplay.NONE, + splitMultiValueFields: false, }; export const TEST_PIE_CHART_CONFIGURATION: TypedPieChartConfiguration = { @@ -62,6 +64,7 @@ export const TEST_PIE_CHART_CONFIGURATION: TypedPieChartConfiguration = { dateGranularity: ObjectRecordGroupByDateGranularity.MONTH, orderBy: GraphOrderBy.VALUE_DESC, displayDataLabel: true, + splitMultiValueFields: false, }; export const TEST_AGGREGATE_CHART_CONFIGURATION: TypedAggregateChartConfiguration = diff --git a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts index e23a20634c..fa583964f9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-update.service.ts @@ -459,10 +459,7 @@ export class PageLayoutUpdateService { pageLayoutTabId: widgetInput.pageLayoutTabId, objectMetadataId: widgetInput.objectMetadataId, }, - flatEntityMaps: { - flatPageLayoutTabMaps, - flatObjectMetadataMaps, - }, + flatEntityMaps: { flatPageLayoutTabMaps, flatObjectMetadataMaps }, }); return { @@ -505,12 +502,26 @@ export class PageLayoutUpdateService { const updatedConfiguration = widgetInput.configuration ?? null; + const { + pageLayoutTabUniversalIdentifier, + objectMetadataUniversalIdentifier, + } = resolveEntityRelationUniversalIdentifiers({ + metadataName: 'pageLayoutWidget', + foreignKeyValues: { + pageLayoutTabId: widgetInput.pageLayoutTabId, + objectMetadataId: widgetInput.objectMetadataId, + }, + flatEntityMaps: { flatPageLayoutTabMaps, flatObjectMetadataMaps }, + }); + return { ...existingWidget, pageLayoutTabId: widgetInput.pageLayoutTabId, + pageLayoutTabUniversalIdentifier, title: widgetInput.title, type: widgetInput.type, objectMetadataId: widgetInput.objectMetadataId ?? null, + objectMetadataUniversalIdentifier, gridPosition: widgetInput.gridPosition, position: widgetInput.position ?? null, configuration: updatedConfiguration, @@ -536,12 +547,26 @@ export class PageLayoutUpdateService { const restoredConfiguration = widgetInput.configuration ?? null; + const { + pageLayoutTabUniversalIdentifier, + objectMetadataUniversalIdentifier, + } = resolveEntityRelationUniversalIdentifiers({ + metadataName: 'pageLayoutWidget', + foreignKeyValues: { + pageLayoutTabId: widgetInput.pageLayoutTabId, + objectMetadataId: widgetInput.objectMetadataId, + }, + flatEntityMaps: { flatPageLayoutTabMaps, flatObjectMetadataMaps }, + }); + return { ...existingWidget, pageLayoutTabId: widgetInput.pageLayoutTabId, + pageLayoutTabUniversalIdentifier, title: widgetInput.title, type: widgetInput.type, objectMetadataId: widgetInput.objectMetadataId ?? null, + objectMetadataUniversalIdentifier, gridPosition: widgetInput.gridPosition, position: widgetInput.position ?? null, configuration: restoredConfiguration,