diff --git a/src/components/Dashboard/Tiles/tilesDefinitions.tsx b/src/components/Dashboard/Tiles/tilesDefinitions.tsx
index 20e3cf023..a3d950748 100644
--- a/src/components/Dashboard/Tiles/tilesDefinitions.tsx
+++ b/src/components/Dashboard/Tiles/tilesDefinitions.tsx
@@ -1,15 +1,14 @@
-import { IntegrationsType } from '../../../types/integration';
-import { CalendarTile } from '../../../widgets/calendar/CalendarTile';
-import { ClockTile } from '../../../widgets/clock/ClockTile';
-import { DashDotTile } from '../../../widgets/dashDot/DashDotTile';
-import { UseNetTile } from '../../../widgets/useNet/UseNetTile';
-import { WeatherTile } from '../../../widgets/weather/WeatherTile';
+import calendarDefinition from '../../../widgets/calendar/CalendarTile';
+import clockDefinition from '../../../widgets/clock/ClockTile';
+import dashDotDefinition from '../../../widgets/dashDot/DashDotTile';
+import useNetDefinition from '../../../widgets/useNet/UseNetTile';
+import weatherDefinition from '../../../widgets/weather/WeatherTile';
import { EmptyTile } from './EmptyTile';
import { AppTile } from './Apps/AppTile';
// TODO: just remove and use app (later app) directly. For widgets the the definition should contain min/max width/height
type TileDefinitionProps = {
- [key in keyof IntegrationsType | 'app']: {
+ [key in keyof any | 'app']: {
minWidth?: number;
minHeight?: number;
maxWidth?: number;
@@ -18,7 +17,6 @@ type TileDefinitionProps = {
};
};
-// TODO: change components for other modules
export const Tiles: TileDefinitionProps = {
app: {
component: AppTile,
@@ -28,49 +26,49 @@ export const Tiles: TileDefinitionProps = {
maxHeight: 12,
},
bitTorrent: {
- component: EmptyTile, //CalendarTile,
+ component: EmptyTile,
minWidth: 4,
maxWidth: 12,
minHeight: 5,
maxHeight: 12,
},
calendar: {
- component: CalendarTile,
+ component: calendarDefinition.component,
minWidth: 4,
maxWidth: 12,
minHeight: 5,
maxHeight: 12,
},
clock: {
- component: ClockTile,
+ component: clockDefinition.component,
minWidth: 4,
maxWidth: 12,
minHeight: 2,
maxHeight: 12,
},
dashDot: {
- component: DashDotTile,
+ component: dashDotDefinition.component,
minWidth: 4,
maxWidth: 9,
minHeight: 5,
maxHeight: 14,
},
torrentNetworkTraffic: {
- component: EmptyTile, //CalendarTile,
+ component: EmptyTile,
minWidth: 4,
maxWidth: 12,
minHeight: 5,
maxHeight: 12,
},
useNet: {
- component: UseNetTile,
+ component: useNetDefinition.component,
minWidth: 4,
maxWidth: 12,
minHeight: 5,
maxHeight: 12,
},
weather: {
- component: WeatherTile,
+ component: weatherDefinition.component,
minWidth: 4,
maxWidth: 12,
minHeight: 2,
diff --git a/src/components/Dashboard/Views/DashboardView.tsx b/src/components/Dashboard/Views/DashboardView.tsx
index 9cb6342ac..bff1f0f04 100644
--- a/src/components/Dashboard/Views/DashboardView.tsx
+++ b/src/components/Dashboard/Views/DashboardView.tsx
@@ -2,6 +2,7 @@ import { Group, Stack } from '@mantine/core';
import { useMemo } from 'react';
import { useConfigContext } from '../../../config/provider';
import { useScreenLargerThan } from '../../../tools/hooks/useScreenLargerThan';
+import { useScreenSmallerThan } from '../../../tools/hooks/useScreenSmallerThan';
import { CategoryType } from '../../../types/category';
import { WrapperType } from '../../../types/wrapper';
import { DashboardCategory } from '../Wrappers/Category/Category';
@@ -11,11 +12,11 @@ import { DashboardWrapper } from '../Wrappers/Wrapper/Wrapper';
export const DashboardView = () => {
const wrappers = useWrapperItems();
const layoutSettings = useConfigContext()?.config?.settings.customization.layout;
- const showSidebars = useScreenLargerThan('md');
+ const doNotShowSidebar = useScreenSmallerThan('md');
return (
- {layoutSettings?.enabledLeftSidebar && showSidebars ? (
+ {layoutSettings?.enabledLeftSidebar && !doNotShowSidebar ? (
) : null}
@@ -27,7 +28,7 @@ export const DashboardView = () => {
)
)}
- {layoutSettings?.enabledRightSidebar && showSidebars ? (
+ {layoutSettings?.enabledRightSidebar && !doNotShowSidebar ? (
) : null}
diff --git a/src/components/Dashboard/Wrappers/Wrapper/Wrapper.tsx b/src/components/Dashboard/Wrappers/Wrapper/Wrapper.tsx
index 013eb2eb2..7c07a72e3 100644
--- a/src/components/Dashboard/Wrappers/Wrapper/Wrapper.tsx
+++ b/src/components/Dashboard/Wrappers/Wrapper/Wrapper.tsx
@@ -34,7 +34,6 @@ export const DashboardWrapper = ({ wrapper }: DashboardWrapperProps) => {
);
})}
{Object.entries(integrations).map(([k, v]) => {
- console.log(k);
const { component: TileComponent, ...tile } = Tiles[k as keyof typeof Tiles];
return (
diff --git a/src/types/integration.ts b/src/types/integration.ts
deleted file mode 100644
index cddd9ca26..000000000
--- a/src/types/integration.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { TileBaseType } from './tile';
-
-export interface IntegrationsType {
- calendar?: CalendarIntegrationType;
- clock?: ClockIntegrationType;
- weather?: WeatherIntegrationType;
- dashDot?: DashDotIntegrationType;
- bitTorrent?: BitTorrentIntegrationType;
- useNet?: UseNetIntegrationType;
- torrentNetworkTraffic?: TorrentNetworkTrafficIntegrationType;
-}
-
-export interface CalendarIntegrationType extends TileBaseType {
- properties: {
- isWeekStartingAtSunday: boolean;
- };
-}
-
-export interface ClockIntegrationType extends TileBaseType {
- properties: {
- is24HoursFormat: boolean;
- };
-}
-
-export interface WeatherIntegrationType extends TileBaseType {
- properties: {
- location: string;
- isFahrenheit: boolean;
- };
-}
-
-export interface DashDotIntegrationType extends TileBaseType {
- properties: {
- graphs: DashDotGraphType[];
- isStorageMultiView: boolean;
- isCpuMultiView: boolean;
- isCompactView: boolean;
- url: string;
- };
-}
-
-export type DashDotGraphType = 'cpu' | 'storage' | 'ram' | 'network' | 'gpu';
-
-export interface BitTorrentIntegrationType extends TileBaseType {
- properties: {
- hideDownloadedTorrents: boolean;
- };
-}
-
-export type UseNetIntegrationType = TileBaseType;
-
-export type TorrentNetworkTrafficIntegrationType = TileBaseType;
diff --git a/src/widgets/calendar/CalendarTile.tsx b/src/widgets/calendar/CalendarTile.tsx
index a9760c869..a23ac7c6d 100644
--- a/src/widgets/calendar/CalendarTile.tsx
+++ b/src/widgets/calendar/CalendarTile.tsx
@@ -1,5 +1,6 @@
import { createStyles, MantineThemeColors, useMantineTheme } from '@mantine/core';
import { Calendar } from '@mantine/dates';
+import { IconCalendarTime } from '@tabler/icons';
import { useQuery } from '@tanstack/react-query';
import { useState } from 'react';
import { HomarrCardWrapper } from '../../components/Dashboard/Tiles/HomarrCardWrapper';
@@ -7,15 +8,30 @@ import { BaseTileProps } from '../../components/Dashboard/Tiles/type';
import { useConfigContext } from '../../config/provider';
import { useColorTheme } from '../../tools/color';
import { isToday } from '../../tools/isToday';
-import { CalendarIntegrationType } from '../../types/integration';
+import { defineWidget } from '../helper';
+import { IWidget } from '../widgets';
import { CalendarDay } from './CalendarDay';
import { MediasType } from './type';
+const definition = defineWidget({
+ id: 'calendar',
+ icon: IconCalendarTime,
+ options: {
+ sundayStart: {
+ type: 'switch',
+ defaultValue: false,
+ },
+ },
+ component: CalendarTile,
+});
+
+export type ICalendarWidget = IWidget;
+
interface CalendarTileProps extends BaseTileProps {
- module: CalendarIntegrationType | undefined; // TODO: change to new type defined through widgetDefinition
+ module: ICalendarWidget;
}
-export const CalendarTile = ({ className, module }: CalendarTileProps) => {
+function CalendarTile({ className, module }: CalendarTileProps) {
const { secondaryColor } = useColorTheme();
const { name: configName } = useConfigContext();
const { classes, cx } = useStyles(secondaryColor);
@@ -34,8 +50,6 @@ export const CalendarTile = ({ className, module }: CalendarTileProps) => {
).json()) as MediasType,
});
- if (!module) return <>>;
-
return (
{
size="xs"
fullWidth
onChange={() => {}}
- firstDayOfWeek={module.properties?.isWeekStartingAtSunday ? 'sunday' : 'monday'}
+ firstDayOfWeek={module.properties.sundayStart ? 'sunday' : 'monday'}
dayStyle={(date) => ({
margin: 1,
backgroundColor: isToday(date)
@@ -67,7 +81,7 @@ export const CalendarTile = ({ className, module }: CalendarTileProps) => {
/>
);
-};
+}
const useStyles = createStyles((theme, secondaryColor: keyof MantineThemeColors) => ({
weekend: {
@@ -99,3 +113,5 @@ const getReleasedMediasForDate = (medias: MediasType | undefined, date: Date): M
totalCount,
};
};
+
+export default definition;
diff --git a/src/widgets/clock/ClockTile.tsx b/src/widgets/clock/ClockTile.tsx
index 0866e8e36..bd90ae1c3 100644
--- a/src/widgets/clock/ClockTile.tsx
+++ b/src/widgets/clock/ClockTile.tsx
@@ -5,15 +5,31 @@ import { HomarrCardWrapper } from '../../components/Dashboard/Tiles/HomarrCardWr
import { WidgetsMenu } from '../../components/Dashboard/Tiles/Widgets/WidgetsMenu';
import { BaseTileProps } from '../../components/Dashboard/Tiles/type';
import { useSetSafeInterval } from '../../tools/hooks/useSetSafeInterval';
-import { ClockIntegrationType } from '../../types/integration';
+import { defineWidget } from '../helper';
+import { IWidget } from '../widgets';
+import { IconClock } from '@tabler/icons';
+
+const definition = defineWidget({
+ id: 'clock',
+ icon: IconClock,
+ options: {
+ display24HourFormat: {
+ type: 'switch',
+ defaultValue: false,
+ },
+ },
+ component: ClockTile,
+});
+
+export type IClockWidget = IWidget;
interface ClockTileProps extends BaseTileProps {
- module: ClockIntegrationType; // TODO: change to new type defined through widgetDefinition
+ module: IClockWidget; // TODO: change to new type defined through widgetDefinition
}
-export const ClockTile = ({ className, module }: ClockTileProps) => {
+function ClockTile({ className, module }: ClockTileProps) {
const date = useDateState();
- const formatString = module?.properties.is24HoursFormat ? 'HH:mm' : 'h:mm A';
+ const formatString = module.properties.display24HourFormat ? 'HH:mm' : 'h:mm A';
// TODO: add widgetWrapper that is generic and uses the definition
return (
@@ -21,7 +37,7 @@ export const ClockTile = ({ className, module }: ClockTileProps) => {
integration="clock"
module={module}
- options={module?.properties}
+ options={module.properties}
labels={{ is24HoursFormat: 'descriptor.settings.display24HourFormat.label' }}
/>
@@ -32,7 +48,7 @@ export const ClockTile = ({ className, module }: ClockTileProps) => {
);
-};
+}
/**
* State which updates when the minute is changing
@@ -69,3 +85,5 @@ const getMsUntilNextMinute = () => {
);
return nextMinute.getTime() - now.getTime();
};
+
+export default definition;
diff --git a/src/widgets/dashDot/DashDotGraph.tsx b/src/widgets/dashDot/DashDotGraph.tsx
index 70280bbc7..7ad600ed3 100644
--- a/src/widgets/dashDot/DashDotGraph.tsx
+++ b/src/widgets/dashDot/DashDotGraph.tsx
@@ -35,10 +35,13 @@ export const DashDotGraph = ({ graph, isCompact, dashDotUrl }: DashDotGraphProps
const useIframeSrc = (dashDotUrl: string, graph: GraphType, isCompact: boolean) => {
const { colorScheme, colors, radius } = useMantineTheme();
const surface = (colorScheme === 'dark' ? colors.dark[7] : colors.gray[0]).substring(1); // removes # from hex value
+
+ const graphId = graph.id === 'memory' ? 'ram' : graph.id;
+
return (
`${dashDotUrl}` +
`?singleGraphMode=true` +
- `&graph=${graph.id}` +
+ `&graph=${graphId}` +
`&theme=${colorScheme}` +
`&surface=${surface}` +
`&gap=${isCompact ? 10 : 5}` +
diff --git a/src/widgets/dashDot/DashDotTile.tsx b/src/widgets/dashDot/DashDotTile.tsx
index fea8273d2..5c25143d6 100644
--- a/src/widgets/dashDot/DashDotTile.tsx
+++ b/src/widgets/dashDot/DashDotTile.tsx
@@ -2,20 +2,52 @@ import { createStyles, Group, Title } from '@mantine/core';
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
import { useTranslation } from 'next-i18next';
-import { DashDotCompactNetwork, DashDotInfo } from './DashDotCompactNetwork';
-import { DashDotGraph } from './DashDotGraph';
-import { DashDotCompactStorage } from './DashDotCompactStorage';
-import { BaseTileProps } from '../../components/Dashboard/Tiles/type';
-import { DashDotIntegrationType } from '../../types/integration';
-import { WidgetsMenu } from '../../components/Dashboard/Tiles/Widgets/WidgetsMenu';
import { HomarrCardWrapper } from '../../components/Dashboard/Tiles/HomarrCardWrapper';
+import { BaseTileProps } from '../../components/Dashboard/Tiles/type';
+import { WidgetsMenu } from '../../components/Dashboard/Tiles/Widgets/WidgetsMenu';
import { useConfigContext } from '../../config/provider';
+import { defineWidget } from '../helper';
+import { IWidget } from '../widgets';
+import { DashDotCompactNetwork, DashDotInfo } from './DashDotCompactNetwork';
+import { DashDotCompactStorage } from './DashDotCompactStorage';
+import { DashDotGraph } from './DashDotGraph';
+
+const definition = defineWidget({
+ id: 'dashDot',
+ icon: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/dashdot.png',
+ options: {
+ cpuMultiView: {
+ type: 'switch',
+ defaultValue: false,
+ },
+ storageMultiView: {
+ type: 'switch',
+ defaultValue: false,
+ },
+ useCompactView: {
+ type: 'switch',
+ defaultValue: true,
+ },
+ graphs: {
+ type: 'multi-select',
+ defaultValue: ['cpu', 'memory'],
+ data: ['cpu', 'memory', 'storage', 'network', 'gpu'],
+ },
+ url: {
+ type: 'text',
+ defaultValue: '',
+ },
+ },
+ component: DashDotTile,
+});
+
+export type IDashDotTile = IWidget;
interface DashDotTileProps extends BaseTileProps {
- module: DashDotIntegrationType; // TODO: change to new type defined through widgetDefinition
+ module: IDashDotTile; // TODO: change to new type defined through widgetDefinition
}
-export const DashDotTile = ({ module, className }: DashDotTileProps) => {
+function DashDotTile({ module, className }: DashDotTileProps) {
const { classes } = useDashDotTileStyles();
const { t } = useTranslation('modules/dashdot');
@@ -25,11 +57,11 @@ export const DashDotTile = ({ module, className }: DashDotTileProps) => {
const graphs = module?.properties.graphs.map((g) => ({
id: g,
- name: t(`card.graphs.${g === 'ram' ? 'memory' : g}.title`),
+ name: t(`card.graphs.${g}.title`),
twoSpan: ['network', 'gpu'].includes(g),
isMultiView:
- (g === 'cpu' && module.properties.isCpuMultiView) ||
- (g === 'storage' && module.properties.isStorageMultiView),
+ (g === 'cpu' && module.properties.cpuMultiView) ||
+ (g === 'storage' && module.properties.storageMultiView),
}));
const heading = (
@@ -66,7 +98,7 @@ export const DashDotTile = ({ module, className }: DashDotTileProps) => {
);
}
- const isCompact = module?.properties.isCompactView ?? false;
+ const isCompact = module?.properties.useCompactView ?? false;
const isCompactStorageVisible = graphs?.some((g) => g.id === 'storage' && isCompact);
@@ -101,7 +133,7 @@ export const DashDotTile = ({ module, className }: DashDotTileProps) => {
)}
);
-};
+}
const useDashDotInfo = () => {
const { name: configName, config } = useConfigContext();
@@ -139,3 +171,5 @@ export const useDashDotTileStyles = createStyles(() => ({
},
},
}));
+
+export default definition;
diff --git a/src/widgets/dashDot/types.ts b/src/widgets/dashDot/types.ts
index 16123735c..b11e4e520 100644
--- a/src/widgets/dashDot/types.ts
+++ b/src/widgets/dashDot/types.ts
@@ -1,7 +1,5 @@
-import { DashDotGraphType } from '../../types/integration';
-
export interface DashDotGraph {
- id: DashDotGraphType;
+ id: string;
name: string;
twoSpan: boolean;
isMultiView: boolean | undefined;
diff --git a/src/widgets/helper.ts b/src/widgets/helper.ts
new file mode 100644
index 000000000..1344584bb
--- /dev/null
+++ b/src/widgets/helper.ts
@@ -0,0 +1,10 @@
+// Method which allows to define the type verry specific and type checks all
+
+import { IWidgetDefinition } from './widgets';
+
+// The options of IWidgetDefinition are so heavily typed that it even used 'true' as type
+export const defineWidget = >(
+ options: TOptions
+) => {
+ return options;
+};
diff --git a/src/widgets/index.ts b/src/widgets/index.ts
index 56c87d6ff..82126275b 100644
--- a/src/widgets/index.ts
+++ b/src/widgets/index.ts
@@ -1,2 +1,4 @@
-export {};
+import calendar from './calendar/CalendarTile';
+
+export default { calendar };
// TODO: add exports of new IWidgetDefinitions to here
diff --git a/src/widgets/useNet/UseNetTile.tsx b/src/widgets/useNet/UseNetTile.tsx
index d6dbe6122..b05287acc 100644
--- a/src/widgets/useNet/UseNetTile.tsx
+++ b/src/widgets/useNet/UseNetTile.tsx
@@ -9,7 +9,7 @@ import {
Title,
useMantineTheme,
} from '@mantine/core';
-import { IconPlayerPause, IconPlayerPlay } from '@tabler/icons';
+import { IconFileDownload, IconPlayerPause, IconPlayerPlay } from '@tabler/icons';
import { useEffect, useState } from 'react';
import { useElementSize } from '@mantine/hooks';
@@ -24,14 +24,25 @@ import { useConfigContext } from '../../config/provider';
import { useGetUsenetInfo, usePauseUsenetQueue, useResumeUsenetQueue } from '../../tools/hooks/api';
import { HomarrCardWrapper } from '../../components/Dashboard/Tiles/HomarrCardWrapper';
import { humanFileSize } from '../../tools/humanFileSize';
+import { defineWidget } from '../helper';
+import { IWidget } from '../widgets';
dayjs.extend(duration);
const downloadAppTypes: AppIntegrationType['type'][] = ['sabnzbd', 'nzbGet'];
+const definition = defineWidget({
+ id: 'useNet',
+ icon: IconFileDownload,
+ options: {},
+ component: UseNetTile,
+});
+
+export type IWeatherWidget = IWidget;
+
interface UseNetTileProps extends BaseTileProps {}
-export const UseNetTile = ({ className }: UseNetTileProps) => {
+function UseNetTile({ className }: UseNetTileProps) {
const { t } = useTranslation('modules/usenet');
const { config } = useConfigContext();
const downloadApps =
@@ -117,4 +128,6 @@ export const UseNetTile = ({ className }: UseNetTileProps) => {
);
-};
+}
+
+export default definition;
diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx
index 342a8d1d4..c768c5705 100644
--- a/src/widgets/weather/WeatherTile.tsx
+++ b/src/widgets/weather/WeatherTile.tsx
@@ -1,22 +1,37 @@
import { Center, Group, Skeleton, Stack, Text, Title } from '@mantine/core';
-import { IconArrowDownRight, IconArrowUpRight } from '@tabler/icons';
+import { IconArrowDownRight, IconArrowUpRight, IconCloudRain } from '@tabler/icons';
import { HomarrCardWrapper } from '../../components/Dashboard/Tiles/HomarrCardWrapper';
-import { WidgetsMenu } from '../../components/Dashboard/Tiles/Widgets/WidgetsMenu';
import { BaseTileProps } from '../../components/Dashboard/Tiles/type';
-import { WeatherIntegrationType } from '../../types/integration';
+import { WidgetsMenu } from '../../components/Dashboard/Tiles/Widgets/WidgetsMenu';
+import { defineWidget } from '../helper';
+import { IWidget } from '../widgets';
import { useWeatherForCity } from './useWeatherForCity';
import { WeatherIcon } from './WeatherIcon';
+const definition = defineWidget({
+ id: 'weather',
+ icon: IconCloudRain,
+ options: {
+ displayInFahrenheit: {
+ type: 'switch',
+ defaultValue: false,
+ },
+ location: {
+ type: 'text',
+ defaultValue: 'Paris',
+ },
+ },
+ component: WeatherTile,
+});
+
+export type IWeatherWidget = IWidget;
+
interface WeatherTileProps extends BaseTileProps {
- module: WeatherIntegrationType; // TODO: change to new type defined through widgetDefinition
+ module: IWeatherWidget;
}
-export const WeatherTile = ({ className, module }: WeatherTileProps) => {
- const {
- data: weather,
- isLoading,
- isError,
- } = useWeatherForCity(module?.properties.location ?? 'Paris');
+function WeatherTile({ className, module }: WeatherTileProps) {
+ const { data: weather, isLoading, isError } = useWeatherForCity(module.properties.location);
if (isLoading) {
return (
@@ -49,7 +64,7 @@ export const WeatherTile = ({ className, module }: WeatherTileProps) => {
{
{getPerferedUnit(
weather!.current_weather.temperature,
- module?.properties.isFahrenheit
+ module.properties.displayInFahrenheit
)}
@@ -70,7 +85,7 @@ export const WeatherTile = ({ className, module }: WeatherTileProps) => {
{getPerferedUnit(
weather!.daily.temperature_2m_max[0],
- module?.properties.isFahrenheit
+ module.properties.displayInFahrenheit
)}
@@ -79,7 +94,7 @@ export const WeatherTile = ({ className, module }: WeatherTileProps) => {
{getPerferedUnit(
weather!.daily.temperature_2m_min[0],
- module?.properties.isFahrenheit
+ module.properties.displayInFahrenheit
)}
@@ -90,7 +105,9 @@ export const WeatherTile = ({ className, module }: WeatherTileProps) => {
);
-};
+}
const getPerferedUnit = (value: number, isFahrenheit = false): string =>
isFahrenheit ? `${(value * (9 / 5) + 32).toFixed(1)}°F` : `${value.toFixed(1)}°C`;
+
+export default definition;
diff --git a/src/widgets/widgets.d.ts b/src/widgets/widgets.d.ts
new file mode 100644
index 000000000..a02f7bf1a
--- /dev/null
+++ b/src/widgets/widgets.d.ts
@@ -0,0 +1,70 @@
+import { IconSun, TablerIcon } from '@tabler/icons';
+import React from 'react';
+import { BaseTileProps } from '../components/Dashboard/Tiles/type';
+
+// Type of widgets which are safed to config
+export type IWidget = {
+ id: TKey;
+ properties: {
+ [key in keyof TDefinition['options']]: MakeLessSpecific<
+ TDefinition['options'][key]['defaultValue']
+ >;
+ };
+ area: AreaType;
+ shape: ShapeType;
+};
+
+// Makes the type less specific
+// For example when the type true is used as input the result is boolean
+// By not using this type the definition would always be { property: true }
+type MakeLessSpecific = TInput extends boolean
+ ? boolean
+ : TInput extends number
+ ? number
+ : TInput extends string[]
+ ? string[]
+ : TInput extends string
+ ? string
+ : never;
+
+// Types of options that can be specified for the widget edit modal
+export type IWidgetOptionValue =
+ | IMultiSelectOptionValue
+ | ISwitchOptionValue
+ | ITextInputOptionValue
+ | INumberInputOptionValue;
+
+// will show a multi-select with specified data
+export type IMultiSelectOptionValue = {
+ type: 'multi-select';
+ defaultValue: string[];
+ data: string[];
+};
+
+// will show a switch
+export type ISwitchOptionValue = {
+ type: 'switch';
+ defaultValue: boolean;
+};
+
+// will show a text-input
+export type ITextInputOptionValue = {
+ type: 'text';
+ defaultValue: string;
+};
+
+// will show a number-input
+export type INumberInputOptionValue = {
+ type: 'number';
+ defaultValue: string;
+};
+
+// is used to type the widget definitions which will be used to display all widgets
+export type IWidgetDefinition = {
+ id: TKey;
+ icon: TablerIcon | string;
+ options: {
+ [key: string]: IWidgetOptionValue;
+ };
+ component: React.ComponentType;
+};