Files
bodyshop/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx
2025-06-11 10:29:58 -07:00

215 lines
7.1 KiB
JavaScript

import { BarsOutlined, PrinterFilled, SyncOutlined, ToolFilled } from "@ant-design/icons";
import { PageHeader } from "@ant-design/pro-layout";
import { useQuery } from "@apollo/client";
import { Button, Divider, Form, Space, Tabs } from "antd";
import Axios from "axios";
import _ from "lodash";
import queryString from "query-string";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import FormFieldsChanged from "../../components/form-fields-changed-alert/form-fields-changed-alert.component.jsx";
import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container.jsx";
import JobLineUpsertModalContainer from "../../components/job-lines-upsert-modal/job-lines-upsert-modal.container.jsx";
import JobProfileDataWarning from "../../components/job-profile-data-warning/job-profile-data-warning.component.jsx";
import JobsChangeStatus from "../../components/jobs-change-status/jobs-change-status.component.jsx";
import JobsDetailHeaderActions from "../../components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx";
import JobsDetailHeader from "../../components/jobs-detail-header/jobs-detail-header.component.jsx";
import JobsDetailPliContainer from "../../components/jobs-detail-pli/jobs-detail-pli.container.jsx";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { useSocket } from "../../contexts/SocketIO/useSocket.js";
import { QUERY_PARTS_BILLS_BY_JOBID } from "../../graphql/bills.queries.js";
import { insertAuditTrail } from "../../redux/application/application.actions.js";
import { selectJobReadOnly } from "../../redux/application/application.selectors.js";
import { setModalContext } from "../../redux/modals/modals.actions.js";
import { selectBodyshop } from "../../redux/user/user.selectors.js";
import AuditTrailMapping from "../../utils/AuditTrailMappings.js";
import { DateTimeFormat } from "../../utils/DateFormatter.jsx";
import dayjs from "../../utils/day.js";
import UndefinedToNull from "../../utils/undefinedtonull.js";
import { transformJobToForm } from "../jobs-detail/jobs-detail.page.component.jsx";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
jobRO: selectJobReadOnly
});
const mapDispatchToProps = (dispatch) => ({
setPrintCenterContext: (context) =>
dispatch(
setModalContext({
context: context,
modal: "printCenter"
})
),
insertAuditTrail: ({ jobid, operation, type }) =>
dispatch(
insertAuditTrail({
jobid,
operation,
type
})
)
});
export function SimplifiedPartsJobDetailComponent({
bodyshop,
setPrintCenterContext,
jobRO,
job,
mutationUpdateJob,
insertAuditTrail,
refetch
}) {
const { t } = useTranslation();
const [form] = Form.useForm();
const history = useNavigate();
const [loading, setLoading] = useState(false);
const search = queryString.parse(useLocation().search);
const formItemLayout = {
layout: "vertical"
};
const billsQuery = useQuery(QUERY_PARTS_BILLS_BY_JOBID, {
variables: { jobid: job.id },
fetchPolicy: "network-only",
nextFetchPolicy: "network-only"
});
const notification = useNotification();
const { scenarioNotificationsOn } = useSocket();
useEffect(() => {
//form.setFieldsValue(transormJobToForm(job));
form.resetFields();
}, [form, job]);
const handleBillOnRowClick = (record) => {
if (record) {
if (record.id) {
search.billid = record.id;
history({ search: queryString.stringify(search) });
}
} else {
delete search.billid;
history({ search: queryString.stringify(search) });
}
};
const handlePartsOrderOnRowClick = (record) => {
if (record) {
if (record.id) {
search.partsorderid = record.id;
history({ search: queryString.stringify(search) });
}
} else {
delete search.partsorderid;
history({ search: queryString.stringify(search) });
}
};
const handlePartsDispatchOnRowClick = (record) => {
if (record) {
if (record.id) {
search.partsdispatchid = record.id;
history.push({ search: queryString.stringify(search) });
}
} else {
delete search.partsdispatchid;
history.push({ search: queryString.stringify(search) });
}
};
const menuExtra = (
<Space wrap>
<Button
onClick={() => {
refetch();
}}
key="refresh"
>
<SyncOutlined />
{t("general.labels.refresh")}
</Button>
<JobsChangeStatus job={job} />
<Button
onClick={() => {
setPrintCenterContext({
actions: { refetch: refetch },
context: {
id: job.id,
job: job,
type: "job"
}
});
}}
key="printing"
>
<PrinterFilled />
{t("jobs.actions.printCenter")}
</Button>
<JobsDetailHeaderActions key="actions" job={job} refetch={refetch} />
<Button type="primary" loading={loading} disabled={jobRO} onClick={() => form.submit()}>
{t("general.actions.save")}
</Button>
</Space>
);
return (
<div>
<JobLineUpsertModalContainer />
<PageHeader title={<Space>{job.ro_number || t("general.labels.na")}</Space>} extra={menuExtra} />
<JobsDetailHeader job={job} />
<Divider type="horizontal" />
<JobProfileDataWarning job={job} />
<FormFieldsChanged form={form} />
<Tabs
defaultActiveKey={search.tab}
onChange={(key) => history({ search: `?tab=${key}` })}
tabBarStyle={{ fontWeight: "bold", borderBottom: "10px" }}
items={[
{
key: "repairdata",
icon: <BarsOutlined />,
id: "job-details-repairdata",
label: t("menus.jobsdetail.repairdata"),
forceRender: true,
children: (
<JobsLinesContainer
job={job}
joblines={job.joblines}
billsQuery={billsQuery}
handleBillOnRowClick={handleBillOnRowClick}
handlePartsOrderOnRowClick={handlePartsOrderOnRowClick}
handlePartsDispatchOnRowClick={handlePartsDispatchOnRowClick}
refetch={refetch}
form={form}
simple
/>
)
},
{
key: "partssublet",
id: "job-details-partssublet",
icon: <ToolFilled />,
label: t("menus.jobsdetail.partssublet"),
children: (
<JobsDetailPliContainer
job={job}
billsQuery={billsQuery}
handleBillOnRowClick={handleBillOnRowClick}
handlePartsOrderOnRowClick={handlePartsOrderOnRowClick}
handlePartsDispatchOnRowClick={handlePartsDispatchOnRowClick}
/>
)
}
]}
/>
</div>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(SimplifiedPartsJobDetailComponent);