feat: add server settings for default board, default color scheme and default locale (#1373)

* feat: add server settings for default board, default color scheme and default locale

* chore: address pull request feedback

* test: adjust unit tests to match requirements

* fix: deepsource issue

* chore: add deepsource as dependency to translation library

* refactor: restructure language-combobox, adjust default locale for next-intl

* chore: change cookie keys prefix from homarr- to homarr.
This commit is contained in:
Meier Lukas
2024-11-02 21:15:46 +01:00
committed by GitHub
parent 49c0ebea6d
commit 326b769c23
42 changed files with 599 additions and 214 deletions

View File

@@ -4,10 +4,17 @@ import type { PropsWithChildren } from "react";
import type { MantineColorsTuple } from "@mantine/core";
import { createTheme, darken, lighten, MantineProvider } from "@mantine/core";
import type { ColorScheme } from "@homarr/definitions";
import { useColorSchemeManager } from "../../_client-providers/mantine";
import { useRequiredBoard } from "./_context";
export const BoardMantineProvider = ({ children }: PropsWithChildren) => {
export const BoardMantineProvider = ({
children,
defaultColorScheme,
}: PropsWithChildren<{ defaultColorScheme: ColorScheme }>) => {
const board = useRequiredBoard();
const colorSchemeManager = useColorSchemeManager();
const theme = createTheme({
colors: {
@@ -18,7 +25,11 @@ export const BoardMantineProvider = ({ children }: PropsWithChildren) => {
autoContrast: true,
});
return <MantineProvider theme={theme}>{children}</MantineProvider>;
return (
<MantineProvider defaultColorScheme={defaultColorScheme} theme={theme} colorSchemeManager={colorSchemeManager}>
{children}
</MantineProvider>
);
};
export const generateColors = (hex: string) => {

View File

@@ -12,7 +12,7 @@ import { BoardRenameModal } from "~/components/board/modals/board-rename-modal";
import { useRequiredBoard } from "../../(content)/_context";
import classes from "./danger.module.css";
export const DangerZoneSettingsContent = () => {
export const DangerZoneSettingsContent = ({ hideVisibility }: { hideVisibility: boolean }) => {
const board = useRequiredBoard();
const t = useScopedI18n("board.setting");
const router = useRouter();
@@ -90,14 +90,18 @@ export const DangerZoneSettingsContent = () => {
buttonText={t("section.dangerZone.action.rename.button")}
onClick={onRenameClick}
/>
<Divider />
<DangerZoneRow
label={t("section.dangerZone.action.visibility.label")}
description={t(`section.dangerZone.action.visibility.description.${visibility}`)}
buttonText={t(`section.dangerZone.action.visibility.button.${visibility}`)}
onClick={onVisibilityClick}
isPending={isChangeVisibilityPending}
/>
{hideVisibility ? null : (
<>
<Divider />
<DangerZoneRow
label={t("section.dangerZone.action.visibility.label")}
description={t(`section.dangerZone.action.visibility.description.${visibility}`)}
buttonText={t(`section.dangerZone.action.visibility.button.${visibility}`)}
onClick={onVisibilityClick}
isPending={isChangeVisibilityPending}
/>
</>
)}
<Divider />
<DangerZoneRow
label={t("section.dangerZone.action.delete.label")}

View File

@@ -14,6 +14,8 @@ import { TRPCError } from "@trpc/server";
import { api } from "@homarr/api/server";
import { capitalize } from "@homarr/common";
import { db } from "@homarr/db";
import { getServerSettingByKeyAsync } from "@homarr/db/queries";
import type { TranslationObject } from "@homarr/translation";
import { getScopedI18n } from "@homarr/translation/server";
import type { TablerIcon } from "@homarr/ui";
@@ -63,6 +65,7 @@ const getBoardAndPermissionsAsync = async (params: Props["params"]) => {
export default async function BoardSettingsPage({ params, searchParams }: Props) {
const { board, permissions } = await getBoardAndPermissionsAsync(params);
const boardSettings = await getServerSettingByKeyAsync(db, "board");
const { hasFullAccess } = await getBoardPermissionsAsync(board);
const t = await getScopedI18n("board.setting");
@@ -92,7 +95,7 @@ export default async function BoardSettingsPage({ params, searchParams }: Props)
<BoardAccessSettings board={board} initialPermissions={permissions} />
</AccordionItemFor>
<AccordionItemFor value="dangerZone" icon={IconAlertTriangle} danger noPadding>
<DangerZoneSettingsContent />
<DangerZoneSettingsContent hideVisibility={boardSettings.defaultBoardId === board.id} />
</AccordionItemFor>
</>
)}

View File

@@ -8,6 +8,7 @@ import { logger } from "@homarr/log";
import { MainHeader } from "~/components/layout/header";
import { BoardLogoWithTitle } from "~/components/layout/logo/board-logo";
import { ClientShell } from "~/components/layout/shell";
import { getCurrentColorSchemeAsync } from "~/theme/color-scheme";
import type { Board } from "./_types";
import { BoardProvider } from "./(content)/_context";
import type { Params } from "./(content)/_creator";
@@ -37,10 +38,11 @@ export const createBoardLayout = <TParams extends Params>({
throw error;
});
const colorScheme = await getCurrentColorSchemeAsync();
return (
<BoardProvider initialBoard={initialBoard}>
<BoardMantineProvider>
<BoardMantineProvider defaultColorScheme={colorScheme}>
<CustomCss />
<ClientShell hasNavigation={false}>
<MainHeader