IO-1590 Production by Technician IO-1585 File access api
This commit is contained in:
@@ -37640,6 +37640,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>production_by_technician</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>purchases_by_cost_center_detail</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
||||
@@ -78,7 +78,8 @@
|
||||
"workbox-range-requests": "^6.4.2",
|
||||
"workbox-routing": "^6.4.2",
|
||||
"workbox-strategies": "^6.4.2",
|
||||
"workbox-streams": "^6.4.2"
|
||||
"workbox-streams": "^6.4.2",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"analyze": "source-map-explorer 'build/static/js/*.js'",
|
||||
|
||||
@@ -172,8 +172,7 @@ export default function GlobalSearch() {
|
||||
options={options}
|
||||
onSearch={handleSearch}
|
||||
placeholder={t("general.labels.globalsearch")}
|
||||
>
|
||||
<Input.Search loading={loading} />
|
||||
</AutoComplete>
|
||||
allowClear
|
||||
></AutoComplete>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,45 +5,124 @@ import { useTranslation } from "react-i18next";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import cleanAxios from "../../utils/CleanAxios";
|
||||
import formatBytes from "../../utils/formatbytes";
|
||||
import yauzl from "yauzl";
|
||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||
|
||||
export default function JobsDocumentsDownloadButton({
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(JobsDocumentsDownloadButton);
|
||||
|
||||
export function JobsDocumentsDownloadButton({
|
||||
bodyshop,
|
||||
galleryImages,
|
||||
identifier,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [download, setDownload] = useState(null);
|
||||
const { Direct_Media_Download } = useTreatments(
|
||||
["Direct_Media_Download"],
|
||||
{},
|
||||
bodyshop.imexshopid
|
||||
);
|
||||
const imagesToDownload = [
|
||||
...galleryImages.images.filter((image) => image.isSelected),
|
||||
// ...galleryImages.other.filter((image) => image.isSelected),
|
||||
];
|
||||
|
||||
const handleDownload = () => {
|
||||
logImEXEvent("jobs_documents_download");
|
||||
axios
|
||||
.post("/media/download", {
|
||||
ids: imagesToDownload.map((_) => _.key),
|
||||
})
|
||||
.then((r) => {
|
||||
// window.open(r.data);
|
||||
downloadAs(
|
||||
r.data,
|
||||
`${identifier || "documents"}.zip`,
|
||||
(progressEvent) => {
|
||||
setDownload((currentDownloadState) => {
|
||||
return {
|
||||
downloaded: progressEvent.loaded || 0,
|
||||
speed:
|
||||
(progressEvent.loaded || 0) -
|
||||
((currentDownloadState && currentDownloadState.downloaded) ||
|
||||
0),
|
||||
};
|
||||
});
|
||||
},
|
||||
() => setDownload(null)
|
||||
);
|
||||
});
|
||||
};
|
||||
function downloadProgress(progressEvent) {
|
||||
setDownload((currentDownloadState) => {
|
||||
return {
|
||||
downloaded: progressEvent.loaded || 0,
|
||||
speed:
|
||||
(progressEvent.loaded || 0) -
|
||||
((currentDownloadState && currentDownloadState.downloaded) || 0),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const handleDownload = async () => {
|
||||
logImEXEvent("jobs_documents_download");
|
||||
|
||||
const zipUrl = await axios({
|
||||
url: "/media/download",
|
||||
method: "POST",
|
||||
//responseType: "arraybuffer", // Important
|
||||
data: { ids: imagesToDownload.map((_) => _.key) },
|
||||
});
|
||||
|
||||
const theDownloadedZip = await cleanAxios({
|
||||
url: zipUrl.data,
|
||||
method: "GET",
|
||||
responseType: "arraybuffer",
|
||||
onDownloadProgress: downloadProgress,
|
||||
});
|
||||
setDownload(null);
|
||||
if (Direct_Media_Download.treatment === "on") {
|
||||
try {
|
||||
const parentDir = await window.showDirectoryPicker({
|
||||
id: "media",
|
||||
startIn: "downloads",
|
||||
});
|
||||
|
||||
const directory = await parentDir.getDirectoryHandle(identifier, {
|
||||
create: true,
|
||||
});
|
||||
|
||||
yauzl.fromBuffer(
|
||||
Buffer.from(theDownloadedZip.data),
|
||||
{},
|
||||
(err, zipFile) => {
|
||||
if (err) throw err;
|
||||
zipFile.on("entry", (entry) => {
|
||||
zipFile.openReadStream(entry, async (readErr, readStream) => {
|
||||
if (readErr) {
|
||||
zipFile.close();
|
||||
throw readErr;
|
||||
}
|
||||
if (err) throw err;
|
||||
let fileSystemHandle = await directory.getFileHandle(
|
||||
entry.fileName,
|
||||
{
|
||||
create: true,
|
||||
}
|
||||
);
|
||||
const writable = await fileSystemHandle.createWritable();
|
||||
readStream.on("data", async function (chunk) {
|
||||
await writable.write(chunk);
|
||||
});
|
||||
readStream.on("end", async function () {
|
||||
await writable.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
standardMediaDownload(theDownloadedZip.data);
|
||||
}
|
||||
} else {
|
||||
standardMediaDownload(theDownloadedZip.data);
|
||||
}
|
||||
|
||||
function standardMediaDownload(bufferData) {
|
||||
const a = document.createElement("a");
|
||||
const url = window.URL.createObjectURL(new Blob([bufferData]));
|
||||
a.href = url;
|
||||
a.download = `${identifier || "documents"}.zip`;
|
||||
a.click();
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
@@ -75,11 +154,6 @@ const downloadAs = (url, name, onDownloadProgress, onCompleted) => {
|
||||
})
|
||||
.then((response) => {
|
||||
onCompleted && onCompleted();
|
||||
const a = document.createElement("a");
|
||||
const url = window.URL.createObjectURL(response.data);
|
||||
a.href = url;
|
||||
a.download = name;
|
||||
a.click();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("error", err);
|
||||
|
||||
@@ -2230,7 +2230,7 @@
|
||||
"open_orders_estimator": "Open Orders by Estimator",
|
||||
"open_orders_ins_co": "Open Orders by Insurance Company",
|
||||
"open_orders_status": "Open Orders by Status",
|
||||
"parts_backorder": "Backordered Parts",
|
||||
"parts_backorder": "IOU Parts List",
|
||||
"parts_not_recieved": "Parts Not Received",
|
||||
"payments_by_date": "Payments by Date",
|
||||
"payments_by_date_type": "Payments by Date and Type",
|
||||
@@ -2239,6 +2239,7 @@
|
||||
"production_by_repair_status": "Production by Status",
|
||||
"production_by_ro": "Production by RO",
|
||||
"production_by_target_date": "Production by Target Date",
|
||||
"production_by_technician": "Production by Technician",
|
||||
"purchases_by_cost_center_detail": "Purchases by Cost Center (Detail)",
|
||||
"purchases_by_cost_center_summary": "Purchases by Cost Center (Summary)",
|
||||
"purchases_by_date_range_detail": "Purchases by Date - Detail",
|
||||
|
||||
@@ -2239,6 +2239,7 @@
|
||||
"production_by_repair_status": "",
|
||||
"production_by_ro": "",
|
||||
"production_by_target_date": "",
|
||||
"production_by_technician": "",
|
||||
"purchases_by_cost_center_detail": "",
|
||||
"purchases_by_cost_center_summary": "",
|
||||
"purchases_by_date_range_detail": "",
|
||||
|
||||
@@ -2239,6 +2239,7 @@
|
||||
"production_by_repair_status": "",
|
||||
"production_by_ro": "",
|
||||
"production_by_target_date": "",
|
||||
"production_by_technician": "",
|
||||
"purchases_by_cost_center_detail": "",
|
||||
"purchases_by_cost_center_summary": "",
|
||||
"purchases_by_date_range_detail": "",
|
||||
|
||||
@@ -1579,6 +1579,14 @@ export const TemplateList = (type, context) => {
|
||||
//idtype: "vendor",
|
||||
disabled: false,
|
||||
},
|
||||
production_by_technician: {
|
||||
title: i18n.t("reportcenter.templates.production_by_technician"),
|
||||
description: "",
|
||||
subject: i18n.t("reportcenter.templates.production_by_technician"),
|
||||
key: "production_by_technician",
|
||||
//idtype: "vendor",
|
||||
disabled: false,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(!type || type === "special"
|
||||
|
||||
Reference in New Issue
Block a user