diff --git a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx index 564171a9f..f58f30750 100644 --- a/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx +++ b/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx @@ -17,6 +17,7 @@ import { Trans, useTranslation } from 'next-i18next'; import { FC, useState } from 'react'; import { useConfigContext } from '../../../../config/provider'; import { useConfigStore } from '../../../../config/store'; +import { mapObject } from '../../../../tools/client/objects'; import { useColorTheme } from '../../../../tools/color'; import Widgets from '../../../../widgets'; import type { IDraggableListInputValue, IWidgetOptionValue } from '../../../../widgets/widgets'; @@ -176,6 +177,7 @@ const WidgetOptionTypeSwitch: FC<{ label={t(`descriptor.settings.${key}.label`)} value={value as number} onChange={(v) => handleChange(key, v!)} + {...option.inputProps} /> ); case 'slider': @@ -193,55 +195,54 @@ const WidgetOptionTypeSwitch: FC<{ ); case 'draggable-list': - // eslint-disable-next-line no-case-declarations + /* eslint-disable no-case-declarations */ const typedVal = value as IDraggableListInputValue['defaultValue']; + const extractSubValue = (liName: string, settingName: string) => + typedVal.find((v) => v.key === liName)?.subValues?.[settingName]; + + const handleSubChange = (liName: string, settingName: string) => (_: any, newVal: any) => + handleChange( + key, + typedVal.map((oldVal) => + oldVal.key === liName + ? { + ...oldVal, + subValues: { + ...oldVal.subValues, + [settingName]: newVal, + }, + } + : oldVal + ) + ); + return ( {t(`descriptor.settings.${key}.label`)} handleChange(key, v)} - labels={Object.fromEntries( - Object.entries(option.items).map(([graphName]) => [ - graphName, - t(`descriptor.settings.${key}.${graphName}.label`), - ]) + labels={mapObject(option.items, (liName) => + t(`descriptor.settings.${key}.${liName}.label`) )} > - {Object.fromEntries( - Object.entries(option.items).map(([graphName, graph]) => [ - graphName, - Object.entries(graph).map(([subKey, setting], i) => ( - v.key === graphName)?.subValues?.[subKey]} - handleChange={(_, newVal) => - handleChange( - key, - typedVal.map((oldVal) => - oldVal.key === graphName - ? { - ...oldVal, - subValues: { - ...oldVal.subValues, - [subKey]: newVal, - }, - } - : oldVal - ) - ) - } - /> - )), - ]) + {mapObject(option.items, (liName, liSettings) => + Object.entries(liSettings).map(([settingName, setting], i) => ( + + )) )} ); + /* eslint-enable no-case-declarations */ default: return null; } diff --git a/src/tools/client/objects.ts b/src/tools/client/objects.ts new file mode 100644 index 000000000..90c5a56d7 --- /dev/null +++ b/src/tools/client/objects.ts @@ -0,0 +1,5 @@ +export const mapObject = ( + items: Record, + mapper: (prop: string, item: T) => R +): Record => + Object.fromEntries(Object.entries(items).map(([name, item]) => [name, mapper(name, item)])); diff --git a/src/widgets/dashDot/DashDotTile.tsx b/src/widgets/dashDot/DashDotTile.tsx index 6f8c2629c..34175f4b3 100644 --- a/src/widgets/dashDot/DashDotTile.tsx +++ b/src/widgets/dashDot/DashDotTile.tsx @@ -28,6 +28,11 @@ const definition = defineWidget({ graphHeight: { type: 'number', defaultValue: 115, + inputProps: { + step: 5, + stepHoldDelay: 500, + stepHoldInterval: 100, + }, }, graphsOrder: { type: 'draggable-list', diff --git a/src/widgets/widgets.ts b/src/widgets/widgets.ts index e10da4c75..d6559ed25 100644 --- a/src/widgets/widgets.ts +++ b/src/widgets/widgets.ts @@ -1,3 +1,11 @@ +import { + MultiSelectProps, + NumberInputProps, + SelectProps, + SliderProps, + SwitchProps, + TextInputProps, +} from '@mantine/core'; import { TablerIcon } from '@tabler/icons'; import React from 'react'; import { AreaType } from '../types/area'; @@ -41,31 +49,36 @@ export type IMultiSelectOptionValue = { type: 'multi-select'; defaultValue: string[]; data: DataType[]; + inputProps?: Partial; }; -// will show a multi-select with specified data +// will show a select with specified data export type ISelectOptionValue = { type: 'select'; defaultValue: string; data: DataType[]; + inputProps?: Partial; }; // will show a switch export type ISwitchOptionValue = { type: 'switch'; defaultValue: boolean; + inputProps?: Partial; }; // will show a text-input export type ITextInputOptionValue = { type: 'text'; defaultValue: string; + inputProps?: Partial; }; // will show a number-input export type INumberInputOptionValue = { type: 'number'; defaultValue: number; + inputProps?: Partial; }; // will show a slider-input @@ -75,8 +88,10 @@ export type ISliderInputOptionValue = { min: number; max: number; step: number; + inputProps?: Partial; }; +// will show a sortable list that can have sub settings export type IDraggableListInputValue = { type: 'draggable-list'; defaultValue: {