Refactor settings code; Add props access to every settings item

This commit is contained in:
MauriceNino
2023-02-14 13:41:59 +01:00
parent 4c2c2fb564
commit d8931644d8
4 changed files with 62 additions and 36 deletions

View File

@@ -17,6 +17,7 @@ import { Trans, useTranslation } from 'next-i18next';
import { FC, useState } from 'react'; import { FC, useState } from 'react';
import { useConfigContext } from '../../../../config/provider'; import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store'; import { useConfigStore } from '../../../../config/store';
import { mapObject } from '../../../../tools/client/objects';
import { useColorTheme } from '../../../../tools/color'; import { useColorTheme } from '../../../../tools/color';
import Widgets from '../../../../widgets'; import Widgets from '../../../../widgets';
import type { IDraggableListInputValue, IWidgetOptionValue } from '../../../../widgets/widgets'; import type { IDraggableListInputValue, IWidgetOptionValue } from '../../../../widgets/widgets';
@@ -176,6 +177,7 @@ const WidgetOptionTypeSwitch: FC<{
label={t(`descriptor.settings.${key}.label`)} label={t(`descriptor.settings.${key}.label`)}
value={value as number} value={value as number}
onChange={(v) => handleChange(key, v!)} onChange={(v) => handleChange(key, v!)}
{...option.inputProps}
/> />
); );
case 'slider': case 'slider':
@@ -193,55 +195,54 @@ const WidgetOptionTypeSwitch: FC<{
</Stack> </Stack>
); );
case 'draggable-list': case 'draggable-list':
// eslint-disable-next-line no-case-declarations /* eslint-disable no-case-declarations */
const typedVal = value as IDraggableListInputValue['defaultValue']; 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 ( return (
<Stack spacing="xs"> <Stack spacing="xs">
<Text>{t(`descriptor.settings.${key}.label`)}</Text> <Text>{t(`descriptor.settings.${key}.label`)}</Text>
<DraggableList <DraggableList
value={typedVal} value={typedVal}
onChange={(v) => handleChange(key, v)} onChange={(v) => handleChange(key, v)}
labels={Object.fromEntries( labels={mapObject(option.items, (liName) =>
Object.entries(option.items).map(([graphName]) => [ t(`descriptor.settings.${key}.${liName}.label`)
graphName,
t(`descriptor.settings.${key}.${graphName}.label`),
])
)} )}
> >
{Object.fromEntries( {mapObject(option.items, (liName, liSettings) =>
Object.entries(option.items).map(([graphName, graph]) => [ Object.entries(liSettings).map(([settingName, setting], i) => (
graphName,
Object.entries(graph).map(([subKey, setting], i) => (
<WidgetOptionTypeSwitch <WidgetOptionTypeSwitch
key={`${graphName}.${subKey}.${i}`} key={`${liName}.${settingName}.${i}`}
option={setting as IWidgetOptionValue} option={setting as IWidgetOptionValue}
widgetId={widgetId} widgetId={widgetId}
propName={`${key}.${graphName}.${subKey}`} propName={`${key}.${liName}.${settingName}`}
value={typedVal.find((v) => v.key === graphName)?.subValues?.[subKey]} value={extractSubValue(liName, settingName)}
handleChange={(_, newVal) => handleChange={handleSubChange(liName, settingName)}
handleChange(
key,
typedVal.map((oldVal) =>
oldVal.key === graphName
? {
...oldVal,
subValues: {
...oldVal.subValues,
[subKey]: newVal,
},
}
: oldVal
)
)
}
/> />
)), ))
])
)} )}
</DraggableList> </DraggableList>
</Stack> </Stack>
); );
/* eslint-enable no-case-declarations */
default: default:
return null; return null;
} }

View File

@@ -0,0 +1,5 @@
export const mapObject = <T, R>(
items: Record<string, T>,
mapper: (prop: string, item: T) => R
): Record<string, R> =>
Object.fromEntries(Object.entries(items).map(([name, item]) => [name, mapper(name, item)]));

View File

@@ -28,6 +28,11 @@ const definition = defineWidget({
graphHeight: { graphHeight: {
type: 'number', type: 'number',
defaultValue: 115, defaultValue: 115,
inputProps: {
step: 5,
stepHoldDelay: 500,
stepHoldInterval: 100,
},
}, },
graphsOrder: { graphsOrder: {
type: 'draggable-list', type: 'draggable-list',

View File

@@ -1,3 +1,11 @@
import {
MultiSelectProps,
NumberInputProps,
SelectProps,
SliderProps,
SwitchProps,
TextInputProps,
} from '@mantine/core';
import { TablerIcon } from '@tabler/icons'; import { TablerIcon } from '@tabler/icons';
import React from 'react'; import React from 'react';
import { AreaType } from '../types/area'; import { AreaType } from '../types/area';
@@ -41,31 +49,36 @@ export type IMultiSelectOptionValue = {
type: 'multi-select'; type: 'multi-select';
defaultValue: string[]; defaultValue: string[];
data: DataType[]; data: DataType[];
inputProps?: Partial<MultiSelectProps>;
}; };
// will show a multi-select with specified data // will show a select with specified data
export type ISelectOptionValue = { export type ISelectOptionValue = {
type: 'select'; type: 'select';
defaultValue: string; defaultValue: string;
data: DataType[]; data: DataType[];
inputProps?: Partial<SelectProps>;
}; };
// will show a switch // will show a switch
export type ISwitchOptionValue = { export type ISwitchOptionValue = {
type: 'switch'; type: 'switch';
defaultValue: boolean; defaultValue: boolean;
inputProps?: Partial<SwitchProps>;
}; };
// will show a text-input // will show a text-input
export type ITextInputOptionValue = { export type ITextInputOptionValue = {
type: 'text'; type: 'text';
defaultValue: string; defaultValue: string;
inputProps?: Partial<TextInputProps>;
}; };
// will show a number-input // will show a number-input
export type INumberInputOptionValue = { export type INumberInputOptionValue = {
type: 'number'; type: 'number';
defaultValue: number; defaultValue: number;
inputProps?: Partial<NumberInputProps>;
}; };
// will show a slider-input // will show a slider-input
@@ -75,8 +88,10 @@ export type ISliderInputOptionValue = {
min: number; min: number;
max: number; max: number;
step: number; step: number;
inputProps?: Partial<SliderProps>;
}; };
// will show a sortable list that can have sub settings
export type IDraggableListInputValue = { export type IDraggableListInputValue = {
type: 'draggable-list'; type: 'draggable-list';
defaultValue: { defaultValue: {