diff --git a/src/components/Dashboard/Modals/ChangePosition/ChangeIntegrationPositionModal.tsx b/src/components/Dashboard/Modals/ChangePosition/ChangeIntegrationPositionModal.tsx new file mode 100644 index 000000000..fddde2e01 --- /dev/null +++ b/src/components/Dashboard/Modals/ChangePosition/ChangeIntegrationPositionModal.tsx @@ -0,0 +1,89 @@ +import { SelectItem } from '@mantine/core'; +import { closeModal, ContextModalProps } from '@mantine/modals'; +import { useConfigContext } from '../../../../config/provider'; +import { useConfigStore } from '../../../../config/store'; +import { IntegrationsType } from '../../../../types/integration'; +import { TileBaseType } from '../../../../types/tile'; +import { Tiles } from '../../Tiles/tilesDefinitions'; +import { ChangePositionModal } from './ChangePositionModal'; + +export type IntegrationChangePositionModalInnerProps = { + integration: keyof IntegrationsType; + module: TileBaseType; +}; + +export const ChangeIntegrationPositionModal = ({ + context, + id, + innerProps, +}: ContextModalProps) => { + const { name: configName } = useConfigContext(); + const updateConfig = useConfigStore((x) => x.updateConfig); + + const handleSubmit = (x: number, y: number, width: number, height: number) => { + if (!configName) { + return; + } + + updateConfig(configName, (prev) => ({ + ...prev, + integrations: { + ...prev.integrations, + [innerProps.integration]: { + ...prev.integrations[innerProps.integration], + shape: { + location: { + x, + y, + }, + size: { + height, + width, + }, + }, + }, + }, + })); + context.closeModal(id); + }; + + const handleCancel = () => { + closeModal(id); + }; + + const widthData = useWidthData(innerProps.integration); + const heightData = useHeightData(innerProps.integration); + + return ( + + ); +}; + +const useWidthData = (integration: keyof IntegrationsType): SelectItem[] => { + const tileDefinitions = Tiles[integration]; + const offset = tileDefinitions.minWidth ?? 2; + const length = (tileDefinitions.maxWidth ?? 12) - offset; + return Array.from({ length }, (_, i) => i + offset).map((n) => ({ + value: n.toString(), + label: `${64 * n}px`, + })); +}; + +const useHeightData = (integration: keyof IntegrationsType): SelectItem[] => { + const tileDefinitions = Tiles[integration]; + const offset = tileDefinitions.minHeight ?? 2; + const length = (tileDefinitions.maxHeight ?? 12) - offset; + return Array.from({ length }, (_, i) => i + offset).map((n) => ({ + value: n.toString(), + label: `${64 * n}px`, + })); +}; diff --git a/src/components/Dashboard/Modals/ChangePosition/ChangePositionModal.tsx b/src/components/Dashboard/Modals/ChangePosition/ChangePositionModal.tsx index 7c6aec0c4..52bb4afcb 100644 --- a/src/components/Dashboard/Modals/ChangePosition/ChangePositionModal.tsx +++ b/src/components/Dashboard/Modals/ChangePosition/ChangePositionModal.tsx @@ -1,44 +1,55 @@ -import { Button, Flex, Grid, NumberInput } from '@mantine/core'; +import { Button, Flex, Grid, NumberInput, Select, SelectItem } from '@mantine/core'; import { useForm } from '@mantine/form'; -import { closeModal, ContextModalProps } from '@mantine/modals'; import { useConfigContext } from '../../../../config/provider'; -import { useConfigStore } from '../../../../config/store'; -import { ServiceType } from '../../../../types/service'; -import { TileBaseType } from '../../../../types/tile'; + +interface ChangePositionModalProps { + initialX: number; + initialY: number; + initialWidth: number; + initialHeight: number; + widthData: SelectItem[]; + heightData: SelectItem[]; + onSubmit: (x: number, y: number, width: number, height: number) => void; + onCancel: () => void; +} export const ChangePositionModal = ({ - context, - id, - innerProps, -}: ContextModalProps<{ type: 'service' | 'type'; tile: TileBaseType }>) => { - const updateConfig = useConfigStore((x) => x.updateConfig); + initialX, + initialY, + initialWidth, + initialHeight, + widthData, + heightData, + onCancel, + onSubmit, +}: ChangePositionModalProps) => { const { name: configName } = useConfigContext(); - const form = useForm({ + const form = useForm({ initialValues: { - tile: innerProps.tile, + x: initialX, + y: initialY, + width: initialWidth, + height: initialHeight, }, validateInputOnChange: true, validateInputOnBlur: true, }); - const onSubmit = () => { + const handleSubmit = () => { if (!configName) { return; } - const tileAsService = form.values.tile as ServiceType; - - updateConfig(configName, (previous) => ({ - ...previous, - services: [...previous.services.filter((x) => x.id === tileAsService.id), tileAsService], - })); - - closeModal(id); + onSubmit(form.values.x, form.values.y, form.values.width, form.values.height); }; + console.log(`Initial: (${form.values.width} / ${form.values.height})`); + console.log(widthData); + console.log(heightData); + return ( -
+ @@ -56,39 +67,48 @@ export const ChangePositionModal = ({ min={0} label="Y Position" description="0 or higher" - {...form.getInputProps('tile.shape.location.y')} + {...form.getInputProps('y')} /> - - - - +
); }; + +type FormType = { + x: number; + y: number; + width: number; + height: number; +}; diff --git a/src/components/Dashboard/Modals/ChangePosition/ChangeServicePositionModal.tsx b/src/components/Dashboard/Modals/ChangePosition/ChangeServicePositionModal.tsx new file mode 100644 index 000000000..506f2b0c5 --- /dev/null +++ b/src/components/Dashboard/Modals/ChangePosition/ChangeServicePositionModal.tsx @@ -0,0 +1,72 @@ +import { SelectItem } from '@mantine/core'; +import { closeModal, ContextModalProps } from '@mantine/modals'; +import { useConfigContext } from '../../../../config/provider'; +import { useConfigStore } from '../../../../config/store'; +import { ServiceType } from '../../../../types/service'; +import { ChangePositionModal } from './ChangePositionModal'; + +type ChangeServicePositionModalInnerProps = { + service: ServiceType; +}; + +export const ChangeServicePositionModal = ({ + id, + context, + innerProps, +}: ContextModalProps) => { + const { name: configName } = useConfigContext(); + const updateConfig = useConfigStore((x) => x.updateConfig); + + const handleSubmit = (x: number, y: number, width: number, height: number) => { + if (!configName) { + return; + } + + updateConfig(configName, (previousConfig) => ({ + ...previousConfig, + services: [ + ...previousConfig.services.filter((x) => x.id !== innerProps.service.id), + { ...innerProps.service, shape: { location: { x, y }, size: { width, height } } }, + ], + })); + context.closeModal(id); + }; + + const handleCancel = () => { + closeModal(id); + }; + + const widthData = useWidthData(); + const heightData = useHeightData(); + + return ( + + ); +}; + +const useHeightData = (): SelectItem[] => + Array.from(Array(11).keys()).map((n) => { + const index = n + 1; + return { + value: index.toString(), + label: `${64 * index}px`, + }; + }); + +const useWidthData = (): SelectItem[] => + Array.from(Array(11).keys()).map((n) => { + const index = n + 1; + return { + value: index.toString(), + label: `${64 * index}px`, + }; + }); diff --git a/src/components/Dashboard/Tiles/IntegrationChangePositionModal.tsx b/src/components/Dashboard/Tiles/IntegrationChangePositionModal.tsx deleted file mode 100644 index 07aabb448..000000000 --- a/src/components/Dashboard/Tiles/IntegrationChangePositionModal.tsx +++ /dev/null @@ -1,169 +0,0 @@ -import { - Button, - Center, - createStyles, - Grid, - Group, - NumberInput, - Select, - SelectItem, - Stack, - Text, - Title, -} from '@mantine/core'; -import { useForm } from '@mantine/form'; -import { ContextModalProps } from '@mantine/modals'; -import { - IconArrowsUpDown, - IconCalendarTime, - IconClock, - IconCloudRain, - IconFileDownload, -} from '@tabler/icons'; -import { useTranslation } from 'next-i18next'; -import { useConfigContext } from '../../../config/provider'; -import { useConfigStore } from '../../../config/store'; -import { IntegrationsType } from '../../../types/integration'; -import { TileBaseType } from '../../../types/tile'; -import { integrationModuleTranslationsMap } from './IntegrationsEditModal'; -import { ServiceIcon } from './Service/ServiceIcon'; -import { Tiles } from './tilesDefinitions'; - -export type IntegrationChangePositionModalInnerProps = { - integration: keyof IntegrationsType; - module: TileBaseType; -}; - -export const IntegrationChangePositionModal = ({ - context, - id, - innerProps, -}: ContextModalProps) => { - const translationKey = integrationModuleTranslationsMap.get(innerProps.integration); - const { t } = useTranslation([translationKey ?? '', 'common']); - const { classes } = useStyles(); - const { name: configName } = useConfigContext(); - const updateConfig = useConfigStore((x) => x.updateConfig); - const form = useForm({ - initialValues: { - x: innerProps.module.shape.location.x, - y: innerProps.module.shape.location.y, - width: innerProps.module.shape.size.width.toString(), - height: innerProps.module.shape.size.height.toString(), - }, - }); - if (!configName) return null; - null; - const handleSubmit = (values: FormType) => { - updateConfig(configName, (prev) => { - return { - ...prev, - integrations: { - ...prev.integrations, - [innerProps.integration]: { - ...prev.integrations[innerProps.integration], - shape: { - location: { - x: values.x, - y: values.y, - }, - size: { - height: parseInt(values.height), - width: parseInt(values.width), - }, - }, - }, - }, - }; - }); - context.closeModal(id); - }; - - const widthData = useWidthData(innerProps.integration); - const heightData = useHeightData(innerProps.integration); - - return ( - - -
-
{integrationIcons[innerProps.integration]}
-
- - Change position of - - - {t('descriptor.name')} - -
-
- - - - - - - - - - - - - - - - - -
-
- ); -}; - -type FormType = { - x: number; - y: number; - width: string; - height: string; -}; - -// TODO: define width of gridstack somewhere (64) -const useWidthData = (integration: keyof IntegrationsType): SelectItem[] => { - const tileDefinitions = Tiles[integration]; - const offset = tileDefinitions.minWidth ?? 2; - const length = (tileDefinitions.maxWidth ?? 12) - offset; - return Array.from({ length }, (_, i) => i + offset).map((n) => ({ - value: n.toString(), - label: `${64 * n}px`, - })); -}; - -const useHeightData = (integration: keyof IntegrationsType): SelectItem[] => { - const tileDefinitions = Tiles[integration]; - const offset = tileDefinitions.minHeight ?? 2; - const length = (tileDefinitions.maxHeight ?? 12) - offset; - return Array.from({ length }, (_, i) => i + offset).map((n) => ({ - value: n.toString(), - label: `${64 * n}px`, - })); -}; - -const integrationIcons = { - useNet: , - bitTorrent: , - calendar: , - clock: , - weather: , - dashDot: , - torrentNetworkTraffic: , -}; - -const useStyles = createStyles(() => ({ - icon: { - height: 120, - width: 120, - }, -})); diff --git a/src/components/Dashboard/Tiles/Integrations/IntegrationsMenu.tsx b/src/components/Dashboard/Tiles/Integrations/IntegrationsMenu.tsx index 97f04e9f4..ac04fac11 100644 --- a/src/components/Dashboard/Tiles/Integrations/IntegrationsMenu.tsx +++ b/src/components/Dashboard/Tiles/Integrations/IntegrationsMenu.tsx @@ -42,7 +42,7 @@ export const IntegrationsMenu = const handleChangeSizeClick = () => { openContextModalGeneric({ - modal: 'integrationChangePosition', + modal: 'changeIntegrationPositionModal', size: 'xl', title: null, innerProps: { diff --git a/src/components/Dashboard/Tiles/Service/ServiceMenu.tsx b/src/components/Dashboard/Tiles/Service/ServiceMenu.tsx index 8b14f4c61..49739536f 100644 --- a/src/components/Dashboard/Tiles/Service/ServiceMenu.tsx +++ b/src/components/Dashboard/Tiles/Service/ServiceMenu.tsx @@ -19,9 +19,9 @@ export const ServiceMenu = ({ service }: TileMenuProps) => { const handleClickChangePosition = () => { openContextModalGeneric({ - modal: 'changeTilePosition', + modal: 'changeServicePositionModal', innerProps: { - tile: service, + service, }, }); }; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 5448b0272..2e2c4bdf4 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -9,18 +9,18 @@ import { appWithTranslation } from 'next-i18next'; import { AppProps } from 'next/app'; import Head from 'next/head'; import { useState } from 'react'; -import { IntegrationsEditModal } from '../components/Dashboard/Tiles/IntegrationsEditModal'; -import { IntegrationRemoveModal } from '../components/Dashboard/Tiles/IntegrationRemoveModal'; -import { ChangePositionModal } from '../components/Dashboard/Modals/ChangePosition/ChangePositionModal'; +import { ChangeIntegrationPositionModal } from '../components/Dashboard/Modals/ChangePosition/ChangeIntegrationPositionModal'; +import { ChangeServicePositionModal } from '../components/Dashboard/Modals/ChangePosition/ChangeServicePositionModal'; import { EditServiceModal } from '../components/Dashboard/Modals/EditService/EditServiceModal'; import { SelectElementModal } from '../components/Dashboard/Modals/SelectElement/SelectElementModal'; +import { IntegrationRemoveModal } from '../components/Dashboard/Tiles/IntegrationRemoveModal'; +import { IntegrationsEditModal } from '../components/Dashboard/Tiles/IntegrationsEditModal'; +import { CategoryEditModal } from '../components/Dashboard/Wrappers/Category/CategoryEditModal'; import { ConfigProvider } from '../config/provider'; +import '../styles/global.scss'; import { ColorTheme } from '../tools/color'; import { queryClient } from '../tools/queryClient'; import { theme } from '../tools/theme'; -import { IntegrationChangePositionModal } from '../components/Dashboard/Tiles/IntegrationChangePositionModal'; -import '../styles/global.scss'; -import { CategoryEditModal } from '../components/Dashboard/Wrappers/Category/CategoryEditModal'; function App(this: any, props: AppProps & { colorScheme: ColorScheme }) { const { Component, pageProps } = props; @@ -90,9 +90,9 @@ function App(this: any, props: AppProps & { colorScheme: ColorScheme }) { selectElement: SelectElementModal, integrationOptions: IntegrationsEditModal, integrationRemove: IntegrationRemoveModal, - integrationChangePosition: IntegrationChangePositionModal, categoryEditModal: CategoryEditModal, - changeTilePosition: ChangePositionModal, + changeServicePositionModal: ChangeServicePositionModal, + changeIntegrationPositionModal: ChangeIntegrationPositionModal, }} >