From ddc61414809bc583dfb2a0235686561d40334895 Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Thu, 27 Nov 2025 13:15:26 -0800 Subject: [PATCH] IO-3452 Documents Adjustments Signed-off-by: Allan Carr --- ...nt-imgproxy-gallery.download.component.jsx | 29 +++--- ...s-documents-imgproxy-gallery.component.jsx | 6 +- ...ents-imgproxy-gallery.delete.component.jsx | 2 +- ...jobs-documents-local-gallery.container.jsx | 2 +- ...cuments-local-gallery.delete.component.jsx | 11 ++- .../jobs-documents-local-gallery.download.jsx | 88 +++++++++++-------- 6 files changed, 78 insertions(+), 60 deletions(-) diff --git a/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx b/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx index b9f8266ff..6590498aa 100644 --- a/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx +++ b/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx @@ -35,16 +35,14 @@ export function JobsDocumentsImgproxyDownloadButton({ galleryImages, identifier, ...galleryImages.other.filter((image) => image.isSelected) ]; - function downloadProgress(progressEvent) { - setDownload((currentDownloadState) => { - return { - downloaded: progressEvent.loaded || 0, - speed: (progressEvent.loaded || 0) - ((currentDownloadState && currentDownloadState.downloaded) || 0) - }; - }); - } + const downloadProgress = ({ loaded }) => { + setDownload((currentDownloadState) => ({ + downloaded: loaded ?? 0, + speed: (loaded ?? 0) - (currentDownloadState?.downloaded ?? 0) + })); + }; - function standardMediaDownload(bufferData) { + const standardMediaDownload = (bufferData) => { try { const a = document.createElement("a"); const url = window.URL.createObjectURL(new Blob([bufferData])); @@ -55,29 +53,26 @@ export function JobsDocumentsImgproxyDownloadButton({ galleryImages, identifier, setLoading(false); setDownload(null); } - } + }; const handleDownload = async () => { logImEXEvent("jobs_documents_download"); setLoading(true); try { - const response = await axios({ + const { data } = await axios({ url: "/media/imgproxy/download", method: "POST", responseType: "blob", data: { jobId, documentids: imagesToDownload.map((_) => _.id) }, onDownloadProgress: downloadProgress }); - - setLoading(false); - setDownload(null); - // Use the response data (Blob) to trigger download - standardMediaDownload(response.data); + standardMediaDownload(data); } catch { + // handle error (optional) + } finally { setLoading(false); setDownload(null); - // handle error (optional) } }; diff --git a/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.component.jsx b/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.component.jsx index 803505436..1c14eb486 100644 --- a/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.component.jsx +++ b/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.component.jsx @@ -76,14 +76,14 @@ function JobsDocumentsImgproxyComponent({ + {!billId && ( + + )} - {!billId && ( - - )} {!hasMediaAccess && ( diff --git a/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.delete.component.jsx b/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.delete.component.jsx index 4701bca67..c11059b35 100644 --- a/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.delete.component.jsx +++ b/client/src/components/jobs-documents-imgproxy-gallery/jobs-documents-imgproxy-gallery.delete.component.jsx @@ -67,7 +67,7 @@ export default function JobsDocumentsImgproxyDeleteButton({ galleryImages, delet okButtonProps={{ danger: true }} cancelText={t("general.actions.cancel")} > - diff --git a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.container.jsx b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.container.jsx index d3176a19a..f5570257f 100644 --- a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.container.jsx +++ b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.container.jsx @@ -107,8 +107,8 @@ export function JobsDocumentsLocalGallery({ - + diff --git a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx index c194cd57f..3c1c4df38 100644 --- a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx +++ b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.delete.component.jsx @@ -28,6 +28,8 @@ export function JobsDocumentsLocalDeleteButton({ bodyshop, getJobMedia, allMedia const [loading, setLoading] = useState(false); + const imagesToDelete = (allMedia?.[jobid] || []).filter((i) => i.isSelected); + const handleDelete = async () => { logImEXEvent("job_documents_delete"); setLoading(true); @@ -36,7 +38,7 @@ export function JobsDocumentsLocalDeleteButton({ bodyshop, getJobMedia, allMedia `${bodyshop.localmediaserverhttp}/jobs/delete`, { jobid: jobid, - files: (allMedia?.[jobid] || []).filter((i) => i.isSelected).map((i) => i.filename) + files: imagesToDelete.map((i) => i.filename) }, { headers: { ims_token: bodyshop.localmediatoken } } ); @@ -60,14 +62,17 @@ export function JobsDocumentsLocalDeleteButton({ bodyshop, getJobMedia, allMedia return ( } onConfirm={handleDelete} title={t("documents.labels.confirmdelete")} okText={t("general.actions.delete")} - okButtonProps={{ type: "danger" }} + okButtonProps={{ danger: true }} cancelText={t("general.actions.cancel")} > - + ); } diff --git a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.download.jsx b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.download.jsx index c5ed07019..d1c05988a 100644 --- a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.download.jsx +++ b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.download.jsx @@ -1,8 +1,8 @@ -import { Button } from "antd"; +import { Button, Space } from "antd"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import cleanAxios from "../../utils/CleanAxios"; - +import formatBytes from "../../utils/formatbytes"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectAllMedia } from "../../redux/media/media.selectors"; @@ -19,45 +19,63 @@ export default connect(mapStateToProps, mapDispatchToProps)(JobsLocalGalleryDown export function JobsLocalGalleryDownloadButton({ bodyshop, allMedia, job }) { const { t } = useTranslation(); - const [download, setDownload] = useState(null); + const [loading, setLoading] = useState(false); + const [download, setDownload] = useState(false); - function downloadProgress(progressEvent) { - setDownload((currentDownloadState) => { - return { - downloaded: progressEvent.loaded || 0, - speed: (progressEvent.loaded || 0) - (currentDownloadState?.downloaded || 0) - }; - }); - } + const imagesToDownload = (allMedia?.[job.id] || []).filter((i) => i.isSelected); + + const downloadProgress = ({ loaded }) => { + setDownload((currentDownloadState) => ({ + downloaded: loaded || 0, + speed: (loaded || 0) - (currentDownloadState?.downloaded || 0) + })); + }; + + const standardMediaDownload = (bufferData, filename) => { + try { + const a = document.createElement("a"); + const url = window.URL.createObjectURL(new Blob([bufferData])); + a.href = url; + a.download = `${filename}.zip`; + a.click(); + } catch { + setLoading(false); + setDownload(null); + } + }; const handleDownload = async () => { - const theDownloadedZip = await cleanAxios.post( - `${bodyshop.localmediaserverhttp}/jobs/download`, - { - jobid: job.id, - files: (allMedia?.[job.id] || []).filter((i) => i.isSelected).map((i) => i.filename) - }, - { - headers: { ims_token: bodyshop.localmediatoken }, - responseType: "arraybuffer", - onDownloadProgress: downloadProgress - } - ); - setDownload(null); - standardMediaDownload(theDownloadedZip.data, job.ro_number); + const { localmediaserverhttp, localmediatoken } = bodyshop; + const { id, ro_number } = job; + setLoading(true); + try { + const response = await cleanAxios.post( + `${localmediaserverhttp}/jobs/download`, + { + jobid: id, + files: imagesToDownload.map((i) => i.filename) + }, + { + headers: { ims_token: localmediatoken }, + responseType: "arraybuffer", + onDownloadProgress: downloadProgress + } + ); + standardMediaDownload(response.data, ro_number); + } catch { + // handle error (optional) + } finally { + setLoading(false); + setDownload(null); + } }; return ( - ); } - -function standardMediaDownload(bufferData, filename) { - const a = document.createElement("a"); - const url = window.URL.createObjectURL(new Blob([bufferData])); - a.href = url; - a.download = `${filename}.zip`; - a.click(); -}