Skip to content

Commit 0158c6f

Browse files
authored
1 parent eecc7aa commit 0158c6f

File tree

9 files changed

+170
-25
lines changed

9 files changed

+170
-25
lines changed

packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/hooks/useGraphBarChartWidgetData.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
2+
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
23
import { type BarChartLayout } from '@/page-layout/widgets/graph/graphWidgetBarChart/types/BarChartLayout';
34
import { type BarChartSeries } from '@/page-layout/widgets/graph/graphWidgetBarChart/types/BarChartSeries';
45
import { getBarChartQueryLimit } from '@/page-layout/widgets/graph/graphWidgetBarChart/utils/getBarChartQueryLimit';
@@ -40,6 +41,7 @@ export const useGraphBarChartWidgetData = ({
4041
const { objectMetadataItem } = useObjectMetadataItemById({
4142
objectId: objectMetadataItemId,
4243
});
44+
const { objectMetadataItems } = useObjectMetadataItems();
4345

4446
const limit = getBarChartQueryLimit(configuration);
4547

@@ -59,10 +61,17 @@ export const useGraphBarChartWidgetData = ({
5961
transformGroupByDataToBarChartData({
6062
groupByData,
6163
objectMetadataItem,
64+
objectMetadataItems: objectMetadataItems ?? [],
6265
configuration,
6366
aggregateOperation,
6467
}),
65-
[groupByData, objectMetadataItem, configuration, aggregateOperation],
68+
[
69+
groupByData,
70+
objectMetadataItem,
71+
objectMetadataItems,
72+
configuration,
73+
aggregateOperation,
74+
],
6675
);
6776

6877
return {

packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/utils/__tests__/transformGroupByDataToBarChartData.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('transformGroupByDataToBarChartData', () => {
4444
id: 'group-by-field',
4545
name: 'company',
4646
type: FieldMetadataType.RELATION,
47+
relation: { targetObjectMetadata: { nameSingular: 'company' } },
4748
};
4849

4950
const aggregateField = {
@@ -56,9 +57,15 @@ describe('transformGroupByDataToBarChartData', () => {
5657
id: 'obj-1',
5758
nameSingular: 'company',
5859
namePlural: 'companies',
59-
fields: [groupByField, aggregateField],
60+
fields: [
61+
groupByField,
62+
aggregateField,
63+
{ id: 'createdAt', name: 'createdAt', type: FieldMetadataType.DATE },
64+
],
6065
} as any;
6166

67+
const objectMetadataItems = [objectMetadataItem];
68+
6269
const configuration = {
6370
__typename: 'BarChartConfiguration',
6471
aggregateFieldMetadataId: aggregateField.id,
@@ -81,6 +88,7 @@ describe('transformGroupByDataToBarChartData', () => {
8188
const result = transformGroupByDataToBarChartData({
8289
groupByData,
8390
objectMetadataItem,
91+
objectMetadataItems,
8492
configuration,
8593
aggregateOperation: 'COUNT',
8694
});

packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/utils/transformGroupByDataToBarChartData.ts

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupBy
1313
import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDimensionValue';
1414
import { filterGroupByResults } from '@/page-layout/widgets/graph/utils/filterGroupByResults';
1515
import { getFieldKey } from '@/page-layout/widgets/graph/utils/getFieldKey';
16+
import { isNestedFieldDateType } from '@/page-layout/widgets/graph/utils/isNestedFieldDateType';
1617
import { type BarDatum } from '@nivo/bar';
1718
import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
1819
import { GraphType } from '~/generated-metadata/graphql';
@@ -24,6 +25,7 @@ import {
2425
type TransformGroupByDataToBarChartDataParams = {
2526
groupByData: Record<string, GroupByRawResult[]> | null | undefined;
2627
objectMetadataItem: ObjectMetadataItem;
28+
objectMetadataItems: ObjectMetadataItem[];
2729
configuration: BarChartConfiguration;
2830
aggregateOperation: string;
2931
};
@@ -59,6 +61,7 @@ const EMPTY_BAR_CHART_RESULT: TransformGroupByDataToBarChartDataResult = {
5961
export const transformGroupByDataToBarChartData = ({
6062
groupByData,
6163
objectMetadataItem,
64+
objectMetadataItems,
6265
configuration,
6366
aggregateOperation,
6467
}: TransformGroupByDataToBarChartDataParams): TransformGroupByDataToBarChartDataResult => {
@@ -97,6 +100,8 @@ export const transformGroupByDataToBarChartData = ({
97100

98101
const primaryAxisSubFieldName =
99102
configuration.primaryAxisGroupBySubFieldName ?? undefined;
103+
const secondaryAxisSubFieldName =
104+
configuration.secondaryAxisGroupBySubFieldName ?? undefined;
100105

101106
const indexByKey = getFieldKey({
102107
field: groupByFieldX,
@@ -154,9 +159,44 @@ export const transformGroupByDataToBarChartData = ({
154159
const showLegend = configuration.displayLegend ?? true;
155160

156161
const isDateField = isFieldMetadataDateKind(groupByFieldX.type);
157-
const isNestedDateField =
158-
!isDateField && isDefined(configuration.primaryAxisDateGranularity);
159-
const shouldApplyDateGapFill = isDateField || isNestedDateField;
162+
const isNestedDateField = isNestedFieldDateType(
163+
groupByFieldX,
164+
primaryAxisSubFieldName,
165+
objectMetadataItems,
166+
);
167+
168+
const primaryAxisDateGranularity =
169+
isDateField || isNestedDateField
170+
? (configuration.primaryAxisDateGranularity ??
171+
GRAPH_DEFAULT_DATE_GRANULARITY)
172+
: undefined;
173+
174+
const isSecondaryDateField = isDefined(groupByFieldY)
175+
? isFieldMetadataDateKind(groupByFieldY.type)
176+
: false;
177+
178+
const isSecondaryNestedDateField =
179+
isDefined(groupByFieldY) &&
180+
isNestedFieldDateType(
181+
groupByFieldY,
182+
secondaryAxisSubFieldName ?? undefined,
183+
objectMetadataItems,
184+
);
185+
186+
const secondaryAxisDateGranularity =
187+
isSecondaryDateField || isSecondaryNestedDateField
188+
? (configuration.secondaryAxisGroupByDateGranularity ??
189+
GRAPH_DEFAULT_DATE_GRANULARITY)
190+
: undefined;
191+
192+
const sanitizedConfiguration: BarChartConfiguration = {
193+
...configuration,
194+
primaryAxisDateGranularity: primaryAxisDateGranularity ?? undefined,
195+
secondaryAxisGroupByDateGranularity:
196+
secondaryAxisDateGranularity ?? undefined,
197+
};
198+
199+
const shouldApplyDateGapFill = isDefined(primaryAxisDateGranularity);
160200

161201
const omitNullValues = configuration.omitNullValues ?? false;
162202

@@ -166,8 +206,7 @@ export const transformGroupByDataToBarChartData = ({
166206
data: filteredResults,
167207
keys: [aggregateField.name],
168208
dateGranularity:
169-
configuration.primaryAxisDateGranularity ??
170-
GRAPH_DEFAULT_DATE_GRANULARITY,
209+
primaryAxisDateGranularity ?? GRAPH_DEFAULT_DATE_GRANULARITY,
171210
hasSecondDimension: isDefined(groupByFieldY),
172211
})
173212
: { data: filteredResults, wasTruncated: false };
@@ -181,7 +220,7 @@ export const transformGroupByDataToBarChartData = ({
181220
groupByFieldX,
182221
groupByFieldY,
183222
aggregateField,
184-
configuration,
223+
configuration: sanitizedConfiguration,
185224
aggregateOperation,
186225
objectMetadataItem,
187226
primaryAxisSubFieldName,
@@ -190,7 +229,7 @@ export const transformGroupByDataToBarChartData = ({
190229
rawResults: filteredResultsWithDateGaps,
191230
groupByFieldX,
192231
aggregateField,
193-
configuration,
232+
configuration: sanitizedConfiguration,
194233
aggregateOperation,
195234
objectMetadataItem,
196235
primaryAxisSubFieldName,

packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetLineChart/hooks/useGraphLineChartWidgetData.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
2+
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
23
import { type LineChartSeries } from '@/page-layout/widgets/graph/graphWidgetLineChart/types/LineChartSeries';
34
import { getLineChartQueryLimit } from '@/page-layout/widgets/graph/graphWidgetLineChart/utils/getLineChartQueryLimit';
45
import { useGraphWidgetGroupByQuery } from '@/page-layout/widgets/graph/hooks/useGraphWidgetGroupByQuery';
@@ -34,6 +35,7 @@ export const useGraphLineChartWidgetData = ({
3435
const { objectMetadataItem } = useObjectMetadataItemById({
3536
objectId: objectMetadataItemId,
3637
});
38+
const { objectMetadataItems } = useObjectMetadataItems();
3739

3840
const limit = getLineChartQueryLimit(configuration);
3941

@@ -53,10 +55,17 @@ export const useGraphLineChartWidgetData = ({
5355
transformGroupByDataToLineChartData({
5456
groupByData,
5557
objectMetadataItem,
58+
objectMetadataItems: objectMetadataItems ?? [],
5659
configuration,
5760
aggregateOperation,
5861
}),
59-
[groupByData, objectMetadataItem, configuration, aggregateOperation],
62+
[
63+
groupByData,
64+
objectMetadataItem,
65+
objectMetadataItems,
66+
configuration,
67+
aggregateOperation,
68+
],
6069
);
6170

6271
return {

packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/hooks/useGraphPieChartWidgetData.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
2+
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
23
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
34
import { EXTRA_ITEM_TO_DETECT_TOO_MANY_GROUPS } from '@/page-layout/widgets/graph/constants/ExtraItemToDetectTooManyGroups.constant';
45
import { PIE_CHART_MAXIMUM_NUMBER_OF_SLICES } from '@/page-layout/widgets/graph/graphWidgetPieChart/constants/PieChartMaximumNumberOfSlices.constant';
@@ -33,6 +34,7 @@ export const useGraphPieChartWidgetData = ({
3334
const { objectMetadataItem } = useObjectMetadataItemById({
3435
objectId: objectMetadataItemId,
3536
});
37+
const { objectMetadataItems } = useObjectMetadataItems();
3638

3739
const {
3840
data: groupByData,
@@ -51,10 +53,17 @@ export const useGraphPieChartWidgetData = ({
5153
transformGroupByDataToPieChartData({
5254
groupByData,
5355
objectMetadataItem,
56+
objectMetadataItems: objectMetadataItems ?? [],
5457
configuration,
5558
aggregateOperation,
5659
}),
57-
[groupByData, objectMetadataItem, configuration, aggregateOperation],
60+
[
61+
groupByData,
62+
objectMetadataItem,
63+
objectMetadataItems,
64+
configuration,
65+
aggregateOperation,
66+
],
5867
);
5968

6069
return {

packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/utils/__tests__/transformGroupByDataToPieChartData.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ describe('transformGroupByDataToPieChartData', () => {
4141
namePlural: 'companies',
4242
fields: [groupByField, aggregateField],
4343
} as any;
44+
const objectMetadataItems = [objectMetadataItem];
4445

4546
const configuration = {
4647
__typename: 'PieChartConfiguration',
@@ -72,6 +73,7 @@ describe('transformGroupByDataToPieChartData', () => {
7273
const result = transformGroupByDataToPieChartData({
7374
groupByData,
7475
objectMetadataItem,
76+
objectMetadataItems,
7577
configuration,
7678
aggregateOperation: 'COUNT',
7779
});
@@ -106,6 +108,7 @@ describe('transformGroupByDataToPieChartData', () => {
106108
namePlural: 'companies',
107109
fields: [groupByField, aggregateField],
108110
} as any;
111+
const objectMetadataItems = [objectMetadataItem];
109112

110113
const configuration = {
111114
__typename: 'PieChartConfiguration',
@@ -137,6 +140,7 @@ describe('transformGroupByDataToPieChartData', () => {
137140
const result = transformGroupByDataToPieChartData({
138141
groupByData,
139142
objectMetadataItem,
143+
objectMetadataItems,
140144
configuration,
141145
aggregateOperation: 'COUNT',
142146
});

packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetPieChart/utils/transformGroupByDataToPieChartData.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDim
1111
import { buildFormattedToRawLookup } from '@/page-layout/widgets/graph/utils/buildFormattedToRawLookup';
1212
import { computeAggregateValueFromGroupByResult } from '@/page-layout/widgets/graph/utils/computeAggregateValueFromGroupByResult';
1313
import { formatPrimaryDimensionValues } from '@/page-layout/widgets/graph/utils/formatPrimaryDimensionValues';
14-
import { isDefined } from 'twenty-shared/utils';
14+
import { isNestedFieldDateType } from '@/page-layout/widgets/graph/utils/isNestedFieldDateType';
15+
import { type ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
16+
import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
1517
import { type PieChartConfiguration } from '~/generated/graphql';
1618

1719
type TransformGroupByDataToPieChartDataParams = {
1820
groupByData: Record<string, GroupByRawResult[]> | null | undefined;
1921
objectMetadataItem: ObjectMetadataItem;
22+
objectMetadataItems: ObjectMetadataItem[];
2023
configuration: PieChartConfiguration;
2124
aggregateOperation: string;
2225
};
@@ -38,6 +41,7 @@ const EMPTY_PIE_CHART_RESULT: TransformGroupByDataToPieChartDataResult = {
3841
export const transformGroupByDataToPieChartData = ({
3942
groupByData,
4043
objectMetadataItem,
44+
objectMetadataItems,
4145
configuration,
4246
aggregateOperation,
4347
}: TransformGroupByDataToPieChartDataParams): TransformGroupByDataToPieChartDataResult => {
@@ -66,6 +70,18 @@ export const transformGroupByDataToPieChartData = ({
6670
return EMPTY_PIE_CHART_RESULT;
6771
}
6872

73+
const isDateField = isFieldMetadataDateKind(groupByField.type);
74+
const isNestedDateField = isNestedFieldDateType(
75+
groupByField,
76+
configuration.groupBySubFieldName ?? undefined,
77+
objectMetadataItems,
78+
);
79+
80+
const dateGranularity: ObjectRecordGroupByDateGranularity | undefined =
81+
isDateField || isNestedDateField
82+
? (configuration.dateGranularity ?? undefined)
83+
: undefined;
84+
6985
// TODO: Add a limit to the query instead of slicing here (issue: twentyhq/core-team-issues#1600)
7086
const limitedResults = rawResults.slice(
7187
0,
@@ -75,7 +91,7 @@ export const transformGroupByDataToPieChartData = ({
7591
const formattedValues = formatPrimaryDimensionValues({
7692
groupByRawResults: limitedResults,
7793
primaryAxisGroupByField: groupByField,
78-
primaryAxisDateGranularity: configuration.dateGranularity ?? undefined,
94+
primaryAxisDateGranularity: dateGranularity,
7995
primaryAxisGroupBySubFieldName:
8096
configuration.groupBySubFieldName ?? undefined,
8197
});

packages/twenty-front/src/modules/page-layout/widgets/graph/utils/formatDimensionValue.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,16 @@ const normalizeMultiSelectValue = (value: unknown): unknown[] => {
4141
export const formatDimensionValue = ({
4242
value,
4343
fieldMetadata,
44-
dateGranularity = GRAPH_DEFAULT_DATE_GRANULARITY as ObjectRecordGroupByDateGranularity,
44+
dateGranularity,
4545
subFieldName,
4646
}: FormatDimensionValueParams): string => {
4747
if (!isDefined(value)) {
4848
return t`Not Set`;
4949
}
5050

51+
const effectiveDateGranularity = (dateGranularity ??
52+
GRAPH_DEFAULT_DATE_GRANULARITY) as ObjectRecordGroupByDateGranularity;
53+
5154
switch (fieldMetadata.type) {
5255
case FieldMetadataType.SELECT: {
5356
const selectedOption = fieldMetadata.options?.find(
@@ -75,21 +78,31 @@ export const formatDimensionValue = ({
7578

7679
case FieldMetadataType.DATE:
7780
case FieldMetadataType.DATE_TIME: {
81+
const parsedDate = new Date(String(value));
82+
83+
if (isNaN(parsedDate.getTime())) {
84+
return String(value);
85+
}
86+
7887
if (
79-
dateGranularity ===
88+
effectiveDateGranularity ===
8089
ObjectRecordGroupByDateGranularity.DAY_OF_THE_WEEK ||
81-
dateGranularity ===
90+
effectiveDateGranularity ===
8291
ObjectRecordGroupByDateGranularity.MONTH_OF_THE_YEAR ||
83-
dateGranularity ===
92+
effectiveDateGranularity ===
8493
ObjectRecordGroupByDateGranularity.QUARTER_OF_THE_YEAR
8594
) {
8695
return String(value);
8796
}
88-
return formatDateByGranularity(new Date(String(value)), dateGranularity);
97+
return formatDateByGranularity(parsedDate, effectiveDateGranularity);
8998
}
9099

91100
case FieldMetadataType.RELATION: {
92101
if (isDefined(dateGranularity)) {
102+
const parsedDate = new Date(String(value));
103+
if (isNaN(parsedDate.getTime())) {
104+
return String(value);
105+
}
93106
if (
94107
dateGranularity ===
95108
ObjectRecordGroupByDateGranularity.DAY_OF_THE_WEEK ||
@@ -100,10 +113,7 @@ export const formatDimensionValue = ({
100113
) {
101114
return String(value);
102115
}
103-
return formatDateByGranularity(
104-
new Date(String(value)),
105-
dateGranularity,
106-
);
116+
return formatDateByGranularity(parsedDate, dateGranularity);
107117
}
108118
return String(value);
109119
}

0 commit comments

Comments
 (0)