Files
klz-cables.com/.pnpm-store/v10/files/9b/6994c1bfa82c103963d7d8b6d07bf2004f0349a8aa76746bfb18eeb5c2535db8c5ff2f1e88977af4738bce49b233eac96fc869bafa5865a11a54d459d79281
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

517 lines
17 KiB
Plaintext

'use client';
import { c as _c } from "react/compiler-runtime";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useModal } from '@faceless-ui/modal';
import { formatAdminURL, isImage } from 'payload/shared';
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react';
import { toast } from 'sonner';
import { FieldError } from '../../fields/FieldError/index.js';
import { fieldBaseClass } from '../../fields/shared/index.js';
import { useForm, useFormProcessing } from '../../forms/Form/index.js';
import { useField } from '../../forms/useField/index.js';
import { useConfig } from '../../providers/Config/index.js';
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js';
import { EditDepthProvider } from '../../providers/EditDepth/index.js';
import { useTranslation } from '../../providers/Translation/index.js';
import { UploadControlsProvider, useUploadControls } from '../../providers/UploadControls/index.js';
import { useUploadEdits } from '../../providers/UploadEdits/index.js';
import { Button } from '../Button/index.js';
import { Drawer } from '../Drawer/index.js';
import { Dropzone } from '../Dropzone/index.js';
import { EditUpload } from '../EditUpload/index.js';
import './index.scss';
import { FileDetails } from '../FileDetails/index.js';
import { PreviewSizes } from '../PreviewSizes/index.js';
import { Thumbnail } from '../Thumbnail/index.js';
const baseClass = 'file-field';
export const editDrawerSlug = 'edit-upload';
export const sizePreviewSlug = 'preview-sizes';
const validate = value => {
if (!value && value !== undefined) {
return 'A file is required.';
}
if (value && (!value.name || value.name === '')) {
return 'A file name is required.';
}
return true;
};
export const UploadActions = t0 => {
const $ = _c(8);
const {
customActions,
enableAdjustments,
enablePreviewSizes,
mimeType
} = t0;
const {
t
} = useTranslation();
const {
openModal
} = useModal();
let t1;
let t2;
if ($[0] !== customActions || $[1] !== enableAdjustments || $[2] !== enablePreviewSizes || $[3] !== mimeType || $[4] !== openModal || $[5] !== t) {
t2 = Symbol.for("react.early_return_sentinel");
bb0: {
const fileTypeIsAdjustable = isImage(mimeType) && mimeType !== "image/svg+xml" && mimeType !== "image/jxl";
if (!fileTypeIsAdjustable && (!customActions || customActions.length === 0)) {
t2 = null;
break bb0;
}
t1 = _jsxs("div", {
className: `${baseClass}__upload-actions`,
children: [fileTypeIsAdjustable && _jsxs(React.Fragment, {
children: [enablePreviewSizes && _jsx(Button, {
buttonStyle: "pill",
className: `${baseClass}__previewSizes`,
margin: false,
onClick: () => {
openModal(sizePreviewSlug);
},
size: "small",
children: t("upload:previewSizes")
}), enableAdjustments && _jsx(Button, {
buttonStyle: "pill",
className: `${baseClass}__edit`,
margin: false,
onClick: () => {
openModal(editDrawerSlug);
},
size: "small",
children: t("upload:editImage")
})]
}), customActions && customActions.map(_temp)]
});
}
$[0] = customActions;
$[1] = enableAdjustments;
$[2] = enablePreviewSizes;
$[3] = mimeType;
$[4] = openModal;
$[5] = t;
$[6] = t1;
$[7] = t2;
} else {
t1 = $[6];
t2 = $[7];
}
if (t2 !== Symbol.for("react.early_return_sentinel")) {
return t2;
}
return t1;
};
export const Upload = props => {
const $ = _c(5);
const {
resetUploadEdits,
updateUploadEdits,
uploadEdits
} = useUploadEdits();
let t0;
if ($[0] !== props || $[1] !== resetUploadEdits || $[2] !== updateUploadEdits || $[3] !== uploadEdits) {
t0 = _jsx(UploadControlsProvider, {
children: _jsx(Upload_v4, {
...props,
resetUploadEdits,
updateUploadEdits,
uploadEdits
})
});
$[0] = props;
$[1] = resetUploadEdits;
$[2] = updateUploadEdits;
$[3] = uploadEdits;
$[4] = t0;
} else {
t0 = $[4];
}
return t0;
};
export const Upload_v4 = props => {
const {
collectionSlug,
customActions,
initialState,
onChange,
resetUploadEdits,
updateUploadEdits,
uploadConfig,
UploadControls,
uploadEdits
} = props;
const {
setUploadControlFile,
setUploadControlFileName,
setUploadControlFileUrl,
uploadControlFile,
uploadControlFileName,
uploadControlFileUrl
} = useUploadControls();
const {
config: {
routes: {
api
}
}
} = useConfig();
const {
t
} = useTranslation();
const {
setModified
} = useForm();
const {
id,
data,
docPermissions,
setUploadStatus
} = useDocumentInfo();
const isFormSubmitting = useFormProcessing();
const {
errorMessage,
setValue,
showError,
value
} = useField({
path: 'file',
validate
});
const [fileSrc, setFileSrc] = useState(null);
const [removedFile, setRemovedFile] = useState(false);
const [filename, setFilename] = useState(value?.name || '');
const [showUrlInput, setShowUrlInput] = useState(false);
const [fileUrl, setFileUrl] = useState('');
const urlInputRef = useRef(null);
const inputRef = useRef(null);
const useServerSideFetch = typeof uploadConfig?.pasteURL === 'object' && uploadConfig.pasteURL.allowList?.length > 0;
const handleFileChange = useCallback(({
file,
isNewFile = true
}) => {
if (isNewFile && file instanceof File) {
setFileSrc(URL.createObjectURL(file));
}
setValue(file);
setShowUrlInput(false);
setUploadControlFileUrl('');
setUploadControlFileName(null);
setUploadControlFile(null);
if (typeof onChange === 'function') {
onChange(file);
}
}, [onChange, setValue, setUploadControlFile, setUploadControlFileName, setUploadControlFileUrl]);
const renameFile = (fileToChange, newName) => {
// Creating a new File object with updated properties
const newFile = new File([fileToChange], newName, {
type: fileToChange.type,
lastModified: fileToChange.lastModified
});
return newFile;
};
const handleFileNameChange = React.useCallback(e => {
const updatedFileName = e.target.value;
if (value) {
handleFileChange({
file: renameFile(value, updatedFileName),
isNewFile: false
});
setFilename(updatedFileName);
}
}, [handleFileChange, value]);
const handleFileSelection = useCallback(files => {
const fileToUpload = files?.[0];
handleFileChange({
file: fileToUpload
});
}, [handleFileChange]);
const handleFileRemoval = useCallback(() => {
setRemovedFile(true);
handleFileChange({
file: null
});
setFileSrc('');
setFileUrl('');
resetUploadEdits();
setShowUrlInput(false);
setUploadControlFileUrl('');
setUploadControlFileName(null);
setUploadControlFile(null);
}, [handleFileChange, resetUploadEdits, setUploadControlFile, setUploadControlFileName, setUploadControlFileUrl]);
const onEditsSave = useCallback(args => {
setModified(true);
updateUploadEdits(args);
}, [setModified, updateUploadEdits]);
const handleUrlSubmit = useCallback(async () => {
if (!fileUrl || uploadConfig?.pasteURL === false) {
return;
}
setUploadStatus('uploading');
try {
// Attempt client-side fetch
const clientResponse = await fetch(fileUrl);
if (!clientResponse.ok) {
throw new Error(`Fetch failed with status: ${clientResponse.status}`);
}
const blob = await clientResponse.blob();
const fileName = uploadControlFileName || decodeURIComponent(fileUrl.split('/').pop() || '');
const file_0 = new File([blob], fileName, {
type: blob.type
});
handleFileChange({
file: file_0
});
setUploadStatus('idle');
return; // Exit if client-side fetch succeeds
} catch (_clientError) {
if (!useServerSideFetch) {
// If server-side fetch is not enabled, show client-side error
toast.error('Failed to fetch the file.');
setUploadStatus('failed');
return;
}
}
// Attempt server-side fetch if client-side fetch fails and useServerSideFetch is true
try {
const pasteURL = `/${collectionSlug}/paste-url${id ? `/${id}?` : '?'}src=${encodeURIComponent(fileUrl)}`;
const serverResponse = await fetch(formatAdminURL({
apiRoute: api,
path: pasteURL
}));
if (!serverResponse.ok) {
throw new Error(`Fetch failed with status: ${serverResponse.status}`);
}
const blob_0 = await serverResponse.blob();
const fileName_0 = decodeURIComponent(fileUrl.split('/').pop() || '');
const file_1 = new File([blob_0], fileName_0, {
type: blob_0.type
});
handleFileChange({
file: file_1
});
setUploadStatus('idle');
} catch (_serverError) {
toast.error('The provided URL is not allowed.');
setUploadStatus('failed');
}
}, [api, collectionSlug, fileUrl, handleFileChange, id, setUploadStatus, uploadConfig, uploadControlFileName, useServerSideFetch]);
useEffect(() => {
if (initialState?.file?.value instanceof File) {
setFileSrc(URL.createObjectURL(initialState.file.value));
setRemovedFile(false);
}
}, [initialState]);
useEffect(() => {
if (showUrlInput && urlInputRef.current) {
// urlInputRef.current.focus() // Focus on the remote-url input field when showUrlInput is true
}
}, [showUrlInput]);
useEffect(() => {
if (isFormSubmitting) {
setRemovedFile(false);
}
}, [isFormSubmitting]);
const canRemoveUpload = docPermissions?.update;
const hasImageSizes = uploadConfig?.imageSizes?.length > 0;
const hasResizeOptions = Boolean(uploadConfig?.resizeOptions);
// Explicity check if set to true, default is undefined
const focalPointEnabled = uploadConfig?.focalPoint === true;
const {
crop: showCrop = true,
focalPoint = true
} = uploadConfig;
const showFocalPoint = focalPoint && (hasImageSizes || hasResizeOptions || focalPointEnabled);
const acceptMimeTypes = uploadConfig.mimeTypes?.join(', ');
const imageCacheTag = uploadConfig?.cacheTags && data?.updatedAt;
useEffect(() => {
const handleControlFileUrl = async () => {
if (uploadControlFileUrl) {
setFileUrl(uploadControlFileUrl);
await handleUrlSubmit();
}
};
void handleControlFileUrl();
}, [uploadControlFileUrl, handleUrlSubmit]);
useEffect(() => {
const handleControlFile = () => {
if (uploadControlFile) {
handleFileChange({
file: uploadControlFile
});
}
};
void handleControlFile();
}, [uploadControlFile, handleFileChange]);
return /*#__PURE__*/_jsxs("div", {
className: [fieldBaseClass, baseClass].filter(Boolean).join(' '),
children: [/*#__PURE__*/_jsx(FieldError, {
message: errorMessage,
showError: showError
}), data && data.filename && !removedFile && /*#__PURE__*/_jsx(FileDetails, {
collectionSlug: collectionSlug,
customUploadActions: customActions,
doc: data,
enableAdjustments: showCrop || showFocalPoint,
handleRemove: canRemoveUpload ? handleFileRemoval : undefined,
hasImageSizes: hasImageSizes,
hideRemoveFile: uploadConfig.hideRemoveFile,
imageCacheTag: imageCacheTag,
uploadConfig: uploadConfig
}), (!uploadConfig.hideFileInputOnCreate && !data?.filename || removedFile) && /*#__PURE__*/_jsxs("div", {
className: `${baseClass}__upload`,
children: [!value && !showUrlInput && /*#__PURE__*/_jsx(Dropzone, {
onChange: handleFileSelection,
children: /*#__PURE__*/_jsxs("div", {
className: `${baseClass}__dropzoneContent`,
children: [/*#__PURE__*/_jsxs("div", {
className: `${baseClass}__dropzoneButtons`,
children: [/*#__PURE__*/_jsx(Button, {
buttonStyle: "pill",
onClick: () => {
if (inputRef.current) {
inputRef.current.click();
}
},
size: "small",
children: t('upload:selectFile')
}), /*#__PURE__*/_jsx("input", {
accept: acceptMimeTypes,
"aria-hidden": "true",
className: `${baseClass}__hidden-input`,
hidden: true,
onChange: e_0 => {
if (e_0.target.files && e_0.target.files.length > 0) {
handleFileSelection(e_0.target.files);
}
},
ref: inputRef,
type: "file"
}), uploadConfig?.pasteURL !== false && /*#__PURE__*/_jsxs(Fragment, {
children: [/*#__PURE__*/_jsx("span", {
className: `${baseClass}__orText`,
children: t('general:or')
}), /*#__PURE__*/_jsx(Button, {
buttonStyle: "pill",
onClick: () => {
setShowUrlInput(true);
setUploadControlFileUrl('');
setUploadControlFile(null);
setUploadControlFileName(null);
},
size: "small",
children: t('upload:pasteURL')
})]
}), UploadControls ? UploadControls : null]
}), /*#__PURE__*/_jsxs("p", {
className: `${baseClass}__dragAndDropText`,
children: [t('general:or'), " ", t('upload:dragAndDrop')]
})]
})
}), showUrlInput && /*#__PURE__*/_jsxs(React.Fragment, {
children: [/*#__PURE__*/_jsxs("div", {
className: `${baseClass}__remote-file-wrap`,
children: [/*#__PURE__*/_jsx("input", {
className: `${baseClass}__remote-file`,
onChange: e_1 => {
setFileUrl(e_1.target.value);
},
ref: urlInputRef,
title: fileUrl,
type: "text",
value: fileUrl
}), /*#__PURE__*/_jsx("div", {
className: `${baseClass}__add-file-wrap`,
children: /*#__PURE__*/_jsx("button", {
className: `${baseClass}__add-file`,
onClick: () => {
void handleUrlSubmit();
},
type: "button",
children: t('upload:addFile')
})
})]
}), /*#__PURE__*/_jsx(Button, {
buttonStyle: "icon-label",
className: `${baseClass}__remove`,
icon: "x",
iconStyle: "with-border",
onClick: () => {
setShowUrlInput(false);
setUploadControlFileUrl('');
setUploadControlFile(null);
setUploadControlFileName(null);
},
round: true,
tooltip: t('general:cancel')
})]
}), value && fileSrc && /*#__PURE__*/_jsxs(React.Fragment, {
children: [/*#__PURE__*/_jsx("div", {
className: `${baseClass}__thumbnail-wrap`,
children: /*#__PURE__*/_jsx(Thumbnail, {
collectionSlug: collectionSlug,
fileSrc: isImage(value.type) ? fileSrc : null
})
}), /*#__PURE__*/_jsxs("div", {
className: `${baseClass}__file-adjustments`,
children: [/*#__PURE__*/_jsx("input", {
className: `${baseClass}__filename`,
onChange: handleFileNameChange,
title: filename || value.name,
type: "text",
value: filename || value.name
}), /*#__PURE__*/_jsx(UploadActions, {
customActions: customActions,
enableAdjustments: showCrop || showFocalPoint,
enablePreviewSizes: hasImageSizes && data?.filename && !removedFile,
mimeType: value.type
})]
}), /*#__PURE__*/_jsx(Button, {
buttonStyle: "icon-label",
className: `${baseClass}__remove`,
icon: "x",
iconStyle: "with-border",
onClick: handleFileRemoval,
round: true,
tooltip: t('general:cancel')
})]
})]
}), (value || data?.filename) && /*#__PURE__*/_jsx(EditDepthProvider, {
children: /*#__PURE__*/_jsx(Drawer, {
Header: null,
slug: editDrawerSlug,
children: /*#__PURE__*/_jsx(EditUpload, {
fileName: value?.name || data?.filename,
fileSrc: data?.url || fileSrc,
imageCacheTag: imageCacheTag,
initialCrop: uploadEdits?.crop ?? undefined,
initialFocalPoint: {
x: uploadEdits?.focalPoint?.x || data?.focalX || 50,
y: uploadEdits?.focalPoint?.y || data?.focalY || 50
},
onSave: onEditsSave,
showCrop: showCrop,
showFocalPoint: showFocalPoint
})
})
}), data && hasImageSizes && /*#__PURE__*/_jsx(Drawer, {
className: `${baseClass}__previewDrawer`,
hoverTitle: true,
slug: sizePreviewSlug,
title: t('upload:sizesFor', {
label: data.filename
}),
children: /*#__PURE__*/_jsx(PreviewSizes, {
doc: data,
imageCacheTag: imageCacheTag,
uploadConfig: uploadConfig
})
})]
});
};
function _temp(CustomAction, i) {
return _jsx(React.Fragment, {
children: CustomAction
}, i);
}
//# sourceMappingURL=index.js.map