Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { type BarChartLayout } from '@/page-layout/widgets/graph/graphWidgetBarChart/types/BarChartLayout';
import { type BarChartSeries } from '@/page-layout/widgets/graph/graphWidgetBarChart/types/BarChartSeries';
import { getBarChartQueryLimit } from '@/page-layout/widgets/graph/graphWidgetBarChart/utils/getBarChartQueryLimit';
Expand Down Expand Up @@ -40,6 +41,7 @@ export const useGraphBarChartWidgetData = ({
const { objectMetadataItem } = useObjectMetadataItemById({
objectId: objectMetadataItemId,
});
const { objectMetadataItems } = useObjectMetadataItems();

const limit = getBarChartQueryLimit(configuration);

Expand All @@ -59,10 +61,17 @@ export const useGraphBarChartWidgetData = ({
transformGroupByDataToBarChartData({
groupByData,
objectMetadataItem,
objectMetadataItems: objectMetadataItems ?? [],
configuration,
aggregateOperation,
}),
[groupByData, objectMetadataItem, configuration, aggregateOperation],
[
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation,
],
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ describe('transformGroupByDataToBarChartData', () => {
id: 'group-by-field',
name: 'company',
type: FieldMetadataType.RELATION,
relation: { targetObjectMetadata: { nameSingular: 'company' } },
};

const aggregateField = {
Expand All @@ -56,9 +57,15 @@ describe('transformGroupByDataToBarChartData', () => {
id: 'obj-1',
nameSingular: 'company',
namePlural: 'companies',
fields: [groupByField, aggregateField],
fields: [
groupByField,
aggregateField,
{ id: 'createdAt', name: 'createdAt', type: FieldMetadataType.DATE },
],
} as any;

const objectMetadataItems = [objectMetadataItem];

const configuration = {
__typename: 'BarChartConfiguration',
aggregateFieldMetadataId: aggregateField.id,
Expand All @@ -81,6 +88,7 @@ describe('transformGroupByDataToBarChartData', () => {
const result = transformGroupByDataToBarChartData({
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation: 'COUNT',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupBy
import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDimensionValue';
import { filterGroupByResults } from '@/page-layout/widgets/graph/utils/filterGroupByResults';
import { getFieldKey } from '@/page-layout/widgets/graph/utils/getFieldKey';
import { isNestedFieldDateType } from '@/page-layout/widgets/graph/utils/isNestedFieldDateType';
import { type BarDatum } from '@nivo/bar';
import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
import { GraphType } from '~/generated-metadata/graphql';
Expand All @@ -24,6 +25,7 @@ import {
type TransformGroupByDataToBarChartDataParams = {
groupByData: Record<string, GroupByRawResult[]> | null | undefined;
objectMetadataItem: ObjectMetadataItem;
objectMetadataItems: ObjectMetadataItem[];
configuration: BarChartConfiguration;
aggregateOperation: string;
};
Expand Down Expand Up @@ -59,6 +61,7 @@ const EMPTY_BAR_CHART_RESULT: TransformGroupByDataToBarChartDataResult = {
export const transformGroupByDataToBarChartData = ({
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation,
}: TransformGroupByDataToBarChartDataParams): TransformGroupByDataToBarChartDataResult => {
Expand Down Expand Up @@ -97,6 +100,8 @@ export const transformGroupByDataToBarChartData = ({

const primaryAxisSubFieldName =
configuration.primaryAxisGroupBySubFieldName ?? undefined;
const secondaryAxisSubFieldName =
configuration.secondaryAxisGroupBySubFieldName ?? undefined;

const indexByKey = getFieldKey({
field: groupByFieldX,
Expand Down Expand Up @@ -154,9 +159,44 @@ export const transformGroupByDataToBarChartData = ({
const showLegend = configuration.displayLegend ?? true;

const isDateField = isFieldMetadataDateKind(groupByFieldX.type);
const isNestedDateField =
!isDateField && isDefined(configuration.primaryAxisDateGranularity);
const shouldApplyDateGapFill = isDateField || isNestedDateField;
const isNestedDateField = isNestedFieldDateType(
groupByFieldX,
primaryAxisSubFieldName,
objectMetadataItems,
);

const primaryAxisDateGranularity =
isDateField || isNestedDateField
? (configuration.primaryAxisDateGranularity ??
GRAPH_DEFAULT_DATE_GRANULARITY)
: undefined;

const isSecondaryDateField = isDefined(groupByFieldY)
? isFieldMetadataDateKind(groupByFieldY.type)
: false;

const isSecondaryNestedDateField =
isDefined(groupByFieldY) &&
isNestedFieldDateType(
groupByFieldY,
secondaryAxisSubFieldName ?? undefined,
objectMetadataItems,
);

const secondaryAxisDateGranularity =
isSecondaryDateField || isSecondaryNestedDateField
? (configuration.secondaryAxisGroupByDateGranularity ??
GRAPH_DEFAULT_DATE_GRANULARITY)
: undefined;

const sanitizedConfiguration: BarChartConfiguration = {
...configuration,
primaryAxisDateGranularity: primaryAxisDateGranularity ?? undefined,
secondaryAxisGroupByDateGranularity:
secondaryAxisDateGranularity ?? undefined,
};

const shouldApplyDateGapFill = isDefined(primaryAxisDateGranularity);

const omitNullValues = configuration.omitNullValues ?? false;

Expand All @@ -166,8 +206,7 @@ export const transformGroupByDataToBarChartData = ({
data: filteredResults,
keys: [aggregateField.name],
dateGranularity:
configuration.primaryAxisDateGranularity ??
GRAPH_DEFAULT_DATE_GRANULARITY,
primaryAxisDateGranularity ?? GRAPH_DEFAULT_DATE_GRANULARITY,
hasSecondDimension: isDefined(groupByFieldY),
})
: { data: filteredResults, wasTruncated: false };
Expand All @@ -181,7 +220,7 @@ export const transformGroupByDataToBarChartData = ({
groupByFieldX,
groupByFieldY,
aggregateField,
configuration,
configuration: sanitizedConfiguration,
aggregateOperation,
objectMetadataItem,
primaryAxisSubFieldName,
Expand All @@ -190,7 +229,7 @@ export const transformGroupByDataToBarChartData = ({
rawResults: filteredResultsWithDateGaps,
groupByFieldX,
aggregateField,
configuration,
configuration: sanitizedConfiguration,
aggregateOperation,
objectMetadataItem,
primaryAxisSubFieldName,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { type LineChartSeries } from '@/page-layout/widgets/graph/graphWidgetLineChart/types/LineChartSeries';
import { getLineChartQueryLimit } from '@/page-layout/widgets/graph/graphWidgetLineChart/utils/getLineChartQueryLimit';
import { useGraphWidgetGroupByQuery } from '@/page-layout/widgets/graph/hooks/useGraphWidgetGroupByQuery';
Expand Down Expand Up @@ -34,6 +35,7 @@ export const useGraphLineChartWidgetData = ({
const { objectMetadataItem } = useObjectMetadataItemById({
objectId: objectMetadataItemId,
});
const { objectMetadataItems } = useObjectMetadataItems();

const limit = getLineChartQueryLimit(configuration);

Expand All @@ -53,10 +55,17 @@ export const useGraphLineChartWidgetData = ({
transformGroupByDataToLineChartData({
groupByData,
objectMetadataItem,
objectMetadataItems: objectMetadataItems ?? [],
configuration,
aggregateOperation,
}),
[groupByData, objectMetadataItem, configuration, aggregateOperation],
[
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation,
],
);

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { EXTRA_ITEM_TO_DETECT_TOO_MANY_GROUPS } from '@/page-layout/widgets/graph/constants/ExtraItemToDetectTooManyGroups.constant';
import { PIE_CHART_MAXIMUM_NUMBER_OF_SLICES } from '@/page-layout/widgets/graph/graphWidgetPieChart/constants/PieChartMaximumNumberOfSlices.constant';
Expand Down Expand Up @@ -33,6 +34,7 @@ export const useGraphPieChartWidgetData = ({
const { objectMetadataItem } = useObjectMetadataItemById({
objectId: objectMetadataItemId,
});
const { objectMetadataItems } = useObjectMetadataItems();

const {
data: groupByData,
Expand All @@ -51,10 +53,17 @@ export const useGraphPieChartWidgetData = ({
transformGroupByDataToPieChartData({
groupByData,
objectMetadataItem,
objectMetadataItems: objectMetadataItems ?? [],
configuration,
aggregateOperation,
}),
[groupByData, objectMetadataItem, configuration, aggregateOperation],
[
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation,
],
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ describe('transformGroupByDataToPieChartData', () => {
namePlural: 'companies',
fields: [groupByField, aggregateField],
} as any;
const objectMetadataItems = [objectMetadataItem];

const configuration = {
__typename: 'PieChartConfiguration',
Expand Down Expand Up @@ -72,6 +73,7 @@ describe('transformGroupByDataToPieChartData', () => {
const result = transformGroupByDataToPieChartData({
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation: 'COUNT',
});
Expand Down Expand Up @@ -106,6 +108,7 @@ describe('transformGroupByDataToPieChartData', () => {
namePlural: 'companies',
fields: [groupByField, aggregateField],
} as any;
const objectMetadataItems = [objectMetadataItem];

const configuration = {
__typename: 'PieChartConfiguration',
Expand Down Expand Up @@ -137,6 +140,7 @@ describe('transformGroupByDataToPieChartData', () => {
const result = transformGroupByDataToPieChartData({
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation: 'COUNT',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ import { type RawDimensionValue } from '@/page-layout/widgets/graph/types/RawDim
import { buildFormattedToRawLookup } from '@/page-layout/widgets/graph/utils/buildFormattedToRawLookup';
import { computeAggregateValueFromGroupByResult } from '@/page-layout/widgets/graph/utils/computeAggregateValueFromGroupByResult';
import { formatPrimaryDimensionValues } from '@/page-layout/widgets/graph/utils/formatPrimaryDimensionValues';
import { isDefined } from 'twenty-shared/utils';
import { isNestedFieldDateType } from '@/page-layout/widgets/graph/utils/isNestedFieldDateType';
import { type ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
import { type PieChartConfiguration } from '~/generated/graphql';

type TransformGroupByDataToPieChartDataParams = {
groupByData: Record<string, GroupByRawResult[]> | null | undefined;
objectMetadataItem: ObjectMetadataItem;
objectMetadataItems: ObjectMetadataItem[];
configuration: PieChartConfiguration;
aggregateOperation: string;
};
Expand All @@ -38,6 +41,7 @@ const EMPTY_PIE_CHART_RESULT: TransformGroupByDataToPieChartDataResult = {
export const transformGroupByDataToPieChartData = ({
groupByData,
objectMetadataItem,
objectMetadataItems,
configuration,
aggregateOperation,
}: TransformGroupByDataToPieChartDataParams): TransformGroupByDataToPieChartDataResult => {
Expand Down Expand Up @@ -66,6 +70,18 @@ export const transformGroupByDataToPieChartData = ({
return EMPTY_PIE_CHART_RESULT;
}

const isDateField = isFieldMetadataDateKind(groupByField.type);
const isNestedDateField = isNestedFieldDateType(
groupByField,
configuration.groupBySubFieldName ?? undefined,
objectMetadataItems,
);

const dateGranularity: ObjectRecordGroupByDateGranularity | undefined =
isDateField || isNestedDateField
? (configuration.dateGranularity ?? undefined)
: undefined;

// TODO: Add a limit to the query instead of slicing here (issue: twentyhq/core-team-issues#1600)
const limitedResults = rawResults.slice(
0,
Expand All @@ -75,7 +91,7 @@ export const transformGroupByDataToPieChartData = ({
const formattedValues = formatPrimaryDimensionValues({
groupByRawResults: limitedResults,
primaryAxisGroupByField: groupByField,
primaryAxisDateGranularity: configuration.dateGranularity ?? undefined,
primaryAxisDateGranularity: dateGranularity,
primaryAxisGroupBySubFieldName:
configuration.groupBySubFieldName ?? undefined,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ const normalizeMultiSelectValue = (value: unknown): unknown[] => {
export const formatDimensionValue = ({
value,
fieldMetadata,
dateGranularity = GRAPH_DEFAULT_DATE_GRANULARITY as ObjectRecordGroupByDateGranularity,
dateGranularity,
subFieldName,
}: FormatDimensionValueParams): string => {
if (!isDefined(value)) {
return t`Not Set`;
}

const effectiveDateGranularity = (dateGranularity ??
GRAPH_DEFAULT_DATE_GRANULARITY) as ObjectRecordGroupByDateGranularity;

switch (fieldMetadata.type) {
case FieldMetadataType.SELECT: {
const selectedOption = fieldMetadata.options?.find(
Expand Down Expand Up @@ -75,21 +78,31 @@ export const formatDimensionValue = ({

case FieldMetadataType.DATE:
case FieldMetadataType.DATE_TIME: {
const parsedDate = new Date(String(value));

if (isNaN(parsedDate.getTime())) {
return String(value);
}

if (
dateGranularity ===
effectiveDateGranularity ===
ObjectRecordGroupByDateGranularity.DAY_OF_THE_WEEK ||
dateGranularity ===
effectiveDateGranularity ===
ObjectRecordGroupByDateGranularity.MONTH_OF_THE_YEAR ||
dateGranularity ===
effectiveDateGranularity ===
ObjectRecordGroupByDateGranularity.QUARTER_OF_THE_YEAR
) {
return String(value);
}
return formatDateByGranularity(new Date(String(value)), dateGranularity);
return formatDateByGranularity(parsedDate, effectiveDateGranularity);
}

case FieldMetadataType.RELATION: {
if (isDefined(dateGranularity)) {
const parsedDate = new Date(String(value));
if (isNaN(parsedDate.getTime())) {
return String(value);
}
if (
dateGranularity ===
ObjectRecordGroupByDateGranularity.DAY_OF_THE_WEEK ||
Expand All @@ -100,10 +113,7 @@ export const formatDimensionValue = ({
) {
return String(value);
}
return formatDateByGranularity(
new Date(String(value)),
dateGranularity,
);
return formatDateByGranularity(parsedDate, dateGranularity);
}
return String(value);
}
Expand Down
Loading