Files
Homarr/src/components/Dashboard/Tiles/Widgets/WidgetsEditModal.tsx

129 lines
4.2 KiB
TypeScript
Raw Normal View History

2022-12-31 17:48:46 +01:00
import { Alert, Button, Group, MultiSelect, Stack, Switch, TextInput, Text } from '@mantine/core';
2022-12-10 22:14:31 +01:00
import { ContextModalProps } from '@mantine/modals';
2022-12-31 17:48:46 +01:00
import { IconAlertTriangle } from '@tabler/icons';
import { Trans, useTranslation } from 'next-i18next';
2022-12-10 22:14:31 +01:00
import { useState } from 'react';
2022-12-20 11:45:33 +09:00
import Widgets from '../../../../widgets';
2022-12-24 17:18:16 +09:00
import type { IWidgetOptionValue } from '../../../../widgets/widgets';
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
import { IWidget } from '../../../../widgets/widgets';
2022-12-10 22:14:31 +01:00
export type WidgetEditModalInnerProps = {
widgetId: string;
options: IWidget<string, any>['properties'];
2022-12-10 22:14:31 +01:00
};
type IntegrationOptionsValueType = IWidget<string, any>['properties'][string];
export const WidgetsEditModal = ({
2022-12-10 22:14:31 +01:00
context,
id,
innerProps,
}: ContextModalProps<WidgetEditModalInnerProps>) => {
const { t } = useTranslation([`modules/${innerProps.widgetId}`, 'common']);
2022-12-10 22:14:31 +01:00
const [moduleProperties, setModuleProperties] = useState(innerProps.options);
const items = Object.entries(moduleProperties ?? {}) as [string, IntegrationOptionsValueType][];
2022-12-10 22:14:31 +01:00
2022-12-24 17:18:16 +09:00
// Find the Key in the "Widgets" Object that matches the widgetId
const currentWidgetDefinition = Widgets[innerProps.widgetId as keyof typeof Widgets];
2022-12-10 22:14:31 +01:00
const { name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig);
if (!configName || !innerProps.options) return null;
const handleChange = (key: string, value: IntegrationOptionsValueType) => {
setModuleProperties((prev) => {
2022-12-17 00:28:46 +09:00
const copyOfPrev: any = { ...prev };
2022-12-10 22:14:31 +01:00
copyOfPrev[key] = value;
return copyOfPrev;
});
};
const getMutliselectData = (option: string) => {
const currentWidgetDefinition = Widgets[innerProps.widgetId as keyof typeof Widgets];
if (!Widgets) return [];
const options = currentWidgetDefinition.options as any;
return options[option]?.data ?? [];
};
2022-12-10 22:14:31 +01:00
const handleSave = () => {
updateConfig(
configName,
(prev) => {
2022-12-20 11:45:33 +09:00
const currentWidget = prev.widgets.find((x) => x.id === innerProps.widgetId);
currentWidget!.properties = moduleProperties;
return {
...prev,
widgets: [...prev.widgets.filter((x) => x.id !== innerProps.widgetId), currentWidget!],
};
},
true
);
2022-12-10 22:14:31 +01:00
context.closeModal(id);
};
return (
<Stack>
2022-12-31 17:48:46 +01:00
{items.map(([key, value], index) => {
2022-12-24 17:18:16 +09:00
const option = (currentWidgetDefinition as any).options[key] as IWidgetOptionValue;
2022-12-31 17:48:46 +01:00
if (!option) {
return (
<Alert icon={<IconAlertTriangle />} color="red">
<Text>
<Trans
i18nKey="modules/common:errors.unmappedOptions.text"
values={{ key }}
components={{ b: <b />, code: <code /> }}
/>
</Text>
</Alert>
);
}
2022-12-24 17:18:16 +09:00
switch (option.type) {
case 'switch':
return (
<Switch
2022-12-31 17:48:46 +01:00
key={`${option.type}-${index}`}
2022-12-24 17:18:16 +09:00
label={t(`descriptor.settings.${key}.label`)}
checked={value as boolean}
onChange={(ev) => handleChange(key, ev.currentTarget.checked)}
/>
);
case 'text':
return (
<TextInput
2022-12-31 17:48:46 +01:00
key={`${option.type}-${index}`}
2022-12-24 17:18:16 +09:00
label={t(`descriptor.settings.${key}.label`)}
value={value as string}
onChange={(ev) => handleChange(key, ev.currentTarget.value)}
/>
);
case 'multi-select':
return (
<MultiSelect
2022-12-31 17:48:46 +01:00
key={`${option.type}-${index}`}
2022-12-24 17:18:16 +09:00
data={getMutliselectData(key)}
label={t(`descriptor.settings.${key}.label`)}
value={value as string[]}
onChange={(v) => handleChange(key, v)}
/>
);
default:
return null;
}
})}
2022-12-10 22:14:31 +01:00
<Group position="right">
<Button onClick={() => context.closeModal(id)} variant="light">
2022-12-20 16:54:22 +09:00
{t('common:cancel')}
2022-12-10 22:14:31 +01:00
</Button>
2022-12-20 16:54:22 +09:00
<Button onClick={handleSave}>{t('common:save')}</Button>
2022-12-10 22:14:31 +01:00
</Group>
</Stack>
);
};