-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
1 parent
49c0ebe
commit 326b769
Showing
42 changed files
with
599 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
apps/nextjs/src/app/[locale]/manage/settings/_components/appearance-settings-form.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"use client"; | ||
|
||
import { Group, Text } from "@mantine/core"; | ||
import { IconMoon, IconSun } from "@tabler/icons-react"; | ||
|
||
import type { ColorScheme } from "@homarr/definitions"; | ||
import { colorSchemes } from "@homarr/definitions"; | ||
import type { ServerSettings } from "@homarr/server-settings"; | ||
import { useScopedI18n } from "@homarr/translation/client"; | ||
import { SelectWithCustomItems } from "@homarr/ui"; | ||
|
||
import { CommonSettingsForm } from "./common-form"; | ||
|
||
export const AppearanceSettingsForm = ({ defaultValues }: { defaultValues: ServerSettings["appearance"] }) => { | ||
const tApperance = useScopedI18n("management.page.settings.section.appearance"); | ||
|
||
return ( | ||
<CommonSettingsForm settingKey="appearance" defaultValues={defaultValues}> | ||
{(form) => ( | ||
<> | ||
<SelectWithCustomItems | ||
label={tApperance("defaultColorScheme.label")} | ||
data={colorSchemes.map((scheme) => ({ | ||
value: scheme, | ||
label: tApperance(`defaultColorScheme.options.${scheme}`), | ||
}))} | ||
{...form.getInputProps("defaultColorScheme")} | ||
SelectOption={ApperanceCustomOption} | ||
/> | ||
</> | ||
)} | ||
</CommonSettingsForm> | ||
); | ||
}; | ||
|
||
const appearanceIcons = { | ||
light: IconSun, | ||
dark: IconMoon, | ||
}; | ||
|
||
const ApperanceCustomOption = ({ value, label }: { value: ColorScheme; label: string }) => { | ||
const Icon = appearanceIcons[value]; | ||
|
||
return ( | ||
<Group> | ||
<Icon size={16} stroke={1.5} /> | ||
<Text fz="sm" fw={500}> | ||
{label} | ||
</Text> | ||
</Group> | ||
); | ||
}; |
44 changes: 44 additions & 0 deletions
44
apps/nextjs/src/app/[locale]/manage/settings/_components/board-settings-form.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"use client"; | ||
|
||
import { Group, Text } from "@mantine/core"; | ||
import { IconLayoutDashboard } from "@tabler/icons-react"; | ||
|
||
import { clientApi } from "@homarr/api/client"; | ||
import type { ServerSettings } from "@homarr/server-settings"; | ||
import { useScopedI18n } from "@homarr/translation/client"; | ||
import { SelectWithCustomItems } from "@homarr/ui"; | ||
|
||
import { CommonSettingsForm } from "./common-form"; | ||
|
||
export const BoardSettingsForm = ({ defaultValues }: { defaultValues: ServerSettings["board"] }) => { | ||
const tBoard = useScopedI18n("management.page.settings.section.board"); | ||
const [selectableBoards] = clientApi.board.getPublicBoards.useSuspenseQuery(); | ||
|
||
return ( | ||
<CommonSettingsForm settingKey="board" defaultValues={defaultValues}> | ||
{(form) => ( | ||
<> | ||
<SelectWithCustomItems | ||
label={tBoard("defaultBoard.label")} | ||
description={tBoard("defaultBoard.description")} | ||
data={selectableBoards.map((board) => ({ | ||
value: board.id, | ||
label: board.name, | ||
image: board.logoImageUrl, | ||
}))} | ||
SelectOption={({ label, image }: { value: string; label: string; image: string | null }) => ( | ||
<Group> | ||
{/* eslint-disable-next-line @next/next/no-img-element */} | ||
{image ? <img width={16} height={16} src={image} alt={label} /> : <IconLayoutDashboard size={16} />} | ||
<Text fz="sm" fw={500}> | ||
{label} | ||
</Text> | ||
</Group> | ||
)} | ||
{...form.getInputProps("defaultBoardId")} | ||
/> | ||
</> | ||
)} | ||
</CommonSettingsForm> | ||
); | ||
}; |
57 changes: 57 additions & 0 deletions
57
apps/nextjs/src/app/[locale]/manage/settings/_components/common-form.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
"use client"; | ||
|
||
import { Button, Group, Stack } from "@mantine/core"; | ||
|
||
import { clientApi } from "@homarr/api/client"; | ||
import { useForm } from "@homarr/form"; | ||
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications"; | ||
import type { ServerSettings } from "@homarr/server-settings"; | ||
import { useI18n, useScopedI18n } from "@homarr/translation/client"; | ||
|
||
export const CommonSettingsForm = <TKey extends keyof ServerSettings>({ | ||
settingKey, | ||
defaultValues, | ||
children, | ||
}: { | ||
settingKey: TKey; | ||
defaultValues: ServerSettings[TKey]; | ||
children: (form: ReturnType<typeof useForm<ServerSettings[TKey]>>) => React.ReactNode; | ||
}) => { | ||
const t = useI18n(); | ||
const tSettings = useScopedI18n("management.page.settings"); | ||
const { mutateAsync, isPending } = clientApi.serverSettings.saveSettings.useMutation({ | ||
onSuccess() { | ||
showSuccessNotification({ | ||
message: tSettings("notification.success.message"), | ||
}); | ||
}, | ||
onError() { | ||
showErrorNotification({ | ||
message: tSettings("notification.error.message"), | ||
}); | ||
}, | ||
}); | ||
const form = useForm({ | ||
initialValues: defaultValues, | ||
}); | ||
|
||
const handleSubmitAsync = async (values: ServerSettings[TKey]) => { | ||
await mutateAsync({ | ||
settingsKey: settingKey, | ||
value: values, | ||
}); | ||
}; | ||
|
||
return ( | ||
<form onSubmit={form.onSubmit((values) => void handleSubmitAsync(values))}> | ||
<Stack gap="sm"> | ||
{children(form)} | ||
<Group justify="end"> | ||
<Button type="submit" loading={isPending}> | ||
{t("common.action.save")} | ||
</Button> | ||
</Group> | ||
</Stack> | ||
</form> | ||
); | ||
}; |
Oops, something went wrong.