From 8f00dbfc1765ea9269052efbadeb36c644d04a51 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 7 Aug 2025 13:54:39 -0700 Subject: [PATCH 1/2] IO-3307 Resolve bill document for imgproxy. --- ...s-documents-imgproxy-gallery.component.jsx | 8 ++++---- server/graphql-client/queries.js | 20 +++++++++++++++++++ server/media/imgproxy-media.js | 9 ++++++--- 3 files changed, 30 insertions(+), 7 deletions(-) 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 8ada3616f..c7f7d46e4 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 @@ -46,8 +46,8 @@ function JobsDocumentsImgproxyComponent({ const [modalState, setModalState] = useState({ open: false, index: 0 }); const fetchThumbnails = useCallback(() => { - fetchImgproxyThumbnails({ setStateCallback: setGalleryImages, jobId }); - }, [jobId, setGalleryImages]); + fetchImgproxyThumbnails({ setStateCallback: setGalleryImages, jobId, billId }); + }, [jobId, billId, setGalleryImages]); useEffect(() => { if (data) { @@ -208,8 +208,8 @@ function JobsDocumentsImgproxyComponent({ export default connect(mapStateToProps, mapDispatchToProps)(JobsDocumentsImgproxyComponent); -export const fetchImgproxyThumbnails = async ({ setStateCallback, jobId, imagesOnly }) => { - const result = await axios.post("/media/imgproxy/thumbnails", { jobid: jobId }); +export const fetchImgproxyThumbnails = async ({ setStateCallback, jobId, billId, imagesOnly }) => { + const result = await axios.post("/media/imgproxy/thumbnails", { jobid: jobId, billid: billId }); const documents = result.data.reduce( (acc, value) => { if (value.type.startsWith("image")) { diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js index f700bb17c..e05e16508 100644 --- a/server/graphql-client/queries.js +++ b/server/graphql-client/queries.js @@ -2846,6 +2846,26 @@ exports.GET_DOCUMENTS_BY_JOB = ` } } }`; +exports.GET_DOCUMENTS_BY_BILL = ` +query GET_DOCUMENTS_BY_BILL($billId: uuid!) { + documents_aggregate(where: {billid: {_eq: $billId}}) { + aggregate { + sum { + size + } + } + } + documents(order_by: {takenat: desc}, where: {billid: {_eq: $billId}}) { + id + name + key + type + size + takenat + extension + } +} +`; exports.QUERY_TEMPORARY_DOCS = ` query QUERY_TEMPORARY_DOCS { documents(where: { jobid: { _is_null: true } }, order_by: { takenat: desc }) { diff --git a/server/media/imgproxy-media.js b/server/media/imgproxy-media.js index 46a8dd840..576c1cd69 100644 --- a/server/media/imgproxy-media.js +++ b/server/media/imgproxy-media.js @@ -18,6 +18,7 @@ const { GET_DOCUMENTS_BY_JOB, QUERY_TEMPORARY_DOCS, GET_DOCUMENTS_BY_IDS, + GET_DOCUMENTS_BY_BILL, DELETE_MEDIA_DOCUMENTS } = require("../graphql-client/queries"); const yazl = require("yazl"); @@ -90,9 +91,11 @@ const getThumbnailUrls = async (req, res) => { //Delayed as the key structure may change slightly from what it is currently and will require evaluating mobile components. const client = req.userGraphQLClient; //If there's no jobid and no billid, we're in temporary documents. - const data = await (jobid - ? client.request(GET_DOCUMENTS_BY_JOB, { jobId: jobid }) - : client.request(QUERY_TEMPORARY_DOCS)); + const data = await ( + billid ? client.request(GET_DOCUMENTS_BY_BILL, { billId: billid }) : + jobid + ? client.request(GET_DOCUMENTS_BY_JOB, { jobId: jobid }) + : client.request(QUERY_TEMPORARY_DOCS)); const thumbResizeParams = `rs:fill:250:250:1/g:ce`; const s3client = new S3Client({ region: InstanceRegion() }); From 4e8ea736c545f5178544d4e78c31d942bf807cd6 Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Thu, 7 Aug 2025 20:45:04 -0700 Subject: [PATCH 2/2] IO-3285 Shop Config Lite-Basic Signed-off-by: Allan Carr --- .../shop-info/shop-info.general.component.jsx | 951 ++++++++++-------- 1 file changed, 520 insertions(+), 431 deletions(-) diff --git a/client/src/components/shop-info/shop-info.general.component.jsx b/client/src/components/shop-info/shop-info.general.component.jsx index 2a20e9549..6803e53ae 100644 --- a/client/src/components/shop-info/shop-info.general.component.jsx +++ b/client/src/components/shop-info/shop-info.general.component.jsx @@ -145,124 +145,168 @@ export function ShopInfoGeneral({ form, bodyshop }) { - {HasFeatureAccess({ featureName: "export", bodyshop }) && ( - <> - - - - {InstanceRenderManager({ - imex: ( - - {() => ( - - - - )} - - ) - })} - - - - - - 2 - 3 - - - - {() => { - return ( - - - {t("bodyshop.labels.2tiername")} - {t("bodyshop.labels.2tiersource")} - - - ); - }} - - - - - - - - - )} - - - - - - - {InstanceRenderManager({ - imex: ( - - - - ) - })} - - - - {HasFeatureAccess({ featureName: "bills", bodyshop }) && ( - <> - {InstanceRenderManager({ - imex: ( + {[ + ...(HasFeatureAccess({ featureName: "export", bodyshop }) + ? [ + + , + InstanceRenderManager({ + imex: ( + + {() => ( + + + + )} + + ) + }), + + + , + + + 2 + 3 + + , + + {() => { + return ( + + + {t("bodyshop.labels.2tiername")} + {t("bodyshop.labels.2tiersource")} + + + ); + }} + , + + + , + + + + ] + : []), + + + , + + + , + InstanceRenderManager({ + imex: ( + + + + ) + }), + + + , + ...(HasFeatureAccess({ featureName: "bills", bodyshop }) + ? [ + InstanceRenderManager({ + imex: ( + + + + ) + }), + + + , + - ) - })} - - - - - - - - )} - - - - {HasFeatureAccess({ featureName: "export", bodyshop }) && ( - <> - - {ReceivableCustomFieldSelect} - - - {ReceivableCustomFieldSelect} - - - {ReceivableCustomFieldSelect} - - { - return { - required: getFieldValue("enforce_class"), - //message: t("general.validation.required"), - type: "array" - }; - } - ]} - > - - - )} - {ADPPayroll.treatment === "on" && ( - - - - )} - - )} + ] + : []), + + + , + ...(HasFeatureAccess({ featureName: "export", bodyshop }) + ? [ + + {ReceivableCustomFieldSelect} + , + + {ReceivableCustomFieldSelect} + , + + {ReceivableCustomFieldSelect} + , + { + return { + required: getFieldValue("enforce_class"), + //message: t("general.validation.required"), + type: "array" + }; + } + ]} + > + + + ] + : []), + ...(ADPPayroll.treatment === "on" + ? [ + + + + ] + : []) + ] + : []) + ]} null}> @@ -446,211 +491,255 @@ export function ShopInfoGeneral({ form, bodyshop }) { - - + , + + + , + + + , + + + , + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ]} + > + + , + + + , + ({ + validator(rule, value) { + if (!value && !getFieldValue(["md_hour_split", "paint"])) { + return Promise.resolve(); + } + if (value + getFieldValue(["md_hour_split", "paint"]) === 1) { + return Promise.resolve(); + } + return Promise.reject(t("bodyshop.validation.larsplit")); + } + }) + ]} + > + + , + ({ + validator(rule, value) { + if (!value && !getFieldValue(["md_hour_split", "paint"])) { + return Promise.resolve(); + } + if (value + getFieldValue(["md_hour_split", "prep"]) === 1) { + return Promise.resolve(); + } + return Promise.reject(t("bodyshop.validation.larsplit")); + } + }) + ]} + > + + , + + + , + + + , + + + , + + + , + + + , + + + , + + + , + + + , + + + , + + + , + + + , + + + + ]}