fix(boards): add missing upload button for background in settings (#2853)

This commit is contained in:
Meier Lukas
2025-04-11 20:17:10 +02:00
committed by GitHub
parent 93bd09c85e
commit 4baec7e3ff

View File

@@ -1,13 +1,15 @@
"use client"; "use client";
import { Autocomplete, Button, Center, Grid, Group, Popover, Stack, Text } from "@mantine/core"; import { startTransition } from "react";
import { ActionIcon, Autocomplete, Button, Center, Grid, Group, Popover, Stack, Text } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks"; import { useDebouncedValue } from "@mantine/hooks";
import { IconPhotoOff } from "@tabler/icons-react"; import { IconPhotoOff, IconUpload } from "@tabler/icons-react";
import { clientApi } from "@homarr/api/client"; import { clientApi } from "@homarr/api/client";
import { useSession } from "@homarr/auth/client"; import { useSession } from "@homarr/auth/client";
import { backgroundImageAttachments, backgroundImageRepeats, backgroundImageSizes } from "@homarr/definitions"; import { backgroundImageAttachments, backgroundImageRepeats, backgroundImageSizes } from "@homarr/definitions";
import { useZodForm } from "@homarr/form"; import { useZodForm } from "@homarr/form";
import { UploadMedia } from "@homarr/forms-collection";
import type { TranslationObject } from "@homarr/translation"; import type { TranslationObject } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client"; import { useI18n } from "@homarr/translation/client";
import type { SelectItemWithDescriptionBadge } from "@homarr/ui"; import type { SelectItemWithDescriptionBadge } from "@homarr/ui";
@@ -62,58 +64,76 @@ export const BackgroundSettingsContent = ({ board }: Props) => {
<Stack> <Stack>
<Grid> <Grid>
<Grid.Col span={12}> <Grid.Col span={12}>
<Autocomplete <Group wrap="nowrap" gap="xs" w="100%" align="start">
leftSection={ <Autocomplete
form.values.backgroundImageUrl && flex={1}
form.values.backgroundImageUrl.trim().length >= 2 && ( leftSection={
<Popover width={300} withArrow> form.values.backgroundImageUrl &&
<Popover.Target> form.values.backgroundImageUrl.trim().length >= 2 && (
<Center h="100%"> <Popover width={300} withArrow>
<ImagePreview src={form.values.backgroundImageUrl} w={20} h={20} /> <Popover.Target>
</Center> <Center h="100%">
</Popover.Target> <ImagePreview src={form.values.backgroundImageUrl} w={20} h={20} />
<Popover.Dropdown> </Center>
<ImagePreview src={form.values.backgroundImageUrl} w="100%" /> </Popover.Target>
</Popover.Dropdown> <Popover.Dropdown>
</Popover> <ImagePreview src={form.values.backgroundImageUrl} w="100%" />
) </Popover.Dropdown>
} </Popover>
// We filter it on the server )
filter={({ options }) => options} }
label={t("board.field.backgroundImageUrl.label")} // We filter it on the server
placeholder={`${t("board.field.backgroundImageUrl.placeholder")}...`} filter={({ options }) => options}
renderOption={({ option }) => { label={t("board.field.backgroundImageUrl.label")}
const current = imageMap.get(option.value); placeholder={`${t("board.field.backgroundImageUrl.placeholder")}...`}
if (!current) return null; renderOption={({ option }) => {
const current = imageMap.get(option.value);
if (!current) return null;
return ( return (
<Group gap="sm"> <Group gap="sm">
<ImagePreview src={option.value} w={20} h={20} /> <ImagePreview src={option.value} w={20} h={20} />
<Stack gap={0}> <Stack gap={0}>
<Text size="sm">{current.name}</Text> <Text size="sm">{current.name}</Text>
<Text size="xs" c="dimmed"> <Text size="xs" c="dimmed">
{option.value} {option.value}
</Text> </Text>
</Stack> </Stack>
</Group> </Group>
); );
}} }}
data={[ data={[
{ {
group: t("board.field.backgroundImageUrl.group.your"), group: t("board.field.backgroundImageUrl.group.your"),
items: images items: images
.filter((media) => media.creatorId === session?.user.id) .filter((media) => media.creatorId === session?.user.id)
.map((media) => `/api/user-medias/${media.id}`), .map((media) => `/api/user-medias/${media.id}`),
}, },
{ {
group: t("board.field.backgroundImageUrl.group.other"), group: t("board.field.backgroundImageUrl.group.other"),
items: images items: images
.filter((media) => media.creatorId !== session?.user.id) .filter((media) => media.creatorId !== session?.user.id)
.map((media) => `/api/user-medias/${media.id}`), .map((media) => `/api/user-medias/${media.id}`),
}, },
]} ]}
{...form.getInputProps("backgroundImageUrl")} {...form.getInputProps("backgroundImageUrl")}
/> />
{session?.user.permissions.includes("media-upload") && (
<UploadMedia
onSuccess={({ url }) =>
startTransition(() => {
form.setFieldValue("backgroundImageUrl", url);
})
}
>
{({ onClick, loading }) => (
<ActionIcon onClick={onClick} loading={loading} mt={24} size={36} variant="default">
<IconUpload size={16} stroke={1.5} />
</ActionIcon>
)}
</UploadMedia>
)}
</Group>
</Grid.Col> </Grid.Col>
<Grid.Col span={12}> <Grid.Col span={12}>
<SelectWithDescriptionBadge <SelectWithDescriptionBadge