63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
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 { getFirstEmptyPosition } from "./empty-position";
|
|
|
|
export interface CreateItemInput {
|
|
kind: WidgetKind;
|
|
}
|
|
|
|
export const createItemCallback =
|
|
({ kind }: CreateItemInput) =>
|
|
(previous: Board): Board => {
|
|
const firstSection = previous.sections
|
|
.filter((section): section is EmptySection => section.kind === "empty")
|
|
.sort((sectionA, sectionB) => sectionA.yOffset - sectionB.yOffset)
|
|
.at(0);
|
|
|
|
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,
|
|
integrationIds: [],
|
|
advancedOptions: {
|
|
customCssClasses: [],
|
|
},
|
|
} satisfies Modify<
|
|
Item,
|
|
{
|
|
kind: WidgetKind;
|
|
}
|
|
>;
|
|
|
|
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),
|
|
};
|
|
}),
|
|
};
|
|
};
|