feat(medias): support upload of multiple items (#4169)

This commit is contained in:
Meier Lukas
2025-10-02 19:54:40 +02:00
committed by GitHub
parent f82f343631
commit dcb845b609
6 changed files with 94 additions and 66 deletions

View File

@@ -165,11 +165,14 @@ export const IconPicker = ({
/>
{session?.user.permissions.includes("media-upload") && (
<UploadMedia
onSuccess={({ url }) => {
onSuccess={(medias) => {
const first = medias.at(0);
if (!first) return;
startTransition(() => {
setValue(url);
setPreviewUrl(url);
setSearch(url);
setValue(first.url);
setPreviewUrl(first.url);
setSearch(first.url);
});
}}
>

View File

@@ -9,27 +9,31 @@ import { supportedMediaUploadFormats } from "@homarr/validation/media";
interface UploadMediaProps {
children: (props: { onClick: () => void; loading: boolean }) => JSX.Element;
multiple?: boolean;
onSettled?: () => MaybePromise<void>;
onSuccess?: (media: { id: string; url: string }) => MaybePromise<void>;
onSuccess?: (media: { id: string; url: string }[]) => MaybePromise<void>;
}
export const UploadMedia = ({ children, onSettled, onSuccess }: UploadMediaProps) => {
export const UploadMedia = ({ children, onSettled, onSuccess, multiple = false }: UploadMediaProps) => {
const t = useI18n();
const { mutateAsync, isPending } = clientApi.media.uploadMedia.useMutation();
const handleFileUploadAsync = async (file: File | null) => {
if (!file) return;
const handleFileUploadAsync = async (files: File[] | File | null) => {
if (!files || (Array.isArray(files) && files.length === 0)) return;
const filesArray: File[] = Array.isArray(files) ? files : [files];
const formData = new FormData();
formData.append("file", file);
filesArray.forEach((file) => formData.append("files", file));
await mutateAsync(formData, {
async onSuccess(mediaId) {
async onSuccess(mediaIds) {
showSuccessNotification({
message: t("media.action.upload.notification.success.message"),
});
await onSuccess?.({
id: mediaId,
url: `/api/user-medias/${mediaId}`,
});
await onSuccess?.(
mediaIds.map((id) => ({
id,
url: `/api/user-medias/${id}`,
})),
);
},
onError() {
showErrorNotification({
@@ -43,7 +47,7 @@ export const UploadMedia = ({ children, onSettled, onSuccess }: UploadMediaProps
};
return (
<FileButton onChange={handleFileUploadAsync} accept={supportedMediaUploadFormats.join(",")}>
<FileButton onChange={handleFileUploadAsync} accept={supportedMediaUploadFormats.join(",")} multiple={multiple}>
{({ onClick }) => children({ onClick, loading: isPending })}
</FileButton>
);