BOD-21 Initial creation of the production schedule list framework.

This commit is contained in:
Patrick Fic
2020-04-21 16:02:12 -07:00
parent 5303ab0114
commit f2fd1bf7eb
30 changed files with 2657 additions and 514 deletions

View File

@@ -0,0 +1,22 @@
import React from "react";
import { Transfer } from "antd";
import dataSource from "./production-list-columns.data";
export default function ProductionColumnsComponent({ columnState }) {
const [columns, setColumns] = columnState;
return (
<div>
<Transfer
dataSource={dataSource}
titles={["Source", "Target"]}
targetKeys={columns.map((c) => c.key)}
render={(item) => item.title}
onChange={(nextTargetKeys, direction, moveKeys) => {
setColumns(dataSource.filter((i) => nextTargetKeys.includes(i.key)));
}}
/>
</div>
);
}

View File

@@ -0,0 +1,158 @@
import i18n from "i18next";
import React from "react";
import { Link } from "react-router-dom";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter } from "../../utils/DateFormatter";
import PhoneFormatter from "../../utils/PhoneFormatter";
import { alphaSort } from "../../utils/sorters";
import { ExclamationCircleFilled } from "@ant-design/icons";
export default [
{
title: i18n.t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
ellipsis: true,
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
render: (text, record) => (
<Link to={`/manage/jobs/${record.id}`}>{record.ro_number}</Link>
),
},
{
title: i18n.t("jobs.fields.owner"),
dataIndex: "ownr",
key: "ownr",
ellipsis: true,
render: (text, record) => (
<span>{`${record.ownr_fn || ""} ${record.ownr_ln || ""} ${
record.ownr_co_nm || ""
}`}</span>
),
sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
},
{
title: i18n.t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
render: (text, record) => (
<span>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
} ${record.v_color || ""} ${record.plate_no || ""}`}</span>
),
},
{
title: i18n.t("jobs.fields.actual_in"),
dataIndex: "actual_in",
key: "actual_in",
ellipsis: true,
sorter: (a, b) => a.actual_in - b.actual_in,
render: (text, record) => (
<DateFormatter>{record.actual_in || ""}</DateFormatter>
),
},
{
title: i18n.t("jobs.fields.scheduled_completion"),
dataIndex: "scheduled_completion",
key: "scheduled_completion",
ellipsis: true,
sorter: (a, b) => a.scheduled_completion - b.scheduled_completion,
render: (text, record) => (
<DateFormatter>{record.scheduled_completion}</DateFormatter>
),
},
{
title: i18n.t("jobs.fields.scheduled_delivery"),
dataIndex: "scheduled_delivery",
key: "scheduled_delivery",
ellipsis: true,
sorter: (a, b) => a.scheduled_delivery - b.scheduled_delivery,
render: (text, record) => (
<DateFormatter>{record.scheduled_delivery}</DateFormatter>
),
},
{
title: i18n.t("jobs.fields.ins_co_nm"),
dataIndex: "ins_co_nm",
key: "ins_co_nm",
ellipsis: true,
sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm),
},
{
title: i18n.t("jobs.fields.clm_no"),
dataIndex: "clm_no",
key: "clm_no",
ellipsis: true,
sorter: (a, b) => alphaSort(a.clm_no, b.clm_no),
},
{
title: i18n.t("jobs.fields.clm_total"),
dataIndex: "clm_total",
key: "clm_total",
ellipsis: true,
sorter: (a, b) => a.clm_total - b.clm_total,
render: (text, record) => (
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
),
},
{
title: i18n.t("jobs.fields.owner_owing"),
dataIndex: "owner_owing",
key: "owner_owing",
ellipsis: true,
sorter: (a, b) => a.owner_owing - b.owner_owing,
render: (text, record) => (
<CurrencyFormatter>{record.owner_owing}</CurrencyFormatter>
),
},
{
title: i18n.t("jobs.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
ellipsis: true,
render: (text, record) => (
<PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>
),
},
{
title: i18n.t("jobs.fields.specialcoveragepolicy"),
dataIndex: "special_coverage_policy",
key: "special_coverage_policy",
ellipsis: true,
},
{
title: i18n.t("jobs.fields.csr"),
dataIndex: "csr",
key: "csr",
ellipsis: true,
sorter: (a, b) => alphaSort(a.csr, b.csr),
},
{
title: i18n.t("jobs.fields.status"),
dataIndex: "status",
key: "status",
ellipsis: true,
},
{
title: i18n.t("production.labels.alert"),
dataIndex: "alert",
key: "alert",
render: (text, record) => (
<div>
{record.production_vars && record.production_vars.alert ? (
<ExclamationCircleFilled style={{ color: "red" }} />
) : null}
</div>
),
},
{
title: i18n.t("production.labels.note"),
dataIndex: "note",
key: "note",
render: (text, record) => (
<span>
{(record.production_vars && record.production_vars.note) || ""}
</span>
),
},
];

View File

@@ -0,0 +1,52 @@
import { useMutation } from "@apollo/react-hooks";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { Button } from "antd";
import { useTranslation } from "react-i18next";
import { UPDATE_SHOP } from "../../graphql/bodyshop.queries";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function ProductionListSaveConfigButton({
columns,
bodyshop,
tableState,
}) {
const [updateShop] = useMutation(UPDATE_SHOP);
const { t } = useTranslation();
const handleSaveConfig = () => {
updateShop({
variables: {
id: bodyshop.id,
shop: {
production_config: {
columnKeys: columns.map((i) => i.key),
tableState,
},
},
},
}).then((response) => {
const shopDetails = response.data.update_bodyshops.returning[0];
console.log("handleSaveConfig -> shopDetails", shopDetails);
});
};
return (
<Button onClick={() => handleSaveConfig()}>
{t("production.actions.saveconfig")}
</Button>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductionListSaveConfigButton);

View File

@@ -0,0 +1,70 @@
import { Table, Button } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { SyncOutlined } from "@ant-design/icons";
import ProductionListSaveConfigButton from "../production-list-save-config-button/production-list-save-config-button.component";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function ProductionListTable({
columns,
loading,
data,
bodyshop,
refetch,
}) {
const [state, setState] = useState(
bodyshop.production_config.tableState || {
sortedInfo: {},
filteredInfo: { text: "" },
}
);
console.log("Filter State", state);
const { t } = useTranslation();
const handleTableChange = (pagination, filters, sorter) => {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
if (!!!columns) return <div>No columns found.</div>;
return (
<Table
size="small"
title={() => (
<div>
<ProductionListSaveConfigButton
columns={columns}
tableState={state}
/>
<Button onClick={() => refetch()}>
<SyncOutlined />
</Button>
</div>
)}
pagination={{ position: "top" }}
columns={columns.map((c) => {
return {
...c,
sortOrder:
state.sortedInfo.columnKey === c.key && state.sortedInfo.order,
};
})}
rowKey="id"
loading={loading}
dataSource={data}
onChange={handleTableChange}
/>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductionListTable);

View File

@@ -0,0 +1,24 @@
import { useQuery } from "@apollo/react-hooks";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { QUERY_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import ProductionListTable from "./production-list-table.component";
export default function ProductionListTableContainer({ columnState }) {
const { loading, data, refetch } = useQuery(QUERY_JOBS_IN_PRODUCTION, {
pollInterval: 30000,
});
return (
<div>
<ProductionListTable
loading={loading}
data={data ? data.jobs : []}
refetch={refetch}
columns={columnState[0]}
/>
</div>
);
}