fix: address board review and CI feedback

This commit is contained in:
ajnart committed 2026-08-14 11:32:09 +02:00
1 parent d63653142d
commit eaaeaaccdb
6 files changed
+57 -36

No files matched your search

@@ -6,8 +6,7 @@ import { TRPCError } from "@trpc/server";
import { getRscUserSettingsAsync } from "@homarr/api/user-server";
import { auth } from "@homarr/auth/next";
import { BoardProvider } from "@homarr/boards/context";
import { EditModeProvider } from "@homarr/boards/edit-mode";
import { constructBoardPermissions } from "@homarr/auth/shared";
import { boardViewportWidthCookieName, getLayoutIdForViewportWidth } from "@homarr/boards/layout-selection";
import { createLogger } from "@homarr/core/infrastructure/logs";
import { ModalProvider } from "@homarr/modals";
@@ -19,6 +18,7 @@ import { BoardTourGate } from "~/components/onboarding/board-tour-gate";
import { env } from "~/env";
import { getCurrentColorSchemeAsync } from "~/theme/color-scheme";
import type { Board } from "./_types";
import { BoardProviders } from "./_providers";
import type { Params } from "./(content)/_creator";
import { CustomCss } from "./(content)/_custom-css";
import { BoardReadyProvider } from "./(content)/_ready-context";
@@ -88,34 +88,34 @@ export const createBoardLayout = <TParams extends Params>({
throw error;
}
const initialBoard = initialBoardResult.board;
const { hasChangeAccess } = constructBoardPermissions(initialBoard, session);
const initialLayoutId = getLayoutIdForViewportWidth(initialBoard.layouts, initialViewportWidth);
return (
<BoardProvider
<BoardProviders
initialBoard={initialBoard}
initialLayoutId={initialLayoutId}
initialViewportWidth={initialViewportWidth}
canModify={hasChangeAccess}
>
<BoardReadyProvider>
<EditModeProvider>
<BoardMantineProvider defaultColorScheme={colorScheme}>
<ModalProvider>
<CustomCss />
<BoardTourGate enabled={shouldRunBoardTour}>
<ClientShell hasNavigation={false}>
<MainHeader
logo={<BoardLogoWithTitle size="md" hideTitleOnMobile />}
actions={headerActions}
hasNavigation={false}
/>
<AppShellMain data-advanced-focus-background>{children}</AppShellMain>
</ClientShell>
</BoardTourGate>
</ModalProvider>
</BoardMantineProvider>
</EditModeProvider>
<BoardMantineProvider defaultColorScheme={colorScheme}>
<ModalProvider>
<CustomCss />
<BoardTourGate enabled={shouldRunBoardTour}>
<ClientShell hasNavigation={false}>
<MainHeader
logo={<BoardLogoWithTitle size="md" hideTitleOnMobile />}
actions={headerActions}
hasNavigation={false}
/>
<AppShellMain data-advanced-focus-background>{children}</AppShellMain>
</ClientShell>
</BoardTourGate>
</ModalProvider>
</BoardMantineProvider>
</BoardReadyProvider>
</BoardProvider>
</BoardProviders>
);
};
@@ -1,6 +1,6 @@
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: repeat(var(--mobile-column-count), minmax(0, 1fr));
grid-auto-flow: row;
grid-auto-rows: min(calc((100vw - 42px) / 2), 12rem);
gap: 10px;
@@ -1,6 +1,6 @@
"use client";
import type { RefObject } from "react";
import type { CSSProperties, RefObject } from "react";
import { useMemo, useRef } from "react";
import { Box } from "@mantine/core";
@@ -11,19 +11,22 @@ import type { GridItemHTMLElement, GridStack as GridStackInstance } from "@homar
import { BoardItemContent } from "../items/item-content";
import { SectionProvider } from "../sections/section-context";
import classes from "./mobile-board.module.css";
import { createMobileBoardItems } from "./mobile-layout";
import { createMobileBoardItems, mobileColumnCount } from "./mobile-layout";
export const MobileBoard = () => {
const board = useRequiredBoard();
const desktopLayout = getDesktopLayout(board);
const items = useMemo(() => createMobileBoardItems(board, desktopLayout.id), [board, desktopLayout.id]);
const rootSection = board.sections.find((section) => section.kind !== "dynamic");
const rootSection = board.sections.find((section) => section.kind !== "dynamic") ?? {
id: "mobile",
kind: "empty" as const,
xOffset: 0,
yOffset: 0,
};
const wrapperRef = useRef<HTMLDivElement | null>(null);
const itemRefs = useRef<Record<string, RefObject<GridItemHTMLElement | null>>>({});
const gridstackRef = useRef<GridStackInstance | null>(null);
if (!rootSection) return null;
return (
<ReadOnlyEditModeProvider>
<SectionProvider
@@ -34,7 +37,11 @@ export const MobileBoard = () => {
refs: { wrapper: wrapperRef, items: itemRefs, gridstack: gridstackRef },
}}
>
<Box className={classes.grid} data-mobile-board>
<Box
className={classes.grid}
style={{ "--mobile-column-count": mobileColumnCount } as CSSProperties}
data-mobile-board
>
{items.map((item) => (
<Box
key={item.id}
@@ -1,6 +1,6 @@
import type { Board, DynamicSectionItem, ItemLayout, SectionItem } from "~/app/[locale]/boards/_types";
const mobileColumnCount = 2;
export const mobileColumnCount = 2;
const mobileMaxHeight = 3;
type PositionedElement = DynamicSectionItem | SectionItem;
@@ -1,7 +0,0 @@
"use client";
import { useMediaQuery } from "@mantine/hooks";
export const mobileBoardMediaQuery = "(max-width: 48em)";
export const useIsMobileBoard = () => useMediaQuery(mobileBoardMediaQuery);
@@ -0,0 +1,21 @@
"use client";
import type { PropsWithChildren } from "react";
import { createContext, useContext } from "react";
import { useMediaQuery } from "@mantine/hooks";
export const mobileBoardMediaQuery = "(max-width: 48em)";
const InitialMobileBoardContext = createContext<boolean | undefined>(undefined);
export const MobileBoardViewportProvider = ({
initialIsMobile,
children,
}: PropsWithChildren<{ initialIsMobile: boolean }>) => (
<InitialMobileBoardContext.Provider value={initialIsMobile}>{children}</InitialMobileBoardContext.Provider>
);
export const useIsMobileBoard = () => {
const initialIsMobile = useContext(InitialMobileBoardContext);
return useMediaQuery(mobileBoardMediaQuery, initialIsMobile, { getInitialValueInEffect: true });
};