[DASHBOARDS] Add default order by and date granularity when choosing field (#16143)
## QA https://github.com/user-attachments/assets/b512eea0-26d1-4e1c-b8b9-f993a5c0d0fb https://github.com/user-attachments/assets/0222600b-8a9a-44dc-a992-2a234712c913
This commit is contained in:
+21
-42
@@ -3,6 +3,7 @@ import { usePageLayoutIdFromContextStoreTargetedRecord } from '@/command-menu/pa
|
||||
import { useUpdateCurrentWidgetConfig } from '@/command-menu/pages/page-layout/hooks/useUpdateCurrentWidgetConfig';
|
||||
import { useWidgetInEditMode } from '@/command-menu/pages/page-layout/hooks/useWidgetInEditMode';
|
||||
import { type ChartConfiguration } from '@/command-menu/pages/page-layout/types/ChartConfiguration';
|
||||
import { buildChartGroupByFieldConfigUpdate } from '@/command-menu/pages/page-layout/utils/buildChartGroupByFieldConfigUpdate';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
@@ -22,7 +23,6 @@ import { useMemo, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { BarChartGroupMode } from '~/generated/graphql';
|
||||
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
|
||||
|
||||
type ChartGroupByFieldSelectionDropdownContentBaseProps<
|
||||
@@ -93,48 +93,18 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
return null;
|
||||
}
|
||||
|
||||
const buildConfigUpdate = (
|
||||
fieldId: string | null,
|
||||
subFieldName: string | null,
|
||||
) => {
|
||||
const isSecondaryAxis =
|
||||
fieldMetadataIdKey === 'secondaryAxisGroupByFieldMetadataId';
|
||||
const baseConfig = {
|
||||
[fieldMetadataIdKey]: fieldId,
|
||||
[subFieldNameKey]: subFieldName,
|
||||
};
|
||||
|
||||
if (!isSecondaryAxis) {
|
||||
return baseConfig;
|
||||
}
|
||||
|
||||
if (configuration.__typename === 'BarChartConfiguration') {
|
||||
return {
|
||||
...baseConfig,
|
||||
groupMode: isDefined(fieldId)
|
||||
? (configuration.groupMode ?? BarChartGroupMode.STACKED)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (configuration.__typename === 'LineChartConfiguration') {
|
||||
return {
|
||||
...baseConfig,
|
||||
isStacked: isDefined(fieldId)
|
||||
? (configuration.isStacked ?? true)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
return baseConfig;
|
||||
};
|
||||
|
||||
const handleSelectField = (fieldMetadataItem: FieldMetadataItem) => {
|
||||
if (isCompositeFieldType(fieldMetadataItem.type)) {
|
||||
setSelectedCompositeField(fieldMetadataItem);
|
||||
} else {
|
||||
updateCurrentWidgetConfig({
|
||||
configToUpdate: buildConfigUpdate(fieldMetadataItem.id, null),
|
||||
configToUpdate: buildChartGroupByFieldConfigUpdate({
|
||||
configuration,
|
||||
fieldMetadataIdKey,
|
||||
subFieldNameKey,
|
||||
fieldId: fieldMetadataItem.id,
|
||||
subFieldName: null,
|
||||
}),
|
||||
});
|
||||
closeDropdown();
|
||||
}
|
||||
@@ -142,7 +112,13 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
|
||||
const handleSelectNone = () => {
|
||||
updateCurrentWidgetConfig({
|
||||
configToUpdate: buildConfigUpdate(null, null),
|
||||
configToUpdate: buildChartGroupByFieldConfigUpdate({
|
||||
configuration,
|
||||
fieldMetadataIdKey,
|
||||
subFieldNameKey,
|
||||
fieldId: null,
|
||||
subFieldName: null,
|
||||
}),
|
||||
});
|
||||
closeDropdown();
|
||||
};
|
||||
@@ -157,10 +133,13 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
}
|
||||
|
||||
updateCurrentWidgetConfig({
|
||||
configToUpdate: buildConfigUpdate(
|
||||
selectedCompositeField.id,
|
||||
configToUpdate: buildChartGroupByFieldConfigUpdate({
|
||||
configuration,
|
||||
fieldMetadataIdKey,
|
||||
subFieldNameKey,
|
||||
fieldId: selectedCompositeField.id,
|
||||
subFieldName,
|
||||
),
|
||||
}),
|
||||
});
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import { ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
|
||||
import {
|
||||
type BarChartConfiguration,
|
||||
BarChartGroupMode,
|
||||
GraphOrderBy,
|
||||
type PieChartConfiguration,
|
||||
} from '~/generated/graphql';
|
||||
import { buildChartGroupByFieldConfigUpdate } from '../buildChartGroupByFieldConfigUpdate';
|
||||
|
||||
describe('buildChartGroupByFieldConfigUpdate', () => {
|
||||
it('sets default orderBy and dateGranularity for primary axis', () => {
|
||||
const result = buildChartGroupByFieldConfigUpdate({
|
||||
configuration: {
|
||||
__typename: 'BarChartConfiguration',
|
||||
} as BarChartConfiguration,
|
||||
fieldMetadataIdKey: 'primaryAxisGroupByFieldMetadataId',
|
||||
subFieldNameKey: 'primaryAxisGroupBySubFieldName',
|
||||
fieldId: 'field',
|
||||
subFieldName: null,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
primaryAxisOrderBy: GraphOrderBy.FIELD_ASC,
|
||||
primaryAxisDateGranularity: ObjectRecordGroupByDateGranularity.DAY,
|
||||
});
|
||||
});
|
||||
|
||||
it('clears orderBy and dateGranularity when primary axis fieldId is null', () => {
|
||||
const result = buildChartGroupByFieldConfigUpdate({
|
||||
configuration: {
|
||||
__typename: 'BarChartConfiguration',
|
||||
} as BarChartConfiguration,
|
||||
fieldMetadataIdKey: 'primaryAxisGroupByFieldMetadataId',
|
||||
subFieldNameKey: 'primaryAxisGroupBySubFieldName',
|
||||
fieldId: null,
|
||||
subFieldName: null,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
primaryAxisOrderBy: null,
|
||||
primaryAxisDateGranularity: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('sets groupMode for bar chart secondary axis', () => {
|
||||
const result = buildChartGroupByFieldConfigUpdate({
|
||||
configuration: {
|
||||
__typename: 'BarChartConfiguration',
|
||||
} as BarChartConfiguration,
|
||||
fieldMetadataIdKey: 'secondaryAxisGroupByFieldMetadataId',
|
||||
subFieldNameKey: 'secondaryAxisGroupBySubFieldName',
|
||||
fieldId: 'field',
|
||||
subFieldName: null,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
groupMode: BarChartGroupMode.STACKED,
|
||||
});
|
||||
});
|
||||
|
||||
it('sets orderBy and dateGranularity for pie chart groupBy', () => {
|
||||
const result = buildChartGroupByFieldConfigUpdate({
|
||||
configuration: {
|
||||
__typename: 'PieChartConfiguration',
|
||||
} as PieChartConfiguration,
|
||||
fieldMetadataIdKey: 'groupByFieldMetadataId',
|
||||
subFieldNameKey: 'groupBySubFieldName',
|
||||
fieldId: 'field',
|
||||
subFieldName: null,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
orderBy: GraphOrderBy.FIELD_ASC,
|
||||
dateGranularity: ObjectRecordGroupByDateGranularity.DAY,
|
||||
});
|
||||
});
|
||||
});
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
import { type ChartConfiguration } from '@/command-menu/pages/page-layout/types/ChartConfiguration';
|
||||
import { ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { BarChartGroupMode, GraphOrderBy } from '~/generated/graphql';
|
||||
|
||||
type BuildChartGroupByFieldConfigUpdateArgs<T extends ChartConfiguration> = {
|
||||
configuration: T;
|
||||
fieldMetadataIdKey: keyof T;
|
||||
subFieldNameKey: keyof T;
|
||||
fieldId: string | null;
|
||||
subFieldName: string | null;
|
||||
};
|
||||
|
||||
export const buildChartGroupByFieldConfigUpdate = <
|
||||
T extends ChartConfiguration,
|
||||
>({
|
||||
configuration,
|
||||
fieldMetadataIdKey,
|
||||
subFieldNameKey,
|
||||
fieldId,
|
||||
subFieldName,
|
||||
}: BuildChartGroupByFieldConfigUpdateArgs<T>) => {
|
||||
const isPrimaryAxis =
|
||||
fieldMetadataIdKey === 'primaryAxisGroupByFieldMetadataId';
|
||||
const isSecondaryAxis =
|
||||
fieldMetadataIdKey === 'secondaryAxisGroupByFieldMetadataId';
|
||||
const isPieChartGroupBy = fieldMetadataIdKey === 'groupByFieldMetadataId';
|
||||
|
||||
const baseConfig = {
|
||||
[fieldMetadataIdKey]: fieldId,
|
||||
[subFieldNameKey]: subFieldName,
|
||||
};
|
||||
|
||||
const isBarChart = configuration.__typename === 'BarChartConfiguration';
|
||||
const isLineChart = configuration.__typename === 'LineChartConfiguration';
|
||||
const isPieChart = configuration.__typename === 'PieChartConfiguration';
|
||||
|
||||
if (isPrimaryAxis) {
|
||||
const existingOrderBy =
|
||||
isBarChart || isLineChart ? configuration.primaryAxisOrderBy : null;
|
||||
|
||||
const existingDateGranularity =
|
||||
isBarChart || isLineChart
|
||||
? configuration.primaryAxisDateGranularity
|
||||
: null;
|
||||
|
||||
return {
|
||||
...baseConfig,
|
||||
primaryAxisOrderBy: isDefined(fieldId)
|
||||
? (existingOrderBy ?? GraphOrderBy.FIELD_ASC)
|
||||
: null,
|
||||
primaryAxisDateGranularity: isDefined(fieldId)
|
||||
? (existingDateGranularity ?? ObjectRecordGroupByDateGranularity.DAY)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (isPieChartGroupBy) {
|
||||
const existingOrderBy = isPieChart ? configuration.orderBy : null;
|
||||
|
||||
const existingDateGranularity = isPieChart
|
||||
? configuration.dateGranularity
|
||||
: null;
|
||||
|
||||
return {
|
||||
...baseConfig,
|
||||
orderBy: isDefined(fieldId)
|
||||
? (existingOrderBy ?? GraphOrderBy.FIELD_ASC)
|
||||
: null,
|
||||
dateGranularity: isDefined(fieldId)
|
||||
? (existingDateGranularity ?? ObjectRecordGroupByDateGranularity.DAY)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (!isSecondaryAxis) {
|
||||
return baseConfig;
|
||||
}
|
||||
|
||||
if (isBarChart) {
|
||||
return {
|
||||
...baseConfig,
|
||||
secondaryAxisOrderBy: isDefined(fieldId)
|
||||
? (configuration.secondaryAxisOrderBy ?? GraphOrderBy.FIELD_ASC)
|
||||
: null,
|
||||
secondaryAxisGroupByDateGranularity: isDefined(fieldId)
|
||||
? (configuration.secondaryAxisGroupByDateGranularity ??
|
||||
ObjectRecordGroupByDateGranularity.DAY)
|
||||
: null,
|
||||
groupMode: isDefined(fieldId)
|
||||
? (configuration.groupMode ?? BarChartGroupMode.STACKED)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (isLineChart) {
|
||||
return {
|
||||
...baseConfig,
|
||||
secondaryAxisOrderBy: isDefined(fieldId)
|
||||
? (configuration.secondaryAxisOrderBy ?? GraphOrderBy.FIELD_ASC)
|
||||
: null,
|
||||
secondaryAxisGroupByDateGranularity: isDefined(fieldId)
|
||||
? (configuration.secondaryAxisGroupByDateGranularity ??
|
||||
ObjectRecordGroupByDateGranularity.DAY)
|
||||
: null,
|
||||
isStacked: isDefined(fieldId) ? (configuration.isStacked ?? true) : null,
|
||||
};
|
||||
}
|
||||
|
||||
return baseConfig;
|
||||
};
|
||||
Reference in New Issue
Block a user