feat(boards): add responsive layout system (#2271)

This commit is contained in:
Meier Lukas
2025-02-23 17:34:56 +01:00
committed by GitHub
parent 2085b5ece2
commit 7761dc29c8
98 changed files with 11770 additions and 1694 deletions

View File

@@ -1,9 +1,11 @@
import { getBoardLayouts } from "@homarr/boards/context";
import type { Modify } from "@homarr/common/types";
import { createId } from "@homarr/db/client";
import type { WidgetKind } from "@homarr/definitions";
import type { Board, DynamicSection, EmptySection, Item } from "~/app/[locale]/boards/_types";
import type { Board, EmptySection, Item, ItemLayout } from "~/app/[locale]/boards/_types";
import { getFirstEmptyPosition } from "./empty-position";
import { getSectionElements } from "./section-elements";
export interface CreateItemInput {
kind: WidgetKind;
@@ -19,24 +21,11 @@ export const createItemCallback =
if (!firstSection) return previous;
const dynamicSectionsOfFirstSection = previous.sections.filter(
(section): section is DynamicSection => section.kind === "dynamic" && section.parentSectionId === firstSection.id,
);
const elements = [...firstSection.items, ...dynamicSectionsOfFirstSection];
const emptyPosition = getFirstEmptyPosition(elements, previous.columnCount);
if (!emptyPosition) {
console.error("Your board is full");
return previous;
}
const widget = {
id: createId(),
kind,
options: {},
width: 1,
height: 1,
...emptyPosition,
layouts: createItemLayouts(previous, firstSection),
integrationIds: [],
advancedOptions: {
customCssClasses: [],
@@ -50,13 +39,31 @@ export const createItemCallback =
return {
...previous,
sections: previous.sections.map((section) => {
// Return same section if item is not in it
if (section.id !== firstSection.id) return section;
return {
...section,
items: section.items.concat(widget),
};
}),
items: previous.items.concat(widget),
};
};
const createItemLayouts = (board: Board, currentSection: EmptySection): ItemLayout[] => {
const layouts = getBoardLayouts(board);
return layouts.map((layoutId) => {
const boardLayout = board.layouts.find((layout) => layout.id === layoutId);
const elements = getSectionElements(board, { sectionId: currentSection.id, layoutId });
const emptyPosition = boardLayout
? getFirstEmptyPosition(elements, boardLayout.columnCount)
: { xOffset: 0, yOffset: 0 };
if (!emptyPosition) {
throw new Error("Your board is full");
}
return {
width: 1,
height: 1,
...emptyPosition,
sectionId: currentSection.id,
layoutId,
};
});
};