🐛 Fix issues with change position modal

This commit is contained in:
Meierschlumpf
2023-01-07 09:19:02 +01:00
parent 48fa81aaad
commit 2da206d5b0
6 changed files with 187 additions and 158 deletions

View File

@@ -194,67 +194,6 @@
"properties": [] "properties": []
} }
}, },
{
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a337",
"name": "Discord",
"url": "https://discord.com/invite/aCsmEV5RgA",
"behaviour": {
"onClickUrl": "https://discord.com/invite/aCsmEV5RgA",
"isOpeningNewTab": true,
"externalUrl": "https://discord.com/invite/aCsmEV5RgA"
},
"network": {
"enabledStatusChecker": false,
"okStatus": [
200
]
},
"appearance": {
"iconUrl": "https://cdn.jsdelivr.net/gh/walkxhub/dashboard-icons/png/discord.png"
},
"integration": {
"type": null,
"properties": []
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"md": {
"location": {
"x": 0,
"y": 0
},
"size": {
"width": 1,
"height": 4
}
},
"sm": {
"location": {
"x": 0,
"y": 1
},
"size": {
"width": 1,
"height": 1
}
},
"lg": {
"location": {
"x": 0,
"y": 0
},
"size": {
"width": 1,
"height": 1
}
}
}
},
{ {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a990", "id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a990",
"name": "Donate", "name": "Donate",
@@ -316,67 +255,6 @@
} }
} }
}, },
{
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33a",
"name": "Documentation",
"url": "https://homarr.dev",
"behaviour": {
"onClickUrl": "https://homarr.dev",
"externalUrl": "https://homarr.dev",
"isOpeningNewTab": true
},
"network": {
"enabledStatusChecker": false,
"okStatus": [
200
]
},
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"integration": {
"type": null,
"properties": []
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"md": {
"location": {
"x": 0,
"y": 10
},
"size": {
"width": 1,
"height": 1
}
},
"sm": {
"location": {
"x": 0,
"y": 10
},
"size": {
"width": 2,
"height": 1
}
},
"lg": {
"location": {
"x": 3,
"y": 1
},
"size": {
"width": 1,
"height": 1
}
}
}
},
{ {
"id": "e41a11f5-9c6e-41bc-ac0e-4c4c47582faa", "id": "e41a11f5-9c6e-41bc-ac0e-4c4c47582faa",
"name": "Your app", "name": "Your app",
@@ -434,6 +312,128 @@
"type": null, "type": null,
"properties": [] "properties": []
} }
},
{
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a337",
"name": "Discord",
"url": "https://discord.com/invite/aCsmEV5RgA",
"behaviour": {
"onClickUrl": "https://discord.com/invite/aCsmEV5RgA",
"isOpeningNewTab": true,
"externalUrl": "https://discord.com/invite/aCsmEV5RgA"
},
"network": {
"enabledStatusChecker": false,
"okStatus": [
200
]
},
"appearance": {
"iconUrl": "https://cdn.jsdelivr.net/gh/walkxhub/dashboard-icons/png/discord.png"
},
"integration": {
"type": null,
"properties": []
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"md": {
"location": {
"x": 0,
"y": 0
},
"size": {
"width": 1,
"height": 3
}
},
"sm": {
"location": {
"x": 0,
"y": 1
},
"size": {
"width": 1,
"height": 1
}
},
"lg": {
"location": {
"x": 0,
"y": 0
},
"size": {
"width": 1,
"height": 1
}
}
}
},
{
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33a",
"name": "Documentation",
"url": "https://homarr.dev",
"behaviour": {
"onClickUrl": "https://homarr.dev",
"externalUrl": "https://homarr.dev",
"isOpeningNewTab": true
},
"network": {
"enabledStatusChecker": false,
"okStatus": [
200
]
},
"appearance": {
"iconUrl": "/imgs/logo/logo.png"
},
"integration": {
"type": null,
"properties": []
},
"area": {
"type": "category",
"properties": {
"id": "47af36c0-47c1-4e5b-bfc7-ad645ee6a33f"
}
},
"shape": {
"md": {
"location": {
"x": 0,
"y": 3
},
"size": {
"width": 1,
"height": 1
}
},
"sm": {
"location": {
"x": 0,
"y": 10
},
"size": {
"width": 2,
"height": 1
}
},
"lg": {
"location": {
"x": 3,
"y": 1
},
"size": {
"width": 1,
"height": 1
}
}
}
} }
], ],
"widgets": [ "widgets": [

View File

@@ -4,5 +4,5 @@
"height": "Height", "height": "Height",
"yPosition": "Y axis position", "yPosition": "Y axis position",
"zeroOrHigher": "0 or higher", "zeroOrHigher": "0 or higher",
"betweenXandY": "Between {{mim}} and {{max}}" "betweenXandY": "Between {{min}} and {{max}}"
} }

View File

@@ -3,6 +3,7 @@ import { closeModal, ContextModalProps } from '@mantine/modals';
import { useConfigContext } from '../../../../config/provider'; import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store'; import { useConfigStore } from '../../../../config/store';
import { AppType } from '../../../../types/app'; import { AppType } from '../../../../types/app';
import { useGridstackStore, useWrapperColumnCount } from '../../Wrappers/gridstack/store';
import { ChangePositionModal } from './ChangePositionModal'; import { ChangePositionModal } from './ChangePositionModal';
type ChangeAppPositionModalInnerProps = { type ChangeAppPositionModalInnerProps = {
@@ -16,6 +17,9 @@ export const ChangeAppPositionModal = ({
}: ContextModalProps<ChangeAppPositionModalInnerProps>) => { }: ContextModalProps<ChangeAppPositionModalInnerProps>) => {
const { name: configName } = useConfigContext(); const { name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig); const updateConfig = useConfigStore((x) => x.updateConfig);
const shapeSize = useGridstackStore((x) => x.currentShapeSize);
if (!shapeSize) return null;
const handleSubmit = (x: number, y: number, width: number, height: number) => { const handleSubmit = (x: number, y: number, width: number, height: number) => {
if (!configName) { if (!configName) {
@@ -28,7 +32,13 @@ export const ChangeAppPositionModal = ({
...previousConfig, ...previousConfig,
apps: [ apps: [
...previousConfig.apps.filter((x) => x.id !== innerProps.app.id), ...previousConfig.apps.filter((x) => x.id !== innerProps.app.id),
{ ...innerProps.app, shape: { location: { x, y }, size: { width, height } } }, {
...innerProps.app,
shape: {
...innerProps.app.shape,
[shapeSize]: { location: { x, y }, size: { width, height } },
},
},
], ],
}), }),
true true
@@ -49,28 +59,35 @@ export const ChangeAppPositionModal = ({
onCancel={handleCancel} onCancel={handleCancel}
widthData={widthData} widthData={widthData}
heightData={heightData} heightData={heightData}
initialX={innerProps.app.shape.location.x} initialX={innerProps.app.shape[shapeSize]?.location.x}
initialY={innerProps.app.shape.location.y} initialY={innerProps.app.shape[shapeSize]?.location.y}
initialWidth={innerProps.app.shape.size.width} initialWidth={innerProps.app.shape[shapeSize]?.size.width}
initialHeight={innerProps.app.shape.size.height} initialHeight={innerProps.app.shape[shapeSize]?.size.height}
/> />
); );
}; };
const useHeightData = (): SelectItem[] => const useHeightData = (): SelectItem[] => {
Array.from(Array(11).keys()).map((n) => { const mainAreaWidth = useGridstackStore((x) => x.mainAreaWidth);
const index = n + 1; const wrapperColumnCount = useWrapperColumnCount();
return {
value: index.toString(),
label: `${64 * index}px`,
};
});
const useWidthData = (): SelectItem[] => return Array.from(Array(11).keys()).map((n) => {
Array.from(Array(11).keys()).map((n) => {
const index = n + 1; const index = n + 1;
return { return {
value: index.toString(), value: index.toString(),
label: `${64 * index}px`, label: `${Math.floor(index * (mainAreaWidth! / wrapperColumnCount!))}px`,
}; };
}); });
};
const useWidthData = (): SelectItem[] => {
const wrapperColumnCount = useWrapperColumnCount();
return Array.from(Array(wrapperColumnCount!).keys()).map((n) => {
const index = n + 1;
return {
value: index.toString(),
// eslint-disable-next-line no-mixed-operators
label: `${((100 / wrapperColumnCount!) * index).toFixed(2)}%`,
};
});
};

View File

@@ -4,10 +4,10 @@ import { useTranslation } from 'next-i18next';
import { useConfigContext } from '../../../../config/provider'; import { useConfigContext } from '../../../../config/provider';
interface ChangePositionModalProps { interface ChangePositionModalProps {
initialX: number; initialX?: number;
initialY: number; initialY?: number;
initialWidth: number; initialWidth?: number;
initialHeight: number; initialHeight?: number;
widthData: SelectItem[]; widthData: SelectItem[];
heightData: SelectItem[]; heightData: SelectItem[];
onSubmit: (x: number, y: number, width: number, height: number) => void; onSubmit: (x: number, y: number, width: number, height: number) => void;
@@ -28,10 +28,10 @@ export const ChangePositionModal = ({
const form = useForm<FormType>({ const form = useForm<FormType>({
initialValues: { initialValues: {
x: initialX, x: initialX ?? null,
y: initialY, y: initialY ?? null,
width: initialWidth, width: initialWidth?.toString() ?? '',
height: initialHeight, height: initialHeight?.toString() ?? '',
}, },
validateInputOnChange: true, validateInputOnChange: true,
validateInputOnBlur: true, validateInputOnBlur: true,
@@ -42,7 +42,12 @@ export const ChangePositionModal = ({
return; return;
} }
onSubmit(form.values.x, form.values.y, form.values.width, form.values.height); const width = parseInt(form.values.width, 10);
const height = parseInt(form.values.height, 10);
if (!form.values.x || !form.values.y || Number.isNaN(width) || Number.isNaN(height)) return;
onSubmit(form.values.x, form.values.y, width, height);
}; };
const { t } = useTranslation(['layout/modals/change-position', 'common']); const { t } = useTranslation(['layout/modals/change-position', 'common']);
@@ -112,8 +117,8 @@ export const ChangePositionModal = ({
}; };
type FormType = { type FormType = {
x: number; x: number | null;
y: number; y: number | null;
width: number; width: string;
height: number; height: string;
}; };

View File

@@ -4,7 +4,7 @@ import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store'; import { useConfigStore } from '../../../../config/store';
import widgets from '../../../../widgets'; import widgets from '../../../../widgets';
import { WidgetChangePositionModalInnerProps } from '../../Tiles/Widgets/WidgetsMenu'; import { WidgetChangePositionModalInnerProps } from '../../Tiles/Widgets/WidgetsMenu';
import { useGridstackStore } from '../../Wrappers/gridstack/store'; import { useGridstackStore, useWrapperColumnCount } from '../../Wrappers/gridstack/store';
import { ChangePositionModal } from './ChangePositionModal'; import { ChangePositionModal } from './ChangePositionModal';
export const ChangeWidgetPositionModal = ({ export const ChangeWidgetPositionModal = ({
@@ -68,23 +68,30 @@ export const ChangeWidgetPositionModal = ({
}; };
const useWidthData = (integration: string): SelectItem[] => { const useWidthData = (integration: string): SelectItem[] => {
const wrapperColumnCount = useWrapperColumnCount();
const currentWidget = widgets[integration as keyof typeof widgets]; const currentWidget = widgets[integration as keyof typeof widgets];
if (!currentWidget) return []; if (!currentWidget) return [];
const offset = currentWidget.gridstack.minWidth ?? 2; const offset = currentWidget.gridstack.minWidth ?? 2;
const length = (currentWidget.gridstack.maxWidth ?? 12) - offset; const length = (currentWidget.gridstack.maxWidth > wrapperColumnCount!
return Array.from({ length }, (_, i) => i + offset).map((n) => ({ ? wrapperColumnCount!
: currentWidget.gridstack.maxWidth) - offset;
return Array.from({ length: length + 1 }, (_, i) => i + offset).map((n) => ({
value: n.toString(), value: n.toString(),
label: `${64 * n}px`, // eslint-disable-next-line no-mixed-operators
label: `${(100 / wrapperColumnCount! * n).toFixed(2)}%`,
})); }));
}; };
const useHeightData = (integration: string): SelectItem[] => { const useHeightData = (integration: string): SelectItem[] => {
const mainAreaWidth = useGridstackStore((x) => x.mainAreaWidth);
const wrapperColumnCount = useWrapperColumnCount();
const currentWidget = widgets[integration as keyof typeof widgets]; const currentWidget = widgets[integration as keyof typeof widgets];
if (!currentWidget) return []; if (!currentWidget) return [];
const offset = currentWidget.gridstack.minHeight ?? 2; const offset = currentWidget.gridstack.minHeight ?? 2;
const length = (currentWidget.gridstack.maxHeight ?? 12) - offset; const length = (currentWidget.gridstack.maxHeight ?? 12) - offset;
return Array.from({ length }, (_, i) => i + offset).map((n) => ({ return Array.from({ length }, (_, i) => i + offset).map((n) => ({
value: n.toString(), value: n.toString(),
label: `${64 * n}px`, label: `${(mainAreaWidth! / wrapperColumnCount!) * n}px`,
})); }));
}; };

View File

@@ -83,7 +83,7 @@ export const useGridstack = (
// widget width is used to define sizes of gridstack items within global.scss // widget width is used to define sizes of gridstack items within global.scss
root.style.setProperty('--gridstack-widget-width', widgetWidth.toString()); root.style.setProperty('--gridstack-widget-width', widgetWidth.toString());
gridRef.current?.cellHeight(widgetWidth); gridRef.current?.cellHeight(widgetWidth);
}, [mainAreaWidth, wrapperColumnCount]); }, [mainAreaWidth, wrapperColumnCount, gridRef.current]);
useEffect(() => { useEffect(() => {
// column count is used to define count of columns of gridstack within global.scss // column count is used to define count of columns of gridstack within global.scss