handleSelect(i)} onItemHover key={idx}>
+ handleSelect(i)} key={idx}>
{i.label}
))}
diff --git a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx
index ce25fe6d8..dbc603660 100644
--- a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx
+++ b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx
@@ -1,5 +1,5 @@
-import { FileExcelFilled, EditFilled, SyncOutlined } from "@ant-design/icons";
-import { Card, Col, Row, Space, Button } from "antd";
+import { EditFilled, FileExcelFilled, SyncOutlined } from "@ant-design/icons";
+import { Button, Card, Col, Row, Space } from "antd";
import React, { useEffect, useState } from "react";
import Gallery from "react-grid-gallery";
import { useTranslation } from "react-i18next";
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
new file mode 100644
index 000000000..cc7cbe31f
--- /dev/null
+++ b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.container.jsx
@@ -0,0 +1,105 @@
+import { SyncOutlined } from "@ant-design/icons";
+import { Button, Card, Space } from "antd";
+import React, { useEffect } from "react";
+import Gallery from "react-grid-gallery";
+import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import {
+ getBillMedia,
+ getJobMedia,
+ toggleMediaSelected,
+} from "../../redux/media/media.actions";
+import { selectAllMedia } from "../../redux/media/media.selectors";
+import { selectBodyshop } from "../../redux/user/user.selectors";
+import { CreateExplorerLinkForJob } from "../../utils/localmedia";
+import DocumentsLocalUploadComponent from "../documents-local-upload/documents-local-upload.component";
+import JobsDocumentsLocalGalleryReassign from "./jobs-documents-local-gallery.reassign.component";
+
+const mapStateToProps = createStructuredSelector({
+ bodyshop: selectBodyshop,
+ allMedia: selectAllMedia,
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ getJobMedia: (id) => dispatch(getJobMedia(id)),
+ getBillMedia: ({ jobid, invoice_number }) => {
+ dispatch(getBillMedia({ jobid, invoice_number }));
+ },
+ toggleMediaSelected: ({ jobid, filename }) =>
+ dispatch(toggleMediaSelected({ jobid, filename })),
+});
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(JobsDocumentsLocalGallery);
+
+export function JobsDocumentsLocalGallery({
+ bodyshop,
+ toggleMediaSelected,
+ getJobMedia,
+ getBillMedia,
+ allMedia,
+ job,
+ invoice_number,
+ vendorid,
+}) {
+ const { t } = useTranslation();
+ useEffect(() => {
+ if (job) {
+ if (invoice_number) {
+ getBillMedia({ jobid: job.id, invoice_number });
+ } else {
+ getJobMedia(job.id);
+ }
+ }
+ }, [job, invoice_number, getJobMedia, getBillMedia]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ toggleMediaSelected({ jobid: job.id, filename: image.filename });
+ }}
+ onClickImage={(props) => {
+ window.open(
+ props.target.src,
+ "_blank",
+ "toolbar=0,location=0,menubar=0"
+ );
+ }}
+ />
+
+
+ );
+}
diff --git a/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.reassign.component.jsx b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.reassign.component.jsx
new file mode 100644
index 000000000..c8f336d7c
--- /dev/null
+++ b/client/src/components/jobs-documents-local-gallery/jobs-documents-local-gallery.reassign.component.jsx
@@ -0,0 +1,92 @@
+import { Button, Form, Popover, Space } from "antd";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { getJobMedia } from "../../redux/media/media.actions";
+import { selectAllMedia } from "../../redux/media/media.selectors";
+import { selectBodyshop } from "../../redux/user/user.selectors";
+import cleanAxios from "../../utils/CleanAxios";
+import JobSearchSelect from "../job-search-select/job-search-select.component";
+
+const mapStateToProps = createStructuredSelector({
+ allMedia: selectAllMedia,
+ bodyshop: selectBodyshop,
+});
+const mapDispatchToProps = (dispatch) => ({
+ getJobMedia: (id) => dispatch(getJobMedia(id)),
+
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+});
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(JobsDocumentsLocalGalleryReassign);
+
+export function JobsDocumentsLocalGalleryReassign({
+ bodyshop,
+ jobid,
+ allMedia,
+ getJobMedia,
+}) {
+ const { t } = useTranslation();
+ const [form] = Form.useForm();
+
+ const [visible, setVisible] = useState(false);
+ const [loading, setLoading] = useState(false);
+
+ const handleFinish = async ({ jobid: newJobid }) => {
+ setLoading(true);
+ const selectedDocuments = allMedia[jobid].filter((m) => m.isSelected);
+
+ await cleanAxios.post(`${bodyshop.localmediaserverhttp}/jobs/move`, {
+ from_jobid: jobid,
+ jobid: newJobid,
+ files: selectedDocuments.map((f) => f.filename),
+ });
+
+ getJobMedia(jobid);
+ setVisible(false);
+ setLoading(false);
+ };
+
+ const popContent = (
+
+
+
+
+
+
+
+
+
+
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/client/src/components/notes-preset-button/notes-preset-button.component.jsx b/client/src/components/notes-preset-button/notes-preset-button.component.jsx
index 87412ec8c..e330b15f6 100644
--- a/client/src/components/notes-preset-button/notes-preset-button.component.jsx
+++ b/client/src/components/notes-preset-button/notes-preset-button.component.jsx
@@ -24,7 +24,7 @@ export function NotesPresetButton({ bodyshop, form }) {
const menu = (