diff --git a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx index 608000e05..9cd2bcdd8 100644 --- a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx @@ -14,6 +14,7 @@ import { useState } from 'react'; import { useConfigContext } from '../../../../config/provider'; import { useConfigStore } from '../../../../config/store'; import { AppType } from '../../../../types/app'; +import { useEditModeStore } from '../../Views/useEditModeStore'; import { AppearanceTab } from './Tabs/AppereanceTab/AppereanceTab'; import { BehaviourTab } from './Tabs/BehaviourTab/BehaviourTab'; import { GeneralTab } from './Tabs/GeneralTab/GeneralTab'; @@ -33,6 +34,7 @@ export const EditAppModal = ({ const { t } = useTranslation(['layout/modals/add-app', 'common']); const { name: configName, config } = useConfigContext(); const updateConfig = useConfigStore((store) => store.updateConfig); + const { enabled: isEditMode } = useEditModeStore(); const [allowAppNamePropagation, setAllowAppNamePropagation] = useState( innerProps.allowAppNamePropagation ); @@ -87,9 +89,15 @@ export const EditAppModal = ({ configName, (previousConfig) => ({ ...previousConfig, - apps: [...previousConfig.apps.filter((x) => x.id !== form.values.id), form.values], + apps: [ + ...previousConfig.apps.filter((x) => x.id !== values.id), + { + ...values, + }, + ], }), - true + true, + !isEditMode ); // also close the parent modal diff --git a/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx b/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx index 2d38dfbe4..21345ef41 100644 --- a/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx +++ b/src/components/Dashboard/Modals/SelectElement/Components/Overview/AvailableElementsOverview.tsx @@ -3,8 +3,10 @@ import { IconBox, IconStack } from '@tabler/icons'; import { useTranslation } from 'next-i18next'; import { ReactNode } from 'react'; import { v4 as uuidv4 } from 'uuid'; +import { useConfigContext } from '../../../../../../config/provider'; import { openContextModalGeneric } from '../../../../../../tools/mantineModalManagerExtensions'; import { AppType } from '../../../../../../types/app'; +import { appTileDefinition } from '../../../../Tiles/Apps/AppTile'; import { useStyles } from '../Shared/styles'; interface AvailableElementTypesProps { @@ -17,6 +19,8 @@ export const AvailableElementTypes = ({ onOpenStaticElements, }: AvailableElementTypesProps) => { const { t } = useTranslation('layout/element-selector/selector'); + const { config } = useConfigContext(); + const getLowestWrapper = () => config?.wrappers.sort((a, b) => a.position - b.position)[0]; return ( <> @@ -45,10 +49,11 @@ export const AvailableElementTypes = ({ isOpeningNewTab: true, externalUrl: '', }, + area: { - type: 'sidebar', + type: 'wrapper', properties: { - location: 'right', + id: getLowestWrapper()?.id ?? '', }, }, shape: { @@ -57,8 +62,8 @@ export const AvailableElementTypes = ({ y: 0, }, size: { - height: 1, - width: 1, + width: appTileDefinition.minWidth, + height: appTileDefinition.minHeight, }, }, integration: { diff --git a/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx b/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx index db486cfae..01caf6c8b 100644 --- a/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx +++ b/src/components/Dashboard/Modals/SelectElement/Components/WidgetsTab/WidgetElementType.tsx @@ -4,6 +4,7 @@ import { useTranslation } from 'next-i18next'; import { useConfigContext } from '../../../../../../config/provider'; import { useConfigStore } from '../../../../../../config/store'; import { IWidget, IWidgetDefinition } from '../../../../../../widgets/widgets'; +import { useEditModeStore } from '../../../../Views/useEditModeStore'; import { GenericAvailableElementType } from '../Shared/GenericElementType'; interface WidgetElementTypeProps { @@ -18,6 +19,7 @@ export const WidgetElementType = ({ id, image, disabled, widget }: WidgetElement const { t } = useTranslation(`modules/${id}`); const { name: configName, config } = useConfigContext(); const updateConfig = useConfigStore((x) => x.updateConfig); + const isEditMode = useEditModeStore((x) => x.enabled); if (!configName) return null; @@ -56,9 +58,10 @@ export const WidgetElementType = ({ id, image, disabled, widget }: WidgetElement }, ], }), - true + true, + !isEditMode ); - // TODO: safe to file system + closeModal('selectElement'); }; diff --git a/src/components/Dashboard/Tiles/Apps/AppTile.tsx b/src/components/Dashboard/Tiles/Apps/AppTile.tsx index 9c5a8c5e3..d577f8c37 100644 --- a/src/components/Dashboard/Tiles/Apps/AppTile.tsx +++ b/src/components/Dashboard/Tiles/Apps/AppTile.tsx @@ -88,3 +88,11 @@ const useStyles = createStyles((theme, _params, getRef) => ({ }, }, })); + +export const appTileDefinition = { + component: AppTile, + minWidth: 2, + maxWidth: 12, + minHeight: 2, + maxHeight: 12, +}; diff --git a/src/components/Dashboard/Tiles/tilesDefinitions.tsx b/src/components/Dashboard/Tiles/tilesDefinitions.tsx deleted file mode 100644 index 1cc23fa03..000000000 --- a/src/components/Dashboard/Tiles/tilesDefinitions.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import calendarDefinition from '../../../widgets/calendar/CalendarTile'; -import clockDefinition from '../../../widgets/date/DateTile'; -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 any | 'app']: { - minWidth?: number; - minHeight?: number; - maxWidth?: number; - maxHeight?: number; - component: React.ElementType; - }; -}; - -export const Tiles: TileDefinitionProps = { - app: { - component: AppTile, - minWidth: 2, - maxWidth: 12, - minHeight: 2, - maxHeight: 12, - }, - bitTorrent: { - component: EmptyTile, - minWidth: 4, - maxWidth: 12, - minHeight: 5, - maxHeight: 12, - }, - calendar: { - component: calendarDefinition.component, - minWidth: 4, - maxWidth: 12, - minHeight: 5, - maxHeight: 12, - }, - clock: { - component: clockDefinition.component, - minWidth: 4, - maxWidth: 12, - minHeight: 2, - maxHeight: 12, - }, - dashDot: { - component: dashDotDefinition.component, - minWidth: 4, - maxWidth: 9, - minHeight: 5, - maxHeight: 14, - }, - torrentNetworkTraffic: { - component: EmptyTile, - minWidth: 4, - maxWidth: 12, - minHeight: 5, - maxHeight: 12, - }, - useNet: { - component: useNetDefinition.component, - minWidth: 4, - maxWidth: 12, - minHeight: 5, - maxHeight: 12, - }, - weather: { - component: weatherDefinition.component, - minWidth: 4, - maxWidth: 12, - minHeight: 2, - maxHeight: 12, - }, -}; diff --git a/src/components/Dashboard/Wrappers/WrapperContent.tsx b/src/components/Dashboard/Wrappers/WrapperContent.tsx index 657a8eae9..579bbd7c8 100644 --- a/src/components/Dashboard/Wrappers/WrapperContent.tsx +++ b/src/components/Dashboard/Wrappers/WrapperContent.tsx @@ -4,7 +4,7 @@ import { AppType } from '../../../types/app'; import Widgets from '../../../widgets'; import { IWidget, IWidgetDefinition } from '../../../widgets/widgets'; import { WidgetWrapper } from '../../../widgets/WidgetWrapper'; -import { Tiles } from '../Tiles/tilesDefinitions'; +import { appTileDefinition } from '../Tiles/Apps/AppTile'; import { GridstackTileWrapper } from '../Tiles/TileWrapper'; interface WrapperContentProps { @@ -21,7 +21,7 @@ export function WrapperContent({ apps, refs, widgets }: WrapperContentProps) { return ( <> {apps?.map((app) => { - const { component: TileComponent, ...tile } = Tiles.app; + const { component: TileComponent, ...tile } = appTileDefinition; return ( ((set, get) => ({ updateConfig: async ( name, updateCallback: (previous: ConfigType) => ConfigType, - shouldRegenerateGridstack = false + shouldRegenerateGridstack = false, + shouldSaveConfigToFileSystem = false ) => { const { configs } = get(); const currentConfig = configs.find((x) => x.value.configProperties.name === name); @@ -23,7 +25,6 @@ export const useConfigStore = create((set, get) => ({ // copies the value of currentConfig and creates a non reference object named previousConfig const previousConfig: ConfigType = JSON.parse(JSON.stringify(currentConfig.value)); - // TODO: update config on server const updatedConfig = updateCallback(currentConfig.value); set((old) => ({ ...old, @@ -40,6 +41,10 @@ export const useConfigStore = create((set, get) => ({ ) { currentConfig.increaseVersion(); } + + if (shouldSaveConfigToFileSystem) { + axios.put(`/api/configs/${name}`, { ...updatedConfig }); + } }, })); @@ -51,6 +56,7 @@ interface UseConfigStoreType { updateCallback: (previous: ConfigType) => ConfigType, shouldRegenerateGridstace?: | boolean - | ((previousConfig: ConfigType, currentConfig: ConfigType) => boolean) + | ((previousConfig: ConfigType, currentConfig: ConfigType) => boolean), + shouldSaveConfigToFileSystem?: boolean ) => Promise; } diff --git a/tsconfig.json b/tsconfig.json index 97fd02c6c..4cc7a24b0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "allowJs": true, "skipLibCheck": true, "strict": true, - "forceConsistentCasingInFileNames": true, + "forceConsistentCasingInFileNames": false, "noEmit": true, "esModuleInterop": true, "module": "esnext",