IO-3255 Clean up front end components for pm.

This commit is contained in:
Patrick Fic
2025-06-23 14:00:25 -07:00
parent 09e1887609
commit cbb6c43ec3
17 changed files with 588 additions and 414 deletions

View File

@@ -12,7 +12,7 @@ import { PageHeader } from "@ant-design/pro-layout";
import { useMutation } from "@apollo/client";
import { Button, Dropdown, Input, Space, Table, Tag } from "antd";
import axios from "axios";
import React, { useState } from "react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -32,7 +32,7 @@ import JobLinesBillRefernece from "../job-lines-bill-reference/job-lines-bill-re
import { useSplitTreatments } from "@splitsoftware/splitio-react";
import _ from "lodash";
import { FaTasks } from "react-icons/fa";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { selectBodyshop, selectPartsManagementOnly } from "../../redux/user/user.selectors";
import dayjs from "../../utils/day";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
@@ -45,11 +45,13 @@ import PartsOrderDrawer from "../parts-order-list-table/parts-order-list-table-d
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
import JobLinesExpander from "./job-lines-expander.component";
import JobLinesPartPriceChange from "./job-lines-part-price-change.component";
import JobLinesExpanderSimple from "./jobs-lines-expander-simple.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
technician: selectTechnician
technician: selectTechnician,
partsManagementOnly: selectPartsManagementOnly
});
const mapDispatchToProps = (dispatch) => ({
@@ -79,7 +81,7 @@ export function JobLinesComponent({
handleBillOnRowClick,
handlePartsOrderOnRowClick,
handlePartsDispatchOnRowClick,
simple
partsManagementOnly
}) {
const [deleteJobLine] = useMutation(DELETE_JOB_LINE_BY_PK);
const {
@@ -93,7 +95,13 @@ export function JobLinesComponent({
const [selectedLines, setSelectedLines] = useState([]);
const [state, setState] = useState({
sortedInfo: {},
filteredInfo: {}
filteredInfo: {
...(partsManagementOnly
? {
part_type: ["PAN", "PAC", "PAR", "PAL", "PAA", "PAM", "PAP", "PAS", "PASL", "PAG"]
}
: {})
}
});
const { t } = useTranslation();
const jobIsPrivate = bodyshop.md_ins_cos.find((c) => c.name === job.ins_co_nm)?.private;
@@ -221,7 +229,7 @@ export function JobLinesComponent({
sorter: (a, b) => a.part_qty - b.part_qty,
sortOrder: state.sortedInfo.columnKey === "part_qty" && state.sortedInfo.order
},
...(!simple
...(!partsManagementOnly
? [
{
title: t("joblines.fields.mod_lbr_ty"),
@@ -273,7 +281,7 @@ export function JobLinesComponent({
key: "location",
render: (text, record) => <JobLineLocationPopup jobline={record} disabled={jobRO} />
},
...(!simple && HasFeatureAccess({ featureName: "bills", bodyshop })
...(!partsManagementOnly && HasFeatureAccess({ featureName: "bills", bodyshop })
? [
{
title: t("joblines.labels.billref"),
@@ -307,70 +315,74 @@ export function JobLinesComponent({
onFilter: (value, record) => value.includes(record.status),
render: (text, record) => <JobLineStatusPopup jobline={record} disabled={jobRO} />
},
{
title: t("general.labels.actions"),
dataIndex: "actions",
key: "actions",
render: (text, record) => (
<Space>
{(record.manual_line || jobIsPrivate) && !technician && (
<>
<Button
disabled={jobRO}
onClick={() => {
setJobLineEditContext({
actions: { refetch: refetch, submit: form && form.submit },
context: { ...record, jobid: job.id }
});
}}
>
<EditFilled />
</Button>
</>
)}
<Button
title={t("tasks.buttons.create")}
onClick={() => {
setTaskUpsertContext({
context: {
jobid: job.id,
joblineid: record.id
}
});
}}
>
<FaTasks />
</Button>
{(record.manual_line || jobIsPrivate) && !technician && (
<>
<Button
disabled={jobRO}
onClick={async () => {
await deleteJobLine({
variables: { joblineId: record.id },
update(cache) {
cache.modify({
fields: {
joblines(existingJobLines, { readField }) {
return existingJobLines.filter((jlRef) => record.id !== readField("id", jlRef));
...!partsManagementOnly
? [
{
title: t("general.labels.actions"),
dataIndex: "actions",
key: "actions",
render: (text, record) => (
<Space>
{(record.manual_line || jobIsPrivate) && !technician && (
<>
<Button
disabled={jobRO}
onClick={() => {
setJobLineEditContext({
actions: { refetch: refetch, submit: form && form.submit },
context: { ...record, jobid: job.id }
});
}}
>
<EditFilled />
</Button>
</>
)}
<Button
title={t("tasks.buttons.create")}
onClick={() => {
setTaskUpsertContext({
context: {
jobid: job.id,
joblineid: record.id
}
});
}}
>
<FaTasks />
</Button>
{(record.manual_line || jobIsPrivate) && !technician && (
<>
<Button
disabled={jobRO}
onClick={async () => {
await deleteJobLine({
variables: { joblineId: record.id },
update(cache) {
cache.modify({
fields: {
joblines(existingJobLines, { readField }) {
return existingJobLines.filter((jlRef) => record.id !== readField("id", jlRef));
}
}
});
}
}
});
}
});
await axios.post("/job/totalsssu", {
id: job.id
});
refetch && refetch();
}}
>
<DeleteFilled />
</Button>
</>
)}
</Space>
)
}
});
await axios.post("/job/totalsssu", {
id: job.id
});
refetch && refetch();
}}
>
<DeleteFilled />
</Button>
</>
)}
</Space>
)
}
]
: []
];
const handleTableChange = (pagination, filters, sorter) => {
@@ -543,17 +555,19 @@ export function JobLinesComponent({
<Dropdown menu={markMenu} trigger={["click"]}>
<Button id="repair-data-mark-button">{t("jobs.actions.mark")}</Button>
</Dropdown>
<Button
disabled={jobRO || technician}
onClick={() => {
setJobLineEditContext({
actions: { refetch: refetch },
context: { jobid: job.id }
});
}}
>
{t("joblines.actions.new")}
</Button>
{!partsManagementOnly && (
<Button
disabled={jobRO || technician}
onClick={() => {
setJobLineEditContext({
actions: { refetch: refetch },
context: { jobid: job.id }
});
}}
>
{t("joblines.actions.new")}
</Button>
)}
{InstanceRenderManager({ rome: <JobSendPartPriceChangeComponent job={job} disabled={technician} /> })}
<JobCreateIOU job={job} selectedJobLines={selectedLines} />
<Input.Search
@@ -577,7 +591,12 @@ export function JobLinesComponent({
x: true
}}
expandable={{
expandedRowRender: (record) => <JobLinesExpander jobline={record} jobid={job.id} />,
expandedRowRender: (record) =>
partsManagementOnly ? (
<JobLinesExpanderSimple jobline={record} jobid={job.id} />
) : (
<JobLinesExpander jobline={record} jobid={job.id} />
),
rowExpandable: (record) => true,
//expandRowByClick: true,
expandIcon: ({ expanded, onExpand, record }) =>

View File

@@ -0,0 +1,83 @@
import { useQuery } from "@apollo/client";
import { Col, Row, Skeleton, Timeline, Typography } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { GET_JOB_LINE_ORDERS } from "../../graphql/jobs.queries";
import { selectTechnician } from "../../redux/tech/tech.selectors.js";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { DateFormatter } from "../../utils/DateFormatter";
import AlertComponent from "../alert/alert.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
technician: selectTechnician
});
const mapDispatchToProps = (dispatch) => ({});
export default connect(mapStateToProps, mapDispatchToProps)(JobLinesExpanderSimple);
export function JobLinesExpanderSimple({ jobline, jobid, bodyshop, technician }) {
const { t } = useTranslation();
const { loading, error, data } = useQuery(GET_JOB_LINE_ORDERS, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
joblineid: jobline.id
}
});
if (loading) return <Skeleton />;
if (error) return <AlertComponent message={error.message} type="error" />;
return (
<Row>
<Col span={24}>
<Typography.Title level={4}>{t("parts_orders.labels.parts_orders")}</Typography.Title>
<Timeline
items={
data.parts_order_lines.length > 0
? data.parts_order_lines.map((line) => ({
key: line.id,
children: (
<Row wrap>
<Col span={4}>
{!technician ? (
<>
<Link to={`/manage/jobs/${jobid}?partsorderid=${line.parts_order.id}`}>
{line.parts_order.order_number}
</Link>
</>
) : (
`${line.parts_order.order_number}`
)}
</Col>
<Col span={4}>
<DateFormatter>{line.parts_order.order_date}</DateFormatter>
</Col>
<Col span={4}>{line.parts_order.vendor.name}</Col>
{line.backordered_eta ? (
<Col span={4}>
<span>
{`${t("parts_orders.fields.backordered_eta")}: `}
<DateFormatter>{line.backordered_eta}</DateFormatter>
</span>
</Col>
) : null}
</Row>
)
}))
: [
{
key: "no-orders",
children: t("parts_orders.labels.notyetordered")
}
]
}
/>
</Col>
</Row>
);
}