IO-925 IO-927 IO-930 Production List Updates

This commit is contained in:
Patrick Fic
2021-04-26 11:50:49 -07:00
parent f33715b83c
commit cffcd4b19b
7 changed files with 106 additions and 37 deletions

View File

@@ -2,7 +2,7 @@ import { Carousel } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import CardTemplate from "./job-detail-cards.template.component"; import CardTemplate from "./job-detail-cards.template.component";
import { DetermineFileType } from "../documents-upload/documents-upload.utility";
export default function JobDetailCardsDocumentsComponent({ loading, data }) { export default function JobDetailCardsDocumentsComponent({ loading, data }) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -17,13 +17,18 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
<CardTemplate <CardTemplate
loading={loading} loading={loading}
title={t("jobs.labels.cards.documents")} title={t("jobs.labels.cards.documents")}
extraLink={`/manage/jobs/${data.id}?tab=documents`}> extraLink={`/manage/jobs/${data.id}?tab=documents`}
>
{data.documents.length > 0 ? ( {data.documents.length > 0 ? (
<Carousel autoplay> <Carousel autoplay>
{data.documents.map((item) => ( {data.documents.map((item) => (
<img <img
key={item.id} key={item.id}
src={`${process.env.REACT_APP_CLOUDINARY_IMAGE_ENDPOINT}/${process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS}/${item.key}.jpg`} src={`${
process.env.REACT_APP_CLOUDINARY_ENDPOINT
}/${DetermineFileType(item.type)}/upload/${
process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS
}/${item.key}`}
alt={item.name} alt={item.name}
/> />
))} ))}

View File

@@ -18,19 +18,28 @@ export default connect(
mapDispatchToProps mapDispatchToProps
)(ProductionColumnsComponent); )(ProductionColumnsComponent);
export function ProductionColumnsComponent({ columnState, technician }) { export function ProductionColumnsComponent({
columnState,
technician,
tableState,
}) {
const [columns, setColumns] = columnState; const [columns, setColumns] = columnState;
const { t } = useTranslation(); const { t } = useTranslation();
const handleAdd = (e) => { const handleAdd = (e) => {
setColumns([...columns, ...dataSource({technician}).filter((i) => i.key === e.key)]); setColumns([
...columns,
...dataSource({ technician, state: tableState }).filter(
(i) => i.key === e.key
),
]);
}; };
const columnKeys = columns.map((i) => i.key); const columnKeys = columns.map((i) => i.key);
const menu = ( const menu = (
<Menu onClick={handleAdd}> <Menu onClick={handleAdd}>
{dataSource({ technician }) {dataSource({ technician, state: tableState })
.filter((i) => !columnKeys.includes(i.key)) .filter((i) => !columnKeys.includes(i.key))
.map((item) => ( .map((item) => (
<Menu.Item key={item.key}>{item.title}</Menu.Item> <Menu.Item key={item.key}>{item.title}</Menu.Item>

View File

@@ -4,7 +4,7 @@ import { Link } from "react-router-dom";
import CurrencyFormatter from "../../utils/CurrencyFormatter"; import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter"; import { DateFormatter } from "../../utils/DateFormatter";
import PhoneFormatter from "../../utils/PhoneFormatter"; import PhoneFormatter from "../../utils/PhoneFormatter";
import { alphaSort } from "../../utils/sorters"; import { alphaSort, dateSort } from "../../utils/sorters";
import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component"; import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component";
import ProductionListColumnAlert from "./production-list-columns.alert.component"; import ProductionListColumnAlert from "./production-list-columns.alert.component";
import ProductionListColumnBodyPriority from "./production-list-columns.bodypriority.component"; import ProductionListColumnBodyPriority from "./production-list-columns.bodypriority.component";
@@ -15,8 +15,7 @@ import ProductionListColumnPaintPriority from "./production-list-columns.paintpr
import ProductionListColumnNote from "./production-list-columns.productionnote.component"; import ProductionListColumnNote from "./production-list-columns.productionnote.component";
import ProductionListColumnStatus from "./production-list-columns.status.component"; import ProductionListColumnStatus from "./production-list-columns.status.component";
import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component"; import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component";
const r = ({ technician, state }) => {
const r = ({ technician }) => {
return [ return [
{ {
title: i18n.t("jobs.actions.viewdetail"), title: i18n.t("jobs.actions.viewdetail"),
@@ -35,6 +34,8 @@ const r = ({ technician }) => {
key: "ro_number", key: "ro_number",
ellipsis: true, ellipsis: true,
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number), sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) => render: (text, record) =>
technician ? ( technician ? (
<Link to={`/tech/joblookup?selected=${record.id}`}> <Link to={`/tech/joblookup?selected=${record.id}`}>
@@ -55,6 +56,8 @@ const r = ({ technician }) => {
}`}</span> }`}</span>
), ),
sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln), sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
sortOrder:
state.sortedInfo.columnKey === "ownr" && state.sortedInfo.order,
}, },
{ {
title: i18n.t("jobs.fields.vehicle"), title: i18n.t("jobs.fields.vehicle"),
@@ -72,7 +75,9 @@ const r = ({ technician }) => {
dataIndex: "actual_in", dataIndex: "actual_in",
key: "actual_in", key: "actual_in",
ellipsis: true, ellipsis: true,
sorter: (a, b) => a.actual_in - b.actual_in, sorter: (a, b) => dateSort(a.actual_in, b.actual_in),
sortOrder:
state.sortedInfo.columnKey === "actual_in" && state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<DateFormatter>{record.actual_in || ""}</DateFormatter> <DateFormatter>{record.actual_in || ""}</DateFormatter>
), ),
@@ -82,7 +87,11 @@ const r = ({ technician }) => {
dataIndex: "scheduled_completion", dataIndex: "scheduled_completion",
key: "scheduled_completion", key: "scheduled_completion",
ellipsis: true, ellipsis: true,
sorter: (a, b) => a.scheduled_completion - b.scheduled_completion, sorter: (a, b) =>
dateSort(a.scheduled_completion, b.scheduled_completion),
sortOrder:
state.sortedInfo.columnKey === "scheduled_completion" &&
state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<ProductionListDate record={record} field="scheduled_completion" /> <ProductionListDate record={record} field="scheduled_completion" />
), ),
@@ -92,7 +101,10 @@ const r = ({ technician }) => {
dataIndex: "scheduled_delivery", dataIndex: "scheduled_delivery",
key: "scheduled_delivery", key: "scheduled_delivery",
ellipsis: true, ellipsis: true,
sorter: (a, b) => a.scheduled_delivery - b.scheduled_delivery, sorter: (a, b) => dateSort(a.scheduled_delivery, b.scheduled_delivery),
sortOrder:
state.sortedInfo.columnKey === "scheduled_delivery" &&
state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<ProductionListDate record={record} field="scheduled_delivery" /> <ProductionListDate record={record} field="scheduled_delivery" />
), ),
@@ -103,6 +115,8 @@ const r = ({ technician }) => {
key: "ins_co_nm", key: "ins_co_nm",
ellipsis: true, ellipsis: true,
sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm), sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm),
sortOrder:
state.sortedInfo.columnKey === "ins_co_nm" && state.sortedInfo.order,
}, },
{ {
title: i18n.t("jobs.fields.clm_no"), title: i18n.t("jobs.fields.clm_no"),
@@ -110,6 +124,8 @@ const r = ({ technician }) => {
key: "clm_no", key: "clm_no",
ellipsis: true, ellipsis: true,
sorter: (a, b) => alphaSort(a.clm_no, b.clm_no), sorter: (a, b) => alphaSort(a.clm_no, b.clm_no),
sortOrder:
state.sortedInfo.columnKey === "clm_no" && state.sortedInfo.order,
}, },
{ {
title: i18n.t("jobs.fields.clm_total"), title: i18n.t("jobs.fields.clm_total"),
@@ -117,6 +133,8 @@ const r = ({ technician }) => {
key: "clm_total", key: "clm_total",
ellipsis: true, ellipsis: true,
sorter: (a, b) => a.clm_total - b.clm_total, sorter: (a, b) => a.clm_total - b.clm_total,
sortOrder:
state.sortedInfo.columnKey === "clm_total" && state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter> <CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
), ),
@@ -127,6 +145,8 @@ const r = ({ technician }) => {
key: "owner_owing", key: "owner_owing",
ellipsis: true, ellipsis: true,
sorter: (a, b) => a.owner_owing - b.owner_owing, sorter: (a, b) => a.owner_owing - b.owner_owing,
sortOrder:
state.sortedInfo.columnKey === "owner_owing" && state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<CurrencyFormatter>{record.owner_owing}</CurrencyFormatter> <CurrencyFormatter>{record.owner_owing}</CurrencyFormatter>
), ),
@@ -152,6 +172,7 @@ const r = ({ technician }) => {
key: "csr", key: "csr",
ellipsis: true, ellipsis: true,
sorter: (a, b) => alphaSort(a.csr, b.csr), sorter: (a, b) => alphaSort(a.csr, b.csr),
sortOrder: state.sortedInfo.columnKey === "csr" && state.sortedInfo.order,
}, },
{ {
title: i18n.t("jobs.fields.alt_transport"), title: i18n.t("jobs.fields.alt_transport"),
@@ -159,6 +180,9 @@ const r = ({ technician }) => {
key: "alt_transport", key: "alt_transport",
ellipsis: true, ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport), sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
}, },
{ {
title: i18n.t("jobs.fields.status"), title: i18n.t("jobs.fields.status"),
@@ -166,6 +190,8 @@ const r = ({ technician }) => {
key: "status", key: "status",
ellipsis: true, ellipsis: true,
sorter: (a, b) => alphaSort(a.status, b.status), sorter: (a, b) => alphaSort(a.status, b.status),
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
render: (text, record) => <ProductionListColumnStatus record={record} />, render: (text, record) => <ProductionListColumnStatus record={record} />,
}, },
{ {
@@ -174,6 +200,8 @@ const r = ({ technician }) => {
key: "labhrs", key: "labhrs",
sorter: (a, b) => sorter: (a, b) =>
a.labhrs.aggregate.sum.mod_lb_hrs - b.labhrs.aggregate.sum.mod_lb_hrs, a.labhrs.aggregate.sum.mod_lb_hrs - b.labhrs.aggregate.sum.mod_lb_hrs,
sortOrder:
state.sortedInfo.columnKey === "labhrs" && state.sortedInfo.order,
render: (text, record) => record.labhrs.aggregate.sum.mod_lb_hrs, render: (text, record) => record.labhrs.aggregate.sum.mod_lb_hrs,
}, },
{ {
@@ -182,6 +210,8 @@ const r = ({ technician }) => {
key: "larhrs", key: "larhrs",
sorter: (a, b) => sorter: (a, b) =>
a.larhrs.aggregate.sum.mod_lb_hrs - b.larhrs.aggregate.sum.mod_lb_hrs, a.larhrs.aggregate.sum.mod_lb_hrs - b.larhrs.aggregate.sum.mod_lb_hrs,
sortOrder:
state.sortedInfo.columnKey === "larhrs" && state.sortedInfo.order,
render: (text, record) => record.larhrs.aggregate.sum.mod_lb_hrs, render: (text, record) => record.larhrs.aggregate.sum.mod_lb_hrs,
}, },
{ {
@@ -214,6 +244,8 @@ const r = ({ technician }) => {
sorter: (a, b) => sorter: (a, b) =>
((a.production_vars && a.production_vars.bodypriority) || 11) - ((a.production_vars && a.production_vars.bodypriority) || 11) -
((b.production_vars && b.production_vars.bodypriority) || 11), ((b.production_vars && b.production_vars.bodypriority) || 11),
sortOrder:
state.sortedInfo.columnKey === "bodypriority" && state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<ProductionListColumnBodyPriority record={record} /> <ProductionListColumnBodyPriority record={record} />
), ),
@@ -226,6 +258,9 @@ const r = ({ technician }) => {
sorter: (a, b) => sorter: (a, b) =>
((a.production_vars && a.production_vars.paintpriority) || 11) - ((a.production_vars && a.production_vars.paintpriority) || 11) -
((b.production_vars && b.production_vars.paintpriority) || 11), ((b.production_vars && b.production_vars.paintpriority) || 11),
sortOrder:
state.sortedInfo.columnKey === "paintpriority" &&
state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<ProductionListColumnPaintPriority record={record} /> <ProductionListColumnPaintPriority record={record} />
), ),
@@ -238,6 +273,9 @@ const r = ({ technician }) => {
sorter: (a, b) => sorter: (a, b) =>
((a.production_vars && a.production_vars.detailpriority) || 11) - ((a.production_vars && a.production_vars.detailpriority) || 11) -
((b.production_vars && b.production_vars.detailpriority) || 11), ((b.production_vars && b.production_vars.detailpriority) || 11),
sortOrder:
state.sortedInfo.columnKey === "detailpriority" &&
state.sortedInfo.order,
render: (text, record) => ( render: (text, record) => (
<ProductionListColumnDetailPriority record={record} /> <ProductionListColumnDetailPriority record={record} />
), ),

View File

@@ -5,33 +5,51 @@ import ReactDragListView from "react-drag-listview";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import ProductionListColumnsAdd from "../production-list-columns/production-list-columns.add.component"; import ProductionListColumnsAdd from "../production-list-columns/production-list-columns.add.component";
import ProductionListDetail from "../production-list-detail/production-list-detail.component"; import ProductionListDetail from "../production-list-detail/production-list-detail.component";
import ProductionListSaveConfigButton from "../production-list-save-config-button/production-list-save-config-button.component"; import ProductionListSaveConfigButton from "../production-list-save-config-button/production-list-save-config-button.component";
import ResizeableTitle from "./production-list-table.resizeable.component"; import ResizeableTitle from "./production-list-table.resizeable.component";
import ProductionListColumns from "../production-list-columns/production-list-columns.data";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
technician: selectTechnician,
}); });
export function ProductionListTable({ export function ProductionListTable({
columnState,
loading, loading,
data, data,
bodyshop, bodyshop,
technician,
refetch, refetch,
}) { }) {
const [columns, setColumns] = columnState;
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const [state, setState] = useState( const [state, setState] = useState(
bodyshop.production_config.tableState || { (bodyshop.production_config && bodyshop.production_config.tableState) || {
sortedInfo: {}, sortedInfo: {},
filteredInfo: { text: "" }, filteredInfo: { text: "" },
} }
); );
const { t } = useTranslation(); const { t } = useTranslation();
const [columns, setColumns] = useState(
(state &&
bodyshop.production_config &&
bodyshop.production_config.columnKeys.map((k) => {
return {
...ProductionListColumns({ technician, state }).find(
(e) => e.key === k.key
),
width: k.width,
};
})) ||
[]
);
const handleTableChange = (pagination, filters, sorter) => { const handleTableChange = (pagination, filters, sorter) => {
setState({ setState({
...state, ...state,
@@ -125,7 +143,10 @@ export function ProductionListTable({
<PageHeader <PageHeader
extra={ extra={
<Space wrap> <Space wrap>
<ProductionListColumnsAdd columnState={columnState} /> <ProductionListColumnsAdd
columnState={[columns, setColumns]}
tableState={state}
/>
<ProductionListSaveConfigButton <ProductionListSaveConfigButton
columns={columns} columns={columns}
tableState={state} tableState={state}
@@ -175,7 +196,7 @@ export function ProductionListTable({
rowKey="id" rowKey="id"
loading={loading} loading={loading}
dataSource={dataSource} dataSource={dataSource}
// scroll={{ x: true }} // scroll={{ x: true }}
onChange={handleTableChange} onChange={handleTableChange}
/> />
</ReactDragListView.DragColumn> </ReactDragListView.DragColumn>

View File

@@ -1,11 +1,10 @@
import { useSubscription } from "@apollo/client"; import { useSubscription } from "@apollo/client";
import React, { useState } from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { SUBSCRIPTION_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries"; import { SUBSCRIPTION_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries";
import { selectTechnician } from "../../redux/tech/tech.selectors"; import { selectTechnician } from "../../redux/tech/tech.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import ProductionListColumns from "../production-list-columns/production-list-columns.data";
import ProductionListTable from "./production-list-table.component"; import ProductionListTable from "./production-list-table.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
@@ -21,22 +20,5 @@ export function ProductionListTableContainer({ bodyshop, technician }) {
{} {}
); );
const columnState = useState( return <ProductionListTable loading={loading} data={data ? data.jobs : []} />;
(bodyshop.production_config &&
bodyshop.production_config.columnKeys.map((k) => {
return {
...ProductionListColumns({ technician }).find((e) => e.key === k.key),
width: k.width,
};
})) ||
[]
);
return (
<ProductionListTable
loading={loading}
data={data ? data.jobs : []}
columnState={columnState}
/>
);
} }

View File

@@ -130,6 +130,7 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
clm_total clm_total
ownr_ph1 ownr_ph1
special_coverage_policy special_coverage_policy
owner_owing
production_vars production_vars
kanbanparent kanbanparent
alt_transport alt_transport
@@ -743,6 +744,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
documents(limit: 3, order_by: { created_at: desc }) { documents(limit: 3, order_by: { created_at: desc }) {
id id
key key
type
} }
} }
} }
@@ -813,6 +815,7 @@ export const QUERY_TECH_JOB_DETAILS = gql`
id id
key key
size size
type
} }
} }
} }

View File

@@ -1,3 +1,4 @@
import moment from "moment";
export function alphaSort(a, b) { export function alphaSort(a, b) {
let A; let A;
let B; let B;
@@ -12,3 +13,13 @@ export function alphaSort(a, b) {
// if (A > B) return 1; // if (A > B) return 1;
// return 0; //default return value (no sorting) // return 0; //default return value (no sorting)
} }
export function dateSort(a, b) {
return moment(a).isBefore(moment(b));
// if (A < B)
// //sort string ascending
// return -1;
// if (A > B) return 1;
// return 0; //default return value (no sorting)
}