Merged in release/2025-12-19 (pull request #2720)
IO-3464 Document Edit
This commit is contained in:
@@ -97,41 +97,45 @@ export function DocumentEditorLocalComponent({ imageUrl, filename, jobid }) {
|
||||
}, [triggerUpload, imageLoaded]);
|
||||
|
||||
useEffect(() => {
|
||||
// Load the image from imageUrl
|
||||
let isCancelled = false;
|
||||
if (!imageUrl) return;
|
||||
const controller = new AbortController();
|
||||
|
||||
const loadImage = async () => {
|
||||
if (!imageUrl) return;
|
||||
|
||||
setImageLoaded(false);
|
||||
setImageLoading(true);
|
||||
|
||||
try {
|
||||
const response = await axios.get(imageUrl, { responseType: "blob" });
|
||||
|
||||
if (isCancelled) return;
|
||||
|
||||
const response = await axios.get(imageUrl, { responseType: "blob", signal: controller.signal });
|
||||
const blobUrl = URL.createObjectURL(response.data);
|
||||
setLoadedImageUrl((prevUrl) => {
|
||||
if (prevUrl) URL.revokeObjectURL(prevUrl);
|
||||
return blobUrl;
|
||||
});
|
||||
} catch (error) {
|
||||
if (axios.isCancel?.(error) || error.name === "CanceledError") {
|
||||
// request was aborted — safe to ignore
|
||||
return;
|
||||
}
|
||||
console.error("Failed to fetch image blob", error);
|
||||
} finally {
|
||||
if (!isCancelled) {
|
||||
if (!controller.signal.aborted) {
|
||||
setImageLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loadImage();
|
||||
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
controller.abort();
|
||||
};
|
||||
}, [imageUrl]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (loadedImageUrl) {
|
||||
URL.revokeObjectURL(loadedImageUrl);
|
||||
}
|
||||
};
|
||||
}, [loadedImageUrl]);
|
||||
|
||||
async function b64toBlob(url) {
|
||||
const res = await fetch(url);
|
||||
return await res.blob();
|
||||
|
||||
@@ -84,45 +84,50 @@ export function DocumentEditorComponent({ currentUser, bodyshop, document }) {
|
||||
}, [triggerUpload, imageLoaded]);
|
||||
|
||||
useEffect(() => {
|
||||
// When the document changes, fetch the image via axios so auth and base URL are applied
|
||||
let isCancelled = false;
|
||||
if (!document?.id) return;
|
||||
const controller = new AbortController();
|
||||
|
||||
const loadImage = async () => {
|
||||
if (!document || !document.id) return;
|
||||
|
||||
setImageLoaded(false);
|
||||
setImageLoading(true);
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
"/media/imgproxy/original",
|
||||
{ documentId: document.id },
|
||||
{ responseType: "blob" }
|
||||
{
|
||||
responseType: "blob",
|
||||
signal: controller.signal
|
||||
}
|
||||
);
|
||||
|
||||
if (isCancelled) return;
|
||||
|
||||
const blobUrl = URL.createObjectURL(response.data);
|
||||
setImageUrl((prevUrl) => {
|
||||
if (prevUrl) URL.revokeObjectURL(prevUrl);
|
||||
return blobUrl;
|
||||
});
|
||||
} catch (error) {
|
||||
if (axios.isCancel?.(error) || error.name === "CanceledError") {
|
||||
// request was aborted — safe to ignore
|
||||
return;
|
||||
}
|
||||
console.error("Failed to fetch original image blob", error);
|
||||
} finally {
|
||||
if (!isCancelled) {
|
||||
setImageLoading(false);
|
||||
}
|
||||
setImageLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadImage();
|
||||
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
controller.abort();
|
||||
};
|
||||
}, [document]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (imageUrl) {
|
||||
URL.revokeObjectURL(imageUrl);
|
||||
}
|
||||
};
|
||||
}, [imageUrl]);
|
||||
|
||||
async function b64toBlob(url) {
|
||||
const res = await fetch(url);
|
||||
return await res.blob();
|
||||
|
||||
@@ -33,6 +33,19 @@ export function DocumentEditorContainer({ setBodyshop }) {
|
||||
nextFetchPolicy: "network-only"
|
||||
});
|
||||
|
||||
const isLocalMedia = !!dataShop?.bodyshops?.[0]?.uselocalmediaserver;
|
||||
|
||||
const {
|
||||
loading: loadingDoc,
|
||||
error: errorDoc,
|
||||
data: dataDoc
|
||||
} = useQuery(GET_DOCUMENT_BY_PK, {
|
||||
variables: { documentId },
|
||||
skip: !documentId || isLocalMedia,
|
||||
fetchPolicy: "network-only",
|
||||
nextFetchPolicy: "network-only"
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (dataShop) setBodyshop(dataShop.bodyshops[0]);
|
||||
}, [dataShop, setBodyshop]);
|
||||
@@ -40,7 +53,7 @@ export function DocumentEditorContainer({ setBodyshop }) {
|
||||
if (loadingShop) return <LoadingSpinner />;
|
||||
if (errorShop) return <AlertComponent message={errorShop.message} type="error" />;
|
||||
|
||||
if (dataShop?.bodyshops[0]?.uselocalmediaserver) {
|
||||
if (isLocalMedia) {
|
||||
if (imageUrl && filename && jobid) {
|
||||
return (
|
||||
<div>
|
||||
@@ -52,20 +65,13 @@ export function DocumentEditorContainer({ setBodyshop }) {
|
||||
}
|
||||
}
|
||||
|
||||
const { loading, error, data } = useQuery(GET_DOCUMENT_BY_PK, {
|
||||
variables: { documentId },
|
||||
skip: !documentId,
|
||||
fetchPolicy: "network-only",
|
||||
nextFetchPolicy: "network-only"
|
||||
});
|
||||
if (loadingDoc) return <LoadingSpinner />;
|
||||
if (errorDoc) return <AlertComponent message={errorDoc.message} type="error" />;
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
|
||||
if (!data || !data.documents_by_pk) return <Result status="404" title={t("general.errors.notfound")} />;
|
||||
if (!dataDoc || !dataDoc.documents_by_pk) return <Result status="404" title={t("general.errors.notfound")} />;
|
||||
return (
|
||||
<div>
|
||||
<DocumentEditor document={data ? data.documents_by_pk : null} />
|
||||
<DocumentEditor document={dataDoc ? dataDoc.documents_by_pk : null} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ export function JobsDocumentsLocalGallery({
|
||||
key="edit"
|
||||
onClick={() => {
|
||||
const newWindow = window.open(
|
||||
`${window.location.protocol}//${window.location.host}/edit-local?imageUrl=${
|
||||
`${window.location.protocol}//${window.location.host}/edit?imageUrl=${
|
||||
jobMedia.images[modalState.index].fullsize
|
||||
}&filename=${jobMedia.images[modalState.index].filename}&jobid=${job.id}`,
|
||||
"_blank",
|
||||
|
||||
Reference in New Issue
Block a user