diff --git a/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx b/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx
index 501ab664e..a8bd89ebe 100644
--- a/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx
+++ b/src/components/Dashboard/Wrappers/Sidebar/Sidebar.tsx
@@ -4,11 +4,30 @@ import { useCardStyles } from '../../../layout/useCardStyles';
import { useGridstack } from '../gridstack/use-gridstack';
import { WrapperContent } from '../WrapperContent';
-interface DashboardSidebarProps {
+interface DashboardSidebarProps extends DashboardSidebarInnerProps {
+ location: 'right' | 'left';
+ isGridstackReady: boolean;
+}
+
+export const DashboardSidebar = ({ location, isGridstackReady }: DashboardSidebarProps) => (
+
+ {isGridstackReady && }
+
+);
+
+interface DashboardSidebarInnerProps {
location: 'right' | 'left';
}
-export const DashboardSidebar = ({ location }: DashboardSidebarProps) => {
+// Is Required because of the gridstack main area width.
+const SidebarInner = ({ location }: DashboardSidebarInnerProps) => {
const { refs, apps, widgets } = useGridstack('sidebar', location);
const minRow = useMinRowForFullHeight(refs.wrapper);
@@ -18,14 +37,13 @@ export const DashboardSidebar = ({ location }: DashboardSidebarProps) => {
} = useCardStyles(false);
return (
-
+
@@ -34,4 +52,4 @@ export const DashboardSidebar = ({ location }: DashboardSidebarProps) => {
};
const useMinRowForFullHeight = (wrapperRef: RefObject) =>
- wrapperRef.current ? Math.floor(wrapperRef.current!.offsetHeight / 64) : 2;
+ wrapperRef.current ? Math.floor(wrapperRef.current!.offsetHeight / 128) : 2;
diff --git a/src/components/Dashboard/Wrappers/WrapperContent.tsx b/src/components/Dashboard/Wrappers/WrapperContent.tsx
index 579bbd7c8..cfb82ae39 100644
--- a/src/components/Dashboard/Wrappers/WrapperContent.tsx
+++ b/src/components/Dashboard/Wrappers/WrapperContent.tsx
@@ -6,6 +6,7 @@ import { IWidget, IWidgetDefinition } from '../../../widgets/widgets';
import { WidgetWrapper } from '../../../widgets/WidgetWrapper';
import { appTileDefinition } from '../Tiles/Apps/AppTile';
import { GridstackTileWrapper } from '../Tiles/TileWrapper';
+import { useGridstackStore } from './gridstack/store';
interface WrapperContentProps {
apps: AppType[];
@@ -18,6 +19,10 @@ interface WrapperContentProps {
}
export function WrapperContent({ apps, refs, widgets }: WrapperContentProps) {
+ const shapeSize = useGridstackStore((x) => x.currentShapeSize);
+
+ if (!shapeSize) return null;
+
return (
<>
{apps?.map((app) => {
@@ -29,8 +34,8 @@ export function WrapperContent({ apps, refs, widgets }: WrapperContentProps) {
key={app.id}
itemRef={refs.items.current[app.id]}
{...tile}
- {...app.shape.location}
- {...app.shape.size}
+ {...app.shape[shapeSize]?.location}
+ {...app.shape[shapeSize]?.size}
>
@@ -49,8 +54,8 @@ export function WrapperContent({ apps, refs, widgets }: WrapperContentProps) {
itemRef={refs.items.current[widget.id]}
id={definition.id}
{...definition.gridstack}
- {...widget.shape.location}
- {...widget.shape.size}
+ {...widget.shape[shapeSize]?.location}
+ {...widget.shape[shapeSize]?.size}
>
diff --git a/src/components/Dashboard/Wrappers/gridstack/init-gridstack.ts b/src/components/Dashboard/Wrappers/gridstack/init-gridstack.ts
index ba8d2d413..36836222d 100644
--- a/src/components/Dashboard/Wrappers/gridstack/init-gridstack.ts
+++ b/src/components/Dashboard/Wrappers/gridstack/init-gridstack.ts
@@ -1,6 +1,7 @@
import { GridStack, GridStackNode } from 'fily-publish-gridstack';
import { MutableRefObject, RefObject } from 'react';
import { AppType } from '../../../../types/app';
+import { ShapeType } from '../../../../types/shape';
import { IWidget } from '../../../../widgets/widgets';
export const initializeGridstack = (
@@ -12,7 +13,8 @@ export const initializeGridstack = (
items: AppType[],
widgets: IWidget[],
isEditMode: boolean,
- isLargerThanSm: boolean,
+ wrapperColumnCount: 3 | 6 | 12,
+ shapeSize: 'sm' | 'md' | 'lg',
events: {
onChange: (changedNode: GridStackNode) => void;
onAdd: (addedNode: GridStackNode) => void;
@@ -20,27 +22,29 @@ export const initializeGridstack = (
) => {
if (!wrapperRef.current) return;
// calculates the currently available count of columns
- const columnCount =
- areaType === 'sidebar' ? 1 : isLargerThanSm || typeof isLargerThanSm === 'undefined' ? 12 : 6;
- const minRow = areaType !== 'sidebar' ? 1 : Math.floor(wrapperRef.current.offsetHeight / 64);
+ const columnCount = areaType === 'sidebar' ? 2 : wrapperColumnCount;
+ const minRow = areaType !== 'sidebar' ? 1 : Math.floor(wrapperRef.current.offsetHeight / 128);
// initialize gridstack
const newGrid = gridRef;
newGrid.current = GridStack.init(
{
column: columnCount,
margin: 10,
- cellHeight: 64,
+ cellHeight: 128,
float: true,
alwaysShowResizeHandle: 'mobile',
acceptWidgets: true,
disableOneColumnMode: true,
staticGrid: !isEditMode,
minRow,
+ animate: false,
},
// selector of the gridstack item (it's eather category or wrapper)
`.grid-stack-${areaType}[data-${areaType}='${areaId}']`
);
const grid = newGrid.current;
+ // Must be used to update the column count after the initialization
+ grid.column(columnCount);
// Add listener for moving items around in a wrapper
grid.on('change', (_, el) => {
@@ -60,13 +64,23 @@ export const initializeGridstack = (
grid.batchUpdate();
grid.removeAll(false);
- items.forEach(
- ({ id }) =>
- itemRefs.current[id] && grid.makeWidget(itemRefs.current[id].current as HTMLDivElement)
- );
- widgets.forEach(
- ({ id }) =>
- itemRefs.current[id] && grid.makeWidget(itemRefs.current[id].current as HTMLDivElement)
- );
+ items.forEach(({ id, shape }) => {
+ const item = itemRefs.current[id]?.current;
+ setAttributesFromShape(item, shape[shapeSize]);
+ item && grid.makeWidget(item as HTMLDivElement);
+ });
+ widgets.forEach(({ id, shape }) => {
+ const item = itemRefs.current[id]?.current;
+ setAttributesFromShape(item, shape[shapeSize]);
+ item && grid.makeWidget(item as HTMLDivElement);
+ });
grid.batchUpdate(false);
};
+
+function setAttributesFromShape(ref: HTMLDivElement | null, sizedShape: ShapeType['lg']) {
+ if (!sizedShape || !ref) return;
+ ref.setAttribute('gs-x', sizedShape.location.x.toString());
+ ref.setAttribute('gs-y', sizedShape.location.y.toString());
+ ref.setAttribute('gs-w', sizedShape.size.width.toString());
+ ref.setAttribute('gs-h', sizedShape.size.height.toString());
+}
diff --git a/src/components/Dashboard/Wrappers/gridstack/store.tsx b/src/components/Dashboard/Wrappers/gridstack/store.tsx
new file mode 100644
index 000000000..881c0ee39
--- /dev/null
+++ b/src/components/Dashboard/Wrappers/gridstack/store.tsx
@@ -0,0 +1,31 @@
+import { useMantineTheme } from '@mantine/core';
+import create from 'zustand';
+
+export const useGridstackStore = create((set, get) => ({
+ mainAreaWidth: null,
+ currentShapeSize: null,
+ setMainAreaWidth: (w: number) =>
+ set((v) => ({ ...v, mainAreaWidth: w, currentShapeSize: getCurrentShapeSize(w) })),
+}));
+
+interface GridstackStoreType {
+ mainAreaWidth: null | number;
+ currentShapeSize: null | 'sm' | 'md' | 'lg';
+ setMainAreaWidth: (width: number) => void;
+}
+
+export const useWrapperColumnCount = () => {
+ const mainAreaWidth = useGridstackStore((x) => x.mainAreaWidth);
+ const { sm, xl } = useMantineTheme().breakpoints;
+ if (!mainAreaWidth) return null;
+
+ if (mainAreaWidth >= xl) return 12;
+
+ if (mainAreaWidth >= sm) return 6;
+
+ return 3;
+};
+
+function getCurrentShapeSize(size: number) {
+ return size >= 1400 ? 'lg' : size >= 768 ? 'md' : 'sm';
+}
diff --git a/src/components/Dashboard/Wrappers/gridstack/use-gridstack.ts b/src/components/Dashboard/Wrappers/gridstack/use-gridstack.ts
index b6e7fbf64..a47f07486 100644
--- a/src/components/Dashboard/Wrappers/gridstack/use-gridstack.ts
+++ b/src/components/Dashboard/Wrappers/gridstack/use-gridstack.ts
@@ -1,22 +1,13 @@
import { GridStack, GridStackNode } from 'fily-publish-gridstack';
-import {
- createRef,
- MutableRefObject,
- RefObject,
- useEffect,
- useLayoutEffect,
- useMemo,
- useRef,
-} from 'react';
+import { createRef, MutableRefObject, RefObject, useEffect, useMemo, useRef } from 'react';
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
-import { useResize } from '../../../../hooks/use-resize';
-import { useScreenLargerThan } from '../../../../hooks/useScreenLargerThan';
import { AppType } from '../../../../types/app';
import { AreaType } from '../../../../types/area';
import { IWidget } from '../../../../widgets/widgets';
import { useEditModeStore } from '../../Views/useEditModeStore';
import { initializeGridstack } from './init-gridstack';
+import { useGridstackStore, useWrapperColumnCount } from './store';
interface UseGristackReturnType {
apps: AppType[];
@@ -32,7 +23,6 @@ export const useGridstack = (
areaType: 'wrapper' | 'category' | 'sidebar',
areaId: string
): UseGristackReturnType => {
- const isLargerThanSm = useScreenLargerThan('sm');
const isEditMode = useEditModeStore((x) => x.enabled);
const { config, configVersion, name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig);
@@ -42,8 +32,15 @@ export const useGridstack = (
const itemRefs = useRef>>({});
// reference of the gridstack object for modifications after initialization
const gridRef = useRef();
+ const wrapperColumnCount = useWrapperColumnCount();
+ const shapeSize = useGridstackStore((x) => x.currentShapeSize);
+ const mainAreaWidth = useGridstackStore((x) => x.mainAreaWidth);
// width of the wrapper (updating on page resize)
- const { width, height } = useResize(wrapperRef);
+ const root: HTMLHtmlElement = useMemo(() => document.querySelector(':root')!, []);
+
+ if (!mainAreaWidth || !shapeSize || !wrapperColumnCount) {
+ throw new Error('UseGridstack should not be executed before mainAreaWidth has been set!');
+ }
const items = useMemo(
() =>
@@ -77,55 +74,17 @@ export const useGridstack = (
});
}
- // change column count depending on the width and the gridRef
useEffect(() => {
- if (areaType === 'sidebar') return;
- gridRef.current?.column(
- isLargerThanSm || typeof isLargerThanSm === 'undefined' ? 12 : 6,
- (column, prevColumn, newNodes, nodes) => {
- let nextRow = 0;
- let available = 6;
+ const widgetWidth = mainAreaWidth / wrapperColumnCount;
+ // widget width is used to define sizes of gridstack items within global.scss
+ root.style.setProperty('--gridstack-widget-width', widgetWidth.toString());
+ gridRef.current?.cellHeight(widgetWidth);
+ }, [mainAreaWidth, wrapperColumnCount, gridRef.current]);
- if (column === prevColumn) {
- newNodes.concat(nodes);
- return;
- }
-
- nodes.reverse().forEach((node) => {
- const newnode = node;
- const width = parseInt(newnode.el!.getAttribute('data-gridstack-w')!, 10);
- const height = parseInt(newnode.el!.getAttribute('data-gridstack-h')!, 10);
- const x = parseInt(newnode.el!.getAttribute('data-gridstack-x')!, 10);
- const y = parseInt(newnode.el!.getAttribute('data-gridstack-y')!, 10);
-
- if (column === 6) {
- newnode.x = available >= width ? 6 - available : 0;
- newnode.y = nextRow;
-
- if (width > 6) {
- newnode.w = 6;
- nextRow += 2;
- available = 6;
- } else if (available >= width) {
- available -= width;
- if (available === 0) {
- nextRow += 2;
- available = 6;
- }
- } else if (available < width) {
- newnode.y = newnode.y! + 2;
- available = 6 - width;
- nextRow += 2;
- }
- } else {
- newnode.x = y % 2 === 1 ? x + 6 : x;
- newnode.y = Math.floor(y / 2);
- }
- newNodes.push(newnode);
- });
- }
- );
- }, [isLargerThanSm]);
+ useEffect(() => {
+ // column count is used to define count of columns of gridstack within global.scss
+ root.style.setProperty('--gridstack-column-count', wrapperColumnCount.toString());
+ }, [wrapperColumnCount]);
const onChange = isEditMode
? (changedNode: GridStackNode) => {
@@ -143,14 +102,14 @@ export const useGridstack = (
: previous.widgets.find((x) => x.id === itemId);
if (!currentItem) return previous;
- currentItem.shape = {
+ currentItem.shape[shapeSize] = {
location: {
- x: changedNode.x ?? currentItem.shape.location.x,
- y: changedNode.y ?? currentItem.shape.location.y,
+ x: changedNode.x ?? currentItem.shape[shapeSize].location.x,
+ y: changedNode.y ?? currentItem.shape[shapeSize].location.y,
},
size: {
- width: changedNode.w ?? currentItem.shape.size.width,
- height: changedNode.h ?? currentItem.shape.size.height,
+ width: changedNode.w ?? currentItem.shape[shapeSize].size.width,
+ height: changedNode.h ?? currentItem.shape[shapeSize].size.height,
},
};
@@ -209,14 +168,14 @@ export const useGridstack = (
};
}
- currentItem.shape = {
+ currentItem.shape[shapeSize] = {
location: {
- x: addedNode.x ?? currentItem.shape.location.x,
- y: addedNode.y ?? currentItem.shape.location.y,
+ x: addedNode.x ?? currentItem.shape[shapeSize].location.x,
+ y: addedNode.y ?? currentItem.shape[shapeSize].location.y,
},
size: {
- width: addedNode.w ?? currentItem.shape.size.width,
- height: addedNode.h ?? currentItem.shape.size.height,
+ width: addedNode.w ?? currentItem.shape[shapeSize].size.width,
+ height: addedNode.h ?? currentItem.shape[shapeSize].size.height,
},
};
@@ -272,7 +231,7 @@ export const useGridstack = (
: () => {};
// initialize the gridstack
- useLayoutEffect(() => {
+ useEffect(() => {
initializeGridstack(
areaType,
wrapperRef,
@@ -282,13 +241,14 @@ export const useGridstack = (
items,
widgets ?? [],
isEditMode,
- isLargerThanSm,
+ wrapperColumnCount,
+ shapeSize,
{
onChange,
onAdd,
}
);
- }, [items, wrapperRef.current, widgets]);
+ }, [items, wrapperRef.current, widgets, wrapperColumnCount]);
return {
apps: items,
diff --git a/src/components/Settings/Customization/CustomizationSettings.tsx b/src/components/Settings/Customization/CustomizationSettings.tsx
index 8265ac4a6..bc95fc785 100644
--- a/src/components/Settings/Customization/CustomizationSettings.tsx
+++ b/src/components/Settings/Customization/CustomizationSettings.tsx
@@ -1,4 +1,4 @@
-import { ScrollArea, Stack } from '@mantine/core';
+import { Button, ScrollArea, Stack } from '@mantine/core';
import { useViewportSize } from '@mantine/hooks';
import { useTranslation } from 'next-i18next';
import { useConfigContext } from '../../../config/provider';
diff --git a/src/config/store.ts b/src/config/store.ts
index 9f2fc9633..4d32ef860 100644
--- a/src/config/store.ts
+++ b/src/config/store.ts
@@ -75,7 +75,7 @@ interface UseConfigStoreType {
updateConfig: (
name: string,
updateCallback: (previous: ConfigType) => ConfigType,
- shouldRegenerateGridstace?:
+ shouldRegenerateGridstack?:
| boolean
| ((previousConfig: ConfigType, currentConfig: ConfigType) => boolean),
shouldSaveConfigToFileSystem?: boolean
diff --git a/src/hooks/use-resize.ts b/src/hooks/use-resize.ts
index 68a2d7a52..e6f632d36 100644
--- a/src/hooks/use-resize.ts
+++ b/src/hooks/use-resize.ts
@@ -1,12 +1,13 @@
-import { useCallback, useEffect, useState, MutableRefObject } from 'react';
+import { MutableRefObject, useCallback, useEffect, useState } from 'react';
-export const useResize = (myRef: MutableRefObject) => {
+export const useResize = (myRef: MutableRefObject, dependencies: any[]) => {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const handleResize = useCallback(() => {
- setWidth(myRef.current?.offsetWidth ?? 0);
- setHeight(myRef.current?.offsetHeight ?? 0);
+ if (!myRef.current) return;
+ setWidth(myRef.current.offsetWidth);
+ setHeight(myRef.current.offsetHeight);
}, [myRef]);
useEffect(() => {
@@ -19,5 +20,9 @@ export const useResize = (myRef: MutableRefObject) => {
};
}, [myRef, handleResize]);
+ useEffect(() => {
+ handleResize();
+ }, [myRef, dependencies]);
+
return { width, height };
};
diff --git a/src/modules/Docker/ContainerActionBar.tsx b/src/modules/Docker/ContainerActionBar.tsx
index 5a0ad3efd..da7388c73 100644
--- a/src/modules/Docker/ContainerActionBar.tsx
+++ b/src/modules/Docker/ContainerActionBar.tsx
@@ -190,13 +190,35 @@ export default function ContainerActionBar({ selected, reload }: ContainerAction
},
},
shape: {
- location: {
- x: 0,
- y: 0,
+ sm: {
+ location: {
+ x: 0,
+ y: 0,
+ },
+ size: {
+ width: appTileDefinition.minWidth,
+ height: appTileDefinition.minHeight,
+ },
},
- size: {
- width: appTileDefinition.minWidth,
- height: appTileDefinition.minHeight,
+ md: {
+ location: {
+ x: 0,
+ y: 0,
+ },
+ size: {
+ width: appTileDefinition.minWidth,
+ height: appTileDefinition.minHeight,
+ },
+ },
+ lg: {
+ location: {
+ x: 0,
+ y: 0,
+ },
+ size: {
+ width: appTileDefinition.minWidth,
+ height: appTileDefinition.minHeight,
+ },
},
},
integration: {
diff --git a/src/styles/global.scss b/src/styles/global.scss
index a000ae014..0c1fe9d34 100644
--- a/src/styles/global.scss
+++ b/src/styles/global.scss
@@ -1,5 +1,10 @@
@import 'fily-publish-gridstack/dist/gridstack.min.css';
+:root {
+ --gridstack-widget-width: 64;
+ --gridstack-column-count: 12;
+}
+
.grid-stack-placeholder > .placeholder-content {
background-color: rgb(248, 249, 250) !important;
border-radius: 12px;
@@ -12,27 +17,59 @@
}
}
+// Styling for grid-stack main area
@for $i from 1 to 13 {
- .grid-stack>.grid-stack-item[gs-w="#{$i}"] { width: ($i / 12) * 100 + "%" }
- .grid-stack>.grid-stack-item[gs-min-w="#{$i}"] { min-width: ($i / 12) * 100 + "%" }
- .grid-stack>.grid-stack-item[gs-max-w="#{$i}"] { max-width: ($i / 12) * 100 + "%" }
+ .grid-stack>.grid-stack-item[gs-w="#{$i}"] { width: calc(100% / #{var(--gridstack-column-count)} * #{$i}) }
+ .grid-stack>.grid-stack-item[gs-min-w="#{$i}"] { min-width: calc(100% / #{var(--gridstack-column-count)} * #{$i}) }
+ .grid-stack>.grid-stack-item[gs-max-w="#{$i}"] { max-width: calc(100% / #{var(--gridstack-column-count)} * #{$i}) }
}
@for $i from 1 to 96 {
- .grid-stack>.grid-stack-item[gs-h="#{$i}"] { height: $i * 64 + "px" }
- .grid-stack>.grid-stack-item[gs-min-h="#{$i}"] { min-height: $i * 64 + "px" }
- .grid-stack>.grid-stack-item[gs-max-h="#{$i}"] { max-height: $i * 64 + "px" }
+ .grid-stack>.grid-stack-item[gs-h="#{$i}"] { height: calc(#{$i}px * #{var(--gridstack-widget-width)}) }
+ .grid-stack>.grid-stack-item[gs-min-h="#{$i}"] { min-height: calc(#{$i}px * #{var(--gridstack-widget-width)}) }
+ .grid-stack>.grid-stack-item[gs-max-h="#{$i}"] { max-height: calc(#{$i}px * #{var(--gridstack-widget-width)}) }
}
@for $i from 1 to 13 {
- .grid-stack>.grid-stack-item[gs-x="#{$i}"] { left: ($i / 12) * 100 + "%" }
+ .grid-stack>.grid-stack-item[gs-x="#{$i}"] { left: calc(100% / #{var(--gridstack-column-count)} * #{$i}) }
}
@for $i from 1 to 96 {
- .grid-stack>.grid-stack-item[gs-y="#{$i}"] { top: $i * 64 + "px" }
+ .grid-stack>.grid-stack-item[gs-y="#{$i}"] { top: calc(#{$i}px * #{var(--gridstack-widget-width)}) }
}
+.grid-stack>.grid-stack-item {
+ min-width: calc(percentage(1) * #{var(--gridstack-widget-width)});
+}
+
+// Styling for sidebar grid-stack elements
+@for $i from 1 to 3 {
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-w="#{$i}"] { width: 128px * $i }
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-min-w="#{$i}"] { min-width: 128px * $i }
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-max-w="#{$i}"] { max-width: 128px * $i }
+}
+
+@for $i from 1 to 96 {
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-h="#{$i}"] { height: 128px * $i }
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-min-h="#{$i}"] { min-height: 128px * $i }
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-max-h="#{$i}"] { max-height: 128px * $i }
+}
+
+@for $i from 1 to 13 {
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-x="#{$i}"] { left: 128px * $i }
+}
+
+
+@for $i from 1 to 96 {
+ .grid-stack.grid-stack-sidebar>.grid-stack-item[gs-y="#{$i}"] { top: 128px * $i }
+}
+
+.grid-stack.grid-stack-sidebar>.grid-stack-item {
+ min-width: 128px;
+}
+
+// General gridstack styling
.grid-stack>.grid-stack-item>.grid-stack-item-content,
.grid-stack>.grid-stack-item>.placeholder-content {
inset: 10px;
@@ -43,10 +80,6 @@
right: 10px;
}
-.grid-stack>.grid-stack-item {
- min-width: (1/12)+'%';
-}
-
.grid-stack > .grid-stack-item > .grid-stack-item-content {
overflow-y: auto;
}
@@ -54,19 +87,3 @@
.grid-stack.grid-stack-animate {
transition: none;
}
-
-@media screen and (max-width: 768px) {
- @for $i from 1 to 7 {
- .grid-stack>.grid-stack-item[gs-w="#{$i}"] { width: percentage(($i / 6)) !important }
- .grid-stack>.grid-stack-item[gs-min-w="#{$i}"] { min-width: percentage(($i / 6)) !important }
- .grid-stack>.grid-stack-item[gs-max-w="#{$i}"] { max-width: percentage(($i / 6)) !important }
- }
-
- @for $i from 1 to 7 {
- .grid-stack>.grid-stack-item[gs-x="#{$i}"] { left: percentage(($i / 6)) }
- }
-
- .grid-stack>.grid-stack-item {
- min-width: percentage(1/6) !important;
- }
-}
\ No newline at end of file
diff --git a/src/tools/config/migrateConfig.ts b/src/tools/config/migrateConfig.ts
index 9648c1fd1..13d811523 100644
--- a/src/tools/config/migrateConfig.ts
+++ b/src/tools/config/migrateConfig.ts
@@ -92,6 +92,17 @@ const getConfigAndCreateIfNotExsists = (
return category;
};
+const getShapeForColumnCount = (index: number, columnCount: number) => ({
+ location: {
+ x: index % columnCount,
+ y: Math.floor(index / columnCount),
+ },
+ size: {
+ width: 1,
+ height: 1,
+ },
+});
+
const migrateService = (
oldService: serviceItem,
serviceIndex: number,
@@ -117,13 +128,8 @@ const migrateService = (
},
area: areaType,
shape: {
- location: {
- x: (serviceIndex * 3) % 18,
- y: Math.floor(serviceIndex / 6) * 3,
- },
- size: {
- width: 3,
- height: 3,
- },
+ lg: getShapeForColumnCount(serviceIndex, 12),
+ md: getShapeForColumnCount(serviceIndex, 6),
+ sm: getShapeForColumnCount(serviceIndex, 3),
},
});
diff --git a/src/types/shape.ts b/src/types/shape.ts
index 0bc27df0e..a8a6e6823 100644
--- a/src/types/shape.ts
+++ b/src/types/shape.ts
@@ -1,4 +1,10 @@
export interface ShapeType {
+ lg?: SizedShapeType;
+ md?: SizedShapeType;
+ sm?: SizedShapeType;
+}
+
+export interface SizedShapeType {
location: {
x: number;
y: number;
diff --git a/src/widgets/date/DateTile.tsx b/src/widgets/date/DateTile.tsx
index a7aee4fc9..5e830a792 100644
--- a/src/widgets/date/DateTile.tsx
+++ b/src/widgets/date/DateTile.tsx
@@ -17,7 +17,7 @@ const definition = defineWidget({
},
gridstack: {
minWidth: 2,
- minHeight: 2,
+ minHeight: 1,
maxWidth: 12,
maxHeight: 12,
},
diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx
index 677d4bd6c..b053a0a2a 100644
--- a/src/widgets/weather/WeatherTile.tsx
+++ b/src/widgets/weather/WeatherTile.tsx
@@ -20,7 +20,7 @@ const definition = defineWidget({
},
gridstack: {
minWidth: 2,
- minHeight: 2,
+ minHeight: 1,
maxWidth: 12,
maxHeight: 12,
},