2022-06-28 11:27:23 +02:00
|
|
|
import {
|
|
|
|
|
Button,
|
|
|
|
|
Card,
|
|
|
|
|
Group,
|
|
|
|
|
Menu,
|
|
|
|
|
MultiSelect,
|
|
|
|
|
Switch,
|
|
|
|
|
TextInput,
|
|
|
|
|
useMantineColorScheme,
|
|
|
|
|
} from '@mantine/core';
|
2022-05-10 20:33:11 +02:00
|
|
|
import { useConfig } from '../../tools/state';
|
2022-05-10 18:57:04 +02:00
|
|
|
import { IModule } from './modules';
|
|
|
|
|
|
2022-05-26 18:16:57 +02:00
|
|
|
function getItems(module: IModule) {
|
2022-05-18 22:11:37 +02:00
|
|
|
const { config, setConfig } = useConfig();
|
|
|
|
|
const items: JSX.Element[] = [];
|
|
|
|
|
if (module.options) {
|
|
|
|
|
const keys = Object.keys(module.options);
|
|
|
|
|
const values = Object.values(module.options);
|
|
|
|
|
// Get the value and the name of the option
|
|
|
|
|
const types = values.map((v) => typeof v.value);
|
|
|
|
|
// Loop over all the types with a for each loop
|
|
|
|
|
types.forEach((type, index) => {
|
|
|
|
|
const optionName = `${module.title}.${keys[index]}`;
|
2022-05-22 20:42:10 +02:00
|
|
|
const moduleInConfig = config.modules?.[module.title];
|
2022-06-28 11:27:23 +02:00
|
|
|
if (type === 'object') {
|
|
|
|
|
items.push(
|
|
|
|
|
<MultiSelect
|
|
|
|
|
label={module.options?.[keys[index]].name}
|
|
|
|
|
data={module.options?.[keys[index]].options ?? []}
|
2022-06-28 12:10:46 +02:00
|
|
|
defaultValue={
|
|
|
|
|
(moduleInConfig?.options?.[keys[index]]?.value as string[]) ??
|
|
|
|
|
(values[index].value as string[]) ??
|
|
|
|
|
[]
|
|
|
|
|
}
|
2022-06-28 11:27:23 +02:00
|
|
|
searchable
|
|
|
|
|
onChange={(value) => {
|
|
|
|
|
setConfig({
|
|
|
|
|
...config,
|
|
|
|
|
modules: {
|
|
|
|
|
...config.modules,
|
|
|
|
|
[module.title]: {
|
|
|
|
|
...moduleInConfig,
|
|
|
|
|
options: {
|
|
|
|
|
...moduleInConfig?.options,
|
|
|
|
|
[keys[index]]: {
|
|
|
|
|
...moduleInConfig?.options?.[keys[index]],
|
|
|
|
|
value,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-05-24 20:14:07 +02:00
|
|
|
if (type === 'string') {
|
|
|
|
|
items.push(
|
|
|
|
|
<form
|
|
|
|
|
onSubmit={(e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
setConfig({
|
|
|
|
|
...config,
|
|
|
|
|
modules: {
|
|
|
|
|
...config.modules,
|
|
|
|
|
[module.title]: {
|
|
|
|
|
...config.modules[module.title],
|
|
|
|
|
options: {
|
|
|
|
|
...config.modules[module.title].options,
|
|
|
|
|
[keys[index]]: {
|
2022-05-26 18:15:00 +02:00
|
|
|
...config.modules[module.title].options?.[keys[index]],
|
2022-05-24 20:14:07 +02:00
|
|
|
value: (e.target as any)[0].value,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Group noWrap align="end" position="center" mt={0}>
|
|
|
|
|
<TextInput
|
|
|
|
|
key={optionName}
|
|
|
|
|
id={optionName}
|
|
|
|
|
name={optionName}
|
|
|
|
|
label={values[index].name}
|
2022-06-28 12:10:46 +02:00
|
|
|
defaultValue={
|
|
|
|
|
(moduleInConfig?.options?.[keys[index]]?.value as string) ??
|
|
|
|
|
(values[index].value as string) ??
|
|
|
|
|
''
|
|
|
|
|
}
|
2022-05-24 20:14:07 +02:00
|
|
|
onChange={(e) => {}}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Button type="submit">Save</Button>
|
|
|
|
|
</Group>
|
|
|
|
|
</form>
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-05-18 22:11:37 +02:00
|
|
|
// TODO: Add support for other types
|
|
|
|
|
if (type === 'boolean') {
|
|
|
|
|
items.push(
|
|
|
|
|
<Switch
|
|
|
|
|
defaultChecked={
|
|
|
|
|
// Set default checked to the value of the option if it exists
|
2022-06-28 12:10:46 +02:00
|
|
|
(moduleInConfig?.options?.[keys[index]]?.value as boolean) ??
|
|
|
|
|
(values[index].value as boolean) ??
|
|
|
|
|
false
|
2022-05-18 22:11:37 +02:00
|
|
|
}
|
|
|
|
|
key={keys[index]}
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
setConfig({
|
|
|
|
|
...config,
|
2022-05-22 20:42:10 +02:00
|
|
|
modules: {
|
|
|
|
|
...config.modules,
|
|
|
|
|
[module.title]: {
|
|
|
|
|
...config.modules[module.title],
|
|
|
|
|
options: {
|
|
|
|
|
...config.modules[module.title].options,
|
|
|
|
|
[keys[index]]: {
|
|
|
|
|
...config.modules[module.title].options?.[keys[index]],
|
|
|
|
|
value: e.currentTarget.checked,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-05-18 22:11:37 +02:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
label={values[index].name}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2022-05-26 18:16:57 +02:00
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function ModuleWrapper(props: any) {
|
|
|
|
|
const { module }: { module: IModule } = props;
|
2022-06-11 18:37:13 +02:00
|
|
|
const { colorScheme } = useMantineColorScheme();
|
2022-05-26 18:16:57 +02:00
|
|
|
const { config, setConfig } = useConfig();
|
|
|
|
|
const enabledModules = config.modules ?? {};
|
|
|
|
|
// Remove 'Module' from enabled modules titles
|
|
|
|
|
const isShown = enabledModules[module.title]?.enabled ?? false;
|
|
|
|
|
|
2022-05-10 20:56:48 +02:00
|
|
|
if (!isShown) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2022-06-11 18:37:13 +02:00
|
|
|
|
2022-05-10 18:57:04 +02:00
|
|
|
return (
|
2022-06-11 18:37:13 +02:00
|
|
|
<Card
|
|
|
|
|
{...props}
|
|
|
|
|
hidden={!isShown}
|
|
|
|
|
withBorder
|
|
|
|
|
radius="lg"
|
|
|
|
|
shadow="sm"
|
|
|
|
|
style={{
|
|
|
|
|
background: `rgba(${colorScheme === 'dark' ? '37, 38, 43,' : '255, 255, 255,'} \
|
|
|
|
|
${(config.settings.appOpacity || 100) / 100}`,
|
|
|
|
|
borderColor: `rgba(${colorScheme === 'dark' ? '37, 38, 43,' : '233, 236, 239,'} \
|
|
|
|
|
${(config.settings.appOpacity || 100) / 100}`,
|
|
|
|
|
}}
|
|
|
|
|
>
|
2022-06-08 18:41:22 +02:00
|
|
|
<ModuleMenu
|
|
|
|
|
module={module}
|
|
|
|
|
styles={{
|
|
|
|
|
root: {
|
|
|
|
|
position: 'absolute',
|
2022-06-14 20:50:11 +02:00
|
|
|
top: 12,
|
|
|
|
|
right: 12,
|
2022-06-08 18:41:22 +02:00
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<module.component />
|
|
|
|
|
</Card>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function ModuleMenu(props: any) {
|
|
|
|
|
const { module, styles } = props;
|
|
|
|
|
const items: JSX.Element[] = getItems(module);
|
|
|
|
|
return (
|
|
|
|
|
<>
|
2022-05-18 22:11:37 +02:00
|
|
|
{module.options && (
|
|
|
|
|
<Menu
|
2022-05-24 20:14:07 +02:00
|
|
|
size="lg"
|
2022-05-18 22:11:37 +02:00
|
|
|
shadow="xl"
|
|
|
|
|
closeOnItemClick={false}
|
|
|
|
|
radius="md"
|
|
|
|
|
position="left"
|
|
|
|
|
styles={{
|
|
|
|
|
root: {
|
2022-06-08 18:41:22 +02:00
|
|
|
...props?.styles?.root,
|
2022-05-18 22:11:37 +02:00
|
|
|
},
|
|
|
|
|
body: {
|
2022-05-29 15:30:03 +02:00
|
|
|
// Add shadow and elevation to the body
|
|
|
|
|
boxShadow: '0 0 14px 14px rgba(0, 0, 0, 0.05)',
|
2022-05-18 22:11:37 +02:00
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Menu.Label>Settings</Menu.Label>
|
|
|
|
|
{items.map((item) => (
|
|
|
|
|
<Menu.Item key={item.key}>{item}</Menu.Item>
|
|
|
|
|
))}
|
|
|
|
|
</Menu>
|
|
|
|
|
)}
|
2022-06-08 18:41:22 +02:00
|
|
|
</>
|
2022-05-10 18:57:04 +02:00
|
|
|
);
|
|
|
|
|
}
|