diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx index 0f3454653..e9551af52 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx @@ -5,7 +5,7 @@ import { Box, LoadingOverlay, Stack } from "@mantine/core"; import type { RouterOutputs } from "@homarr/api"; import { clientApi } from "@homarr/api/client"; -import { useRequiredBoard } from "@homarr/boards/context"; +import { useCurrentLayout, useRequiredBoard } from "@homarr/boards/context"; import { BoardCategorySection } from "~/components/board/sections/category-section"; import { BoardEmptySection } from "~/components/board/sections/empty-section"; @@ -43,6 +43,7 @@ export const useUpdateBoard = () => { export const ClientBoard = () => { const board = useRequiredBoard(); + const currentLayoutId = useCurrentLayout(); const isReady = useIsBoardReady(); const fullWidthSortedSections = board.sections @@ -63,9 +64,10 @@ export const ClientBoard = () => { {fullWidthSortedSections.map((section) => section.kind === "empty" ? ( - + // Unique keys per layout to always reinitialize the gridstack + ) : ( - + ), )} diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx index f501e95f9..49be8c37c 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx @@ -13,7 +13,7 @@ import { getI18n } from "@homarr/translation/server"; import { createMetaTitle } from "~/metadata"; import { createBoardLayout } from "../_layout-creator"; import type { Board } from "../_types"; -import { ClientBoard } from "./_client"; +import { DynamicClientBoard } from "./_dynamic-client"; import { BoardContentHeaderActions } from "./_header-actions"; export type Params = Record; @@ -37,7 +37,7 @@ export const createBoardContentPage = >( return ( - + ); }, diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_dynamic-client.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_dynamic-client.tsx new file mode 100644 index 000000000..50b0aff66 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_dynamic-client.tsx @@ -0,0 +1,7 @@ +"use client"; + +import dynamic from "next/dynamic"; + +export const DynamicClientBoard = dynamic(() => import("./_client").then((mod) => mod.ClientBoard), { + ssr: false, +}); diff --git a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_layout.tsx b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_layout.tsx index f0c2eeb9f..99c0a7f41 100644 --- a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_layout.tsx +++ b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_layout.tsx @@ -1,43 +1,109 @@ "use client"; -import { Button, Grid, Group, Input, Slider, Stack } from "@mantine/core"; +import { Button, Fieldset, Grid, Group, Input, NumberInput, Slider, Stack, Text, TextInput } from "@mantine/core"; +import { clientApi } from "@homarr/api/client"; +import { createId } from "@homarr/db/client"; import { useZodForm } from "@homarr/form"; import { useI18n } from "@homarr/translation/client"; import { validation } from "@homarr/validation"; import type { Board } from "../../_types"; -import { useSavePartialSettingsMutation } from "./_shared"; interface Props { board: Board; } export const LayoutSettingsContent = ({ board }: Props) => { const t = useI18n(); - const { mutate: savePartialSettings, isPending } = useSavePartialSettingsMutation(board); - const form = useZodForm(validation.board.savePartialSettings.pick({ columnCount: true }).required(), { + const utils = clientApi.useUtils(); + const { mutate: saveLayouts, isPending } = clientApi.board.saveLayouts.useMutation({ + onSettled() { + void utils.board.getBoardByName.invalidate({ name: board.name }); + void utils.board.getHomeBoard.invalidate(); + }, + }); + const form = useZodForm(validation.board.saveLayouts.omit({ id: true }).required(), { initialValues: { - columnCount: board.columnCount, + layouts: board.layouts, }, }); return (
{ - savePartialSettings({ + saveLayouts({ id: board.id, ...values, }); })} > - - - - - - - + + + {t("board.setting.section.layout.responsive.title")} + + + + {form.values.layouts.map((layout, index) => ( +
+ + + + + + + + + + + + + + + + {form.values.layouts.length >= 2 && ( + + + + )} +
+ ))} +
+