Files
twenty/packages/twenty-front/src/modules/command-menu/pages/page-layout/components/ChartSettings.tsx
T
2025-10-14 15:06:50 +02:00

188 lines
7.2 KiB
TypeScript

import { CommandGroup } from '@/command-menu/components/CommandGroup';
import { CommandMenuItemDropdown } from '@/command-menu/components/CommandMenuItemDropdown';
import { CommandMenuItemToggle } from '@/command-menu/components/CommandMenuItemToggle';
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
import { COMMAND_MENU_LIST_SELECTABLE_LIST_ID } from '@/command-menu/constants/CommandMenuListSelectableListId';
import { useUpdateCommandMenuPageInfo } from '@/command-menu/hooks/useUpdateCommandMenuPageInfo';
import { ChartTypeSelectionSection } from '@/command-menu/pages/page-layout/components/ChartTypeSelectionSection';
import { GRAPH_TYPE_INFORMATION } from '@/command-menu/pages/page-layout/constants/GraphTypeInformation';
import { GRAPH_TYPE_TO_CONFIG_TYPENAME } from '@/command-menu/pages/page-layout/constants/GraphTypeToConfigTypename';
import { useChartSettingsValues } from '@/command-menu/pages/page-layout/hooks/useChartSettingsValues';
import { usePageLayoutIdFromContextStoreTargetedRecord } from '@/command-menu/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord';
import { useUpdateCurrentWidgetConfig } from '@/command-menu/pages/page-layout/hooks/useUpdateCurrentWidgetConfig';
import { type ChartConfiguration } from '@/command-menu/pages/page-layout/types/ChartConfiguration';
import {
CHART_CONFIGURATION_SETTING_IDS,
CHART_CONFIGURATION_SETTING_TO_CONFIG_KEY_MAP,
} from '@/command-menu/pages/page-layout/types/ChartConfigurationSettingIds';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { t } from '@lingui/core/macro';
import { isNonEmptyString } from '@sniptt/guards';
import {
BarChartGroupMode,
type GraphType,
type PageLayoutWidget,
} from '~/generated/graphql';
export const ChartSettings = ({ widget }: { widget: PageLayoutWidget }) => {
const { updateCommandMenuPageInfo } = useUpdateCommandMenuPageInfo();
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
const { updateCurrentWidgetConfig } =
useUpdateCurrentWidgetConfig(pageLayoutId);
const { openDropdown } = useOpenDropdown();
if (widget.configuration?.__typename === 'IframeConfiguration') {
throw new Error(t`IframeConfiguration is not supported`);
}
const configuration = widget.configuration as ChartConfiguration;
const { getChartSettingsValues } = useChartSettingsValues({
objectMetadataId: widget.objectMetadataId,
configuration,
});
const currentGraphType = configuration?.graphType;
const handleGraphTypeChange = (graphType: GraphType) => {
updateCurrentWidgetConfig({
configToUpdate: {
__typename: GRAPH_TYPE_TO_CONFIG_TYPENAME[graphType],
graphType,
},
});
updateCommandMenuPageInfo({
pageIcon: GRAPH_TYPE_INFORMATION[graphType].icon,
});
};
const chartSettings = GRAPH_TYPE_INFORMATION[currentGraphType].settings;
const { setSelectedItemId } = useSelectableList(
COMMAND_MENU_LIST_SELECTABLE_LIST_ID,
);
const isGroupByEnabled = getChartSettingsValues(
CHART_CONFIGURATION_SETTING_IDS.GROUP_BY,
);
return (
<CommandMenuList
commandGroups={[]}
selectableItemIds={[
...chartSettings.flatMap((group) => group.items.map((item) => item.id)),
]}
>
<ChartTypeSelectionSection
currentGraphType={currentGraphType}
setCurrentGraphType={handleGraphTypeChange}
/>
{chartSettings.map((group) => (
<CommandGroup key={group.heading} heading={group.heading}>
{group.items.map((item) => {
const isDisabled =
(!isNonEmptyString(widget.objectMetadataId) &&
(item?.dependsOn?.includes(
CHART_CONFIGURATION_SETTING_IDS.SOURCE,
) ??
false)) ||
(!isGroupByEnabled &&
item?.dependsOn?.includes(
CHART_CONFIGURATION_SETTING_IDS.GROUP_BY,
));
const handleToggleChange = () => {
const configKey =
item.id === CHART_CONFIGURATION_SETTING_IDS.DATA_LABELS
? CHART_CONFIGURATION_SETTING_TO_CONFIG_KEY_MAP[
CHART_CONFIGURATION_SETTING_IDS.DATA_LABELS
]
: item.id === CHART_CONFIGURATION_SETTING_IDS.STACKED_BARS
? CHART_CONFIGURATION_SETTING_TO_CONFIG_KEY_MAP[
CHART_CONFIGURATION_SETTING_IDS.STACKED_BARS
]
: item.id;
setSelectedItemId(item.id);
if (item.id === CHART_CONFIGURATION_SETTING_IDS.STACKED_BARS) {
const isCurrentlyStacked = getChartSettingsValues(item.id);
const newGroupMode = isCurrentlyStacked
? BarChartGroupMode.GROUPED
: BarChartGroupMode.STACKED;
updateCurrentWidgetConfig({
configToUpdate: {
groupMode: newGroupMode,
},
});
} else {
const newValue = !getChartSettingsValues(item.id);
updateCurrentWidgetConfig({
configToUpdate: {
[configKey]: newValue,
},
});
}
};
const handleDropdownOpen = () => {
openDropdown({
dropdownComponentInstanceIdFromProps: item.id,
});
};
return item.isBoolean ? (
<SelectableListItem
key={item.id}
itemId={item.id}
onEnter={isDisabled ? undefined : handleToggleChange}
>
<CommandMenuItemToggle
LeftIcon={item.Icon}
text={t(item.label)}
id={item.id}
toggled={getChartSettingsValues(item.id) as boolean}
onToggleChange={handleToggleChange}
/>
</SelectableListItem>
) : (
<SelectableListItem
key={item.id}
itemId={item.id}
onEnter={isDisabled ? undefined : handleDropdownOpen}
>
<CommandMenuItemDropdown
Icon={item.Icon}
label={t(item.label)}
id={item.id}
dropdownId={item.id}
dropdownComponents={
<DropdownContent>
{item.DropdownContent && <item.DropdownContent />}
</DropdownContent>
}
dropdownPlacement="bottom-end"
description={getChartSettingsValues(item.id) as string}
contextualTextPosition={'right'}
hasSubMenu
disabled={isDisabled}
/>
</SelectableListItem>
);
})}
</CommandGroup>
))}
</CommandMenuList>
);
};