[Dashboards] Relation fields groupby (#16093)
This commit is contained in:
+3
-8
@@ -25,12 +25,9 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isFieldMetadataDateKind } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
FieldMetadataType,
|
||||
GraphType,
|
||||
type PageLayoutWidget,
|
||||
} from '~/generated/graphql';
|
||||
import { GraphType, type PageLayoutWidget } from '~/generated/graphql';
|
||||
|
||||
const StyledCommandMenuContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -136,9 +133,7 @@ export const ChartSettings = ({ widget }: { widget: PageLayoutWidget }) => {
|
||||
(field) => field.id === primaryAxisFieldMetadataId,
|
||||
);
|
||||
|
||||
const isPrimaryAxisDate =
|
||||
primaryAxisField?.type === FieldMetadataType.DATE ||
|
||||
primaryAxisField?.type === FieldMetadataType.DATE_TIME;
|
||||
const isPrimaryAxisDate = isFieldMetadataDateKind(primaryAxisField?.type);
|
||||
|
||||
const primaryAxisDateGranularity =
|
||||
configuration.__typename === 'BarChartConfiguration' ||
|
||||
|
||||
+72
-18
@@ -1,4 +1,5 @@
|
||||
import { ChartGroupByFieldSelectionCompositeFieldView } from '@/command-menu/pages/page-layout/components/dropdown-content/ChartGroupByFieldSelectionCompositeFieldView';
|
||||
import { ChartGroupByFieldSelectionRelationFieldView } from '@/command-menu/pages/page-layout/components/dropdown-content/ChartGroupByFieldSelectionRelationFieldView';
|
||||
import { usePageLayoutIdFromContextStoreTargetedRecord } from '@/command-menu/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord';
|
||||
import { useUpdateCurrentWidgetConfig } from '@/command-menu/pages/page-layout/hooks/useUpdateCurrentWidgetConfig';
|
||||
import { useWidgetInEditMode } from '@/command-menu/pages/page-layout/hooks/useWidgetInEditMode';
|
||||
@@ -23,6 +24,7 @@ import { useMemo, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { RelationType } from '~/generated/graphql';
|
||||
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
|
||||
|
||||
type ChartGroupByFieldSelectionDropdownContentBaseProps<
|
||||
@@ -43,6 +45,9 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
const [selectedCompositeField, setSelectedCompositeField] =
|
||||
useState<FieldMetadataItem | null>(null);
|
||||
|
||||
const [selectedRelationField, setSelectedRelationField] =
|
||||
useState<FieldMetadataItem | null>(null);
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
|
||||
@@ -77,8 +82,15 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
items: sourceObjectMetadataItem?.fields || [],
|
||||
searchQuery,
|
||||
getSearchableValues: (item) => [item.label, item.name],
|
||||
// TODO: remove the relation filter once group by is supported for relation fields
|
||||
}).filter((field) => !isFieldRelation(field) && !field.isSystem),
|
||||
}).filter((field) => {
|
||||
if (field.isSystem === true) {
|
||||
return false;
|
||||
}
|
||||
if (isFieldRelation(field)) {
|
||||
return field.relation?.type === RelationType.MANY_TO_ONE;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
[sourceObjectMetadataItem?.fields, searchQuery],
|
||||
);
|
||||
|
||||
@@ -94,20 +106,26 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
}
|
||||
|
||||
const handleSelectField = (fieldMetadataItem: FieldMetadataItem) => {
|
||||
if (isFieldRelation(fieldMetadataItem)) {
|
||||
setSelectedRelationField(fieldMetadataItem);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCompositeFieldType(fieldMetadataItem.type)) {
|
||||
setSelectedCompositeField(fieldMetadataItem);
|
||||
} else {
|
||||
updateCurrentWidgetConfig({
|
||||
configToUpdate: buildChartGroupByFieldConfigUpdate({
|
||||
configuration,
|
||||
fieldMetadataIdKey,
|
||||
subFieldNameKey,
|
||||
fieldId: fieldMetadataItem.id,
|
||||
subFieldName: null,
|
||||
}),
|
||||
});
|
||||
closeDropdown();
|
||||
return;
|
||||
}
|
||||
|
||||
updateCurrentWidgetConfig({
|
||||
configToUpdate: buildChartGroupByFieldConfigUpdate({
|
||||
configuration,
|
||||
fieldMetadataIdKey,
|
||||
subFieldNameKey,
|
||||
fieldId: fieldMetadataItem.id,
|
||||
subFieldName: null,
|
||||
}),
|
||||
});
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
const handleSelectNone = () => {
|
||||
@@ -123,11 +141,15 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
const handleBackFromComposite = () => {
|
||||
setSelectedCompositeField(null);
|
||||
};
|
||||
|
||||
const handleSelectSubField = (subFieldName: string) => {
|
||||
const handleBackFromRelation = () => {
|
||||
setSelectedRelationField(null);
|
||||
};
|
||||
|
||||
const handleSelectCompositeSubField = (subFieldName: string) => {
|
||||
if (!isDefined(selectedCompositeField)) {
|
||||
return;
|
||||
}
|
||||
@@ -144,13 +166,41 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
const handleSelectRelationSubField = (subFieldName: string) => {
|
||||
if (!isDefined(selectedRelationField)) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateCurrentWidgetConfig({
|
||||
configToUpdate: buildChartGroupByFieldConfigUpdate({
|
||||
configuration,
|
||||
fieldMetadataIdKey,
|
||||
subFieldNameKey,
|
||||
fieldId: selectedRelationField.id,
|
||||
subFieldName,
|
||||
}),
|
||||
});
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
if (isDefined(selectedRelationField)) {
|
||||
return (
|
||||
<ChartGroupByFieldSelectionRelationFieldView
|
||||
relationField={selectedRelationField}
|
||||
currentSubFieldName={currentSubFieldName}
|
||||
onBack={handleBackFromRelation}
|
||||
onSelectSubField={handleSelectRelationSubField}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (isDefined(selectedCompositeField)) {
|
||||
return (
|
||||
<ChartGroupByFieldSelectionCompositeFieldView
|
||||
compositeField={selectedCompositeField}
|
||||
currentSubFieldName={currentSubFieldName}
|
||||
onBack={handleBack}
|
||||
onSelectSubField={handleSelectSubField}
|
||||
onBack={handleBackFromComposite}
|
||||
onSelectSubField={handleSelectCompositeSubField}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -195,11 +245,15 @@ export const ChartGroupByFieldSelectionDropdownContentBase = <
|
||||
text={fieldMetadataItem.label}
|
||||
selected={
|
||||
!isCompositeFieldType(fieldMetadataItem.type) &&
|
||||
!isFieldRelation(fieldMetadataItem) &&
|
||||
currentGroupByFieldMetadataId === fieldMetadataItem.id
|
||||
}
|
||||
focused={selectedItemId === fieldMetadataItem.id}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
hasSubMenu={isCompositeFieldType(fieldMetadataItem.type)}
|
||||
hasSubMenu={
|
||||
isCompositeFieldType(fieldMetadataItem.type) ||
|
||||
isFieldRelation(fieldMetadataItem)
|
||||
}
|
||||
onClick={() => {
|
||||
handleSelectField(fieldMetadataItem);
|
||||
}}
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
import { ChartGroupByFieldSelectionCompositeFieldView } from '@/command-menu/pages/page-layout/components/dropdown-content/ChartGroupByFieldSelectionCompositeFieldView';
|
||||
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';
|
||||
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
|
||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
|
||||
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
|
||||
import { IconChevronLeft, useIcons } from 'twenty-ui/display';
|
||||
import { MenuItem, MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
|
||||
|
||||
type ChartGroupByFieldSelectionRelationFieldViewProps = {
|
||||
relationField: FieldMetadataItem;
|
||||
currentSubFieldName: string | undefined;
|
||||
onBack: () => void;
|
||||
onSelectSubField: (subFieldName: string) => void;
|
||||
};
|
||||
|
||||
export const ChartGroupByFieldSelectionRelationFieldView = ({
|
||||
relationField,
|
||||
currentSubFieldName,
|
||||
onBack,
|
||||
onSelectSubField,
|
||||
}: ChartGroupByFieldSelectionRelationFieldViewProps) => {
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
||||
const [selectedCompositeField, setSelectedCompositeField] =
|
||||
useState<FieldMetadataItem | null>(null);
|
||||
|
||||
const dropdownId = useAvailableComponentInstanceIdOrThrow(
|
||||
DropdownComponentInstanceContext,
|
||||
);
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
selectedItemIdComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const targetObjectNameSingular =
|
||||
relationField.relation?.targetObjectMetadata?.nameSingular;
|
||||
|
||||
const targetObjectMetadataItem = useMemo(
|
||||
() =>
|
||||
objectMetadataItems.find(
|
||||
(item) => item.nameSingular === targetObjectNameSingular,
|
||||
),
|
||||
[objectMetadataItems, targetObjectNameSingular],
|
||||
);
|
||||
|
||||
const availableFields = useMemo(() => {
|
||||
if (!isDefined(targetObjectMetadataItem)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return filterBySearchQuery({
|
||||
items: targetObjectMetadataItem.fields.filter(
|
||||
(field) =>
|
||||
!field.isSystem &&
|
||||
!isFieldRelation(field) &&
|
||||
// TODO: Backend doesn't fully support date fields for relation fields yet so we hide them for now. https://github.com/twentyhq/core-team-issues/issues/1935
|
||||
!isFieldMetadataDateKind(field.type),
|
||||
),
|
||||
searchQuery,
|
||||
getSearchableValues: (field) => [field.label, field.name],
|
||||
});
|
||||
}, [targetObjectMetadataItem, searchQuery]);
|
||||
|
||||
const handleSelectField = (fieldMetadataItem: FieldMetadataItem) => {
|
||||
if (isCompositeFieldType(fieldMetadataItem.type)) {
|
||||
setSelectedCompositeField(fieldMetadataItem);
|
||||
} else {
|
||||
onSelectSubField(fieldMetadataItem.name);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectCompositeSubField = (compositeSubFieldName: string) => {
|
||||
if (!isDefined(selectedCompositeField)) {
|
||||
return;
|
||||
}
|
||||
onSelectSubField(`${selectedCompositeField.name}.${compositeSubFieldName}`);
|
||||
};
|
||||
|
||||
const handleBackFromComposite = () => {
|
||||
setSelectedCompositeField(null);
|
||||
};
|
||||
|
||||
const [currentNestedFieldName, currentNestedSubFieldName] =
|
||||
currentSubFieldName?.split('.') ?? [];
|
||||
|
||||
if (isDefined(selectedCompositeField)) {
|
||||
return (
|
||||
<ChartGroupByFieldSelectionCompositeFieldView
|
||||
compositeField={selectedCompositeField}
|
||||
currentSubFieldName={currentNestedSubFieldName}
|
||||
onBack={handleBackFromComposite}
|
||||
onSelectSubField={handleSelectCompositeSubField}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownMenuHeader
|
||||
StartComponent={
|
||||
<DropdownMenuHeaderLeftComponent
|
||||
onClick={onBack}
|
||||
Icon={IconChevronLeft}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{relationField.label}
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuSearchInput
|
||||
autoFocus
|
||||
type="text"
|
||||
placeholder={t`Search fields`}
|
||||
onChange={(event) => setSearchQuery(event.target.value)}
|
||||
value={searchQuery}
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer>
|
||||
{availableFields.length === 0 ? (
|
||||
<MenuItem text={t`No fields available`} />
|
||||
) : (
|
||||
<SelectableList
|
||||
selectableListInstanceId={dropdownId}
|
||||
focusId={dropdownId}
|
||||
selectableItemIdArray={availableFields.map((field) => field.id)}
|
||||
>
|
||||
{availableFields.map((fieldMetadataItem) => (
|
||||
<SelectableListItem
|
||||
key={fieldMetadataItem.id}
|
||||
itemId={fieldMetadataItem.id}
|
||||
onEnter={() => {
|
||||
handleSelectField(fieldMetadataItem);
|
||||
}}
|
||||
>
|
||||
<MenuItemSelect
|
||||
text={fieldMetadataItem.label}
|
||||
selected={
|
||||
!isCompositeFieldType(fieldMetadataItem.type) &&
|
||||
currentNestedFieldName === fieldMetadataItem.name
|
||||
}
|
||||
focused={selectedItemId === fieldMetadataItem.id}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
hasSubMenu={isCompositeFieldType(fieldMetadataItem.type)}
|
||||
onClick={() => {
|
||||
handleSelectField(fieldMetadataItem);
|
||||
}}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
))}
|
||||
</SelectableList>
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+2
@@ -84,6 +84,7 @@ export const useChartSettingsValues = ({
|
||||
? getFieldLabelWithSubField({
|
||||
field: groupByFieldX,
|
||||
subFieldName: groupBySubFieldNameX,
|
||||
objectMetadataItems,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
@@ -181,6 +182,7 @@ export const useChartSettingsValues = ({
|
||||
? getFieldLabelWithSubField({
|
||||
field: pieChartGroupByField,
|
||||
subFieldName: finalGroupBySubFieldNameY,
|
||||
objectMetadataItems,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
|
||||
+1
@@ -32,6 +32,7 @@ export const useGraphGroupBySortOptionLabels = ({
|
||||
const fieldLabel = getFieldLabelWithSubField({
|
||||
field,
|
||||
subFieldName: groupBySubFieldName,
|
||||
objectMetadataItems,
|
||||
});
|
||||
|
||||
switch (graphOrderBy) {
|
||||
|
||||
+1
@@ -39,6 +39,7 @@ export const useGraphXSortOptionLabels = ({
|
||||
const fieldLabel = getFieldLabelWithSubField({
|
||||
field: groupByField,
|
||||
subFieldName: groupBySubFieldNameX,
|
||||
objectMetadataItems,
|
||||
});
|
||||
|
||||
const aggregateField = objectMetadataItem?.fields.find(
|
||||
|
||||
+26
-15
@@ -1,5 +1,9 @@
|
||||
import { getRelationFieldLabel } from '@/command-menu/pages/page-layout/utils/getRelationFieldLabel';
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { getCompositeSubFieldLabel } from '@/object-record/object-filter-dropdown/utils/getCompositeSubFieldLabel';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
|
||||
import { type CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { type CompositeFieldSubFieldName } from 'twenty-shared/types';
|
||||
@@ -8,24 +12,31 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
export const getFieldLabelWithSubField = ({
|
||||
field,
|
||||
subFieldName,
|
||||
objectMetadataItems,
|
||||
}: {
|
||||
field: FieldMetadataItem | undefined;
|
||||
subFieldName?: CompositeFieldSubFieldName;
|
||||
subFieldName?: CompositeFieldSubFieldName | string;
|
||||
objectMetadataItems?: ObjectMetadataItem[];
|
||||
}): string => {
|
||||
const subFieldNameLabel =
|
||||
isDefined(subFieldName) && isDefined(field)
|
||||
? getCompositeSubFieldLabel(
|
||||
field.type as CompositeFieldType,
|
||||
subFieldName,
|
||||
)
|
||||
: undefined;
|
||||
if (!isDefined(field?.label)) {
|
||||
return t`Field`;
|
||||
}
|
||||
|
||||
const fieldLabel =
|
||||
isDefined(subFieldNameLabel) && isDefined(field?.label)
|
||||
? `${field.label} ${subFieldNameLabel}`
|
||||
: isDefined(field?.label)
|
||||
? field.label
|
||||
: t`Field`;
|
||||
if (!isDefined(subFieldName)) {
|
||||
return field.label;
|
||||
}
|
||||
|
||||
return fieldLabel;
|
||||
if (isFieldRelation(field)) {
|
||||
return getRelationFieldLabel(field, subFieldName, objectMetadataItems);
|
||||
}
|
||||
|
||||
if (isCompositeFieldType(field.type)) {
|
||||
const subFieldLabel = getCompositeSubFieldLabel(
|
||||
field.type as CompositeFieldType,
|
||||
subFieldName as CompositeFieldSubFieldName,
|
||||
);
|
||||
return subFieldLabel ? `${field.label} ${subFieldLabel}` : field.label;
|
||||
}
|
||||
|
||||
return field.label;
|
||||
};
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { getCompositeSubFieldLabel } from '@/object-record/object-filter-dropdown/utils/getCompositeSubFieldLabel';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { type CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType';
|
||||
import { type CompositeFieldSubFieldName } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const getRelationFieldLabel = (
|
||||
field: FieldMetadataItem,
|
||||
subFieldName: string,
|
||||
objectMetadataItems: ObjectMetadataItem[] | undefined,
|
||||
): string => {
|
||||
if (!isDefined(objectMetadataItems)) {
|
||||
return field.label;
|
||||
}
|
||||
|
||||
const targetObjectNameSingular =
|
||||
field.relation?.targetObjectMetadata?.nameSingular;
|
||||
const targetObjectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.nameSingular === targetObjectNameSingular,
|
||||
);
|
||||
|
||||
if (!isDefined(targetObjectMetadataItem)) {
|
||||
return field.label;
|
||||
}
|
||||
|
||||
const [nestedFieldName, nestedSubFieldName] = subFieldName.split('.');
|
||||
const nestedField = targetObjectMetadataItem.fields.find(
|
||||
(f) => f.name === nestedFieldName,
|
||||
);
|
||||
|
||||
if (!isDefined(nestedField)) {
|
||||
return field.label;
|
||||
}
|
||||
|
||||
if (
|
||||
!isDefined(nestedSubFieldName) ||
|
||||
!isCompositeFieldType(nestedField.type)
|
||||
) {
|
||||
return `${field.label} ${nestedField.label}`;
|
||||
}
|
||||
|
||||
const compositeSubFieldLabel = getCompositeSubFieldLabel(
|
||||
nestedField.type as CompositeFieldType,
|
||||
nestedSubFieldName as CompositeFieldSubFieldName,
|
||||
);
|
||||
|
||||
return compositeSubFieldLabel
|
||||
? `${field.label} ${nestedField.label} ${compositeSubFieldLabel}`
|
||||
: `${field.label} ${nestedField.label}`;
|
||||
};
|
||||
+5
@@ -2,6 +2,7 @@ import { type ChartConfiguration } from '@/command-menu/pages/page-layout/types/
|
||||
import { CHART_CONFIGURATION_SETTING_IDS } from '@/command-menu/pages/page-layout/types/ChartConfigurationSettingIds';
|
||||
import { type ChartSettingsItem } from '@/command-menu/pages/page-layout/types/ChartSettingsGroup';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { isDefined, isFieldMetadataDateKind } from 'twenty-shared/utils';
|
||||
|
||||
@@ -21,6 +22,10 @@ const shouldHideDateGranularityBasedOnFieldType = (
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isFieldRelation(field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !isFieldMetadataDateKind(field.type);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user