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: {