From 2a1cb3fb9ff6d726f5b93ea3067b0cda258199b8 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 1 Apr 2020 10:48:53 -0700 Subject: [PATCH] BOD-17 Added Contracts list page + updates and bugfixes on other pages. --- bodyshop_translations.babel | 28 ++++- .../contracts-list.component.jsx | 102 ++++++++++++++++++ .../courtesy-cars-list.component.jsx | 2 +- .../jobs-detail-header-actions.component.jsx | 30 ++++++ .../jobs-detail-header.component.jsx | 8 +- client/src/graphql/cccontracts.queries.js | 33 ++++++ client/src/graphql/jobs.queries.js | 1 + .../contract-create.page.container.jsx | 13 ++- .../contract-detail.page.container.jsx | 2 +- .../contracts/contracts.page.component.jsx | 10 ++ .../contracts/contracts.page.container.jsx | 19 ++++ .../pages/manage/manage.page.component.jsx | 6 +- client/src/translations/en_us/common.json | 5 +- client/src/translations/es/common.json | 5 +- client/src/translations/fr/common.json | 5 +- 15 files changed, 253 insertions(+), 16 deletions(-) create mode 100644 client/src/components/contracts-list/contracts-list.component.jsx create mode 100644 client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx create mode 100644 client/src/pages/contracts/contracts.page.component.jsx create mode 100644 client/src/pages/contracts/contracts.page.container.jsx diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 5fa60d411..7a2e7ce18 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -2561,7 +2561,7 @@ - successess + successes saved @@ -9130,6 +9130,32 @@ + + jobsactions + + + newcccontract + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + jobsdetail diff --git a/client/src/components/contracts-list/contracts-list.component.jsx b/client/src/components/contracts-list/contracts-list.component.jsx new file mode 100644 index 000000000..3a0ee8eaf --- /dev/null +++ b/client/src/components/contracts-list/contracts-list.component.jsx @@ -0,0 +1,102 @@ +import { Table } from "antd"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Link } from "react-router-dom"; +import { alphaSort } from "../../utils/sorters"; +import { DateFormatter } from "../../utils/DateFormatter"; + +export default function ContractsList({ loading, contracts }) { + const [state, setState] = useState({ + sortedInfo: {}, + filteredInfo: { text: "" } + }); + + const { t } = useTranslation(); + + const columns = [ + { + title: t("contracts.fields.agreementnumber"), + dataIndex: "agreementnumber", + key: "agreementnumber", + sorter: (a, b) => a.agreementnumber - b.agreementnumber, + sortOrder: + state.sortedInfo.columnKey === "agreementnumber" && + state.sortedInfo.order, + render: (text, record) => ( + + {record.agreementnumber || ""} + + ) + }, + { + title: t("jobs.fields.ro_number"), + dataIndex: "job.ro_number", + key: "job.ro_number", + sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), + sortOrder: + state.sortedInfo.columnKey === "job.ro_number" && + state.sortedInfo.order, + render: (text, record) => ( + + {record.job.ro_number || ""} + + ) + }, + { + title: t("contracts.fields.driver"), + dataIndex: "driver_ln", + key: "driver_ln", + sorter: (a, b) => alphaSort(a.driver_ln, b.driver_ln), + sortOrder: + state.sortedInfo.columnKey === "driver_ln" && state.sortedInfo.order, + render: (text, record) => + `${record.driver_fn || ""} ${record.driver_ln || ""}` + }, + { + title: t("contracts.fields.status"), + dataIndex: "status", + key: "status", + sorter: (a, b) => alphaSort(a.status, b.status), + sortOrder: + state.sortedInfo.columnKey === "status" && state.sortedInfo.order, + render: (text, record) => t(record.status) + }, + { + title: t("contracts.fields.start"), + dataIndex: "start", + key: "start", + sorter: (a, b) => alphaSort(a.start, b.start), + sortOrder: + state.sortedInfo.columnKey === "start" && state.sortedInfo.order, + render: (text, record) => {record.start} + }, + { + title: t("contracts.fields.scheduledreturn"), + dataIndex: "scheduledreturn", + key: "scheduledreturn", + sorter: (a, b) => alphaSort(a.scheduledreturn, b.scheduledreturn), + sortOrder: + state.sortedInfo.columnKey === "scheduledreturn" && + state.sortedInfo.order, + render: (text, record) => ( + {record.scheduledreturn} + ) + } + ]; + + const handleTableChange = (pagination, filters, sorter) => { + setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); + }; + + return ( + ({ ...item }))} + rowKey="id" + dataSource={contracts} + onChange={handleTableChange} + /> + ); +} diff --git a/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx b/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx index 9d31150d4..5fa6e003e 100644 --- a/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx +++ b/client/src/components/courtesy-cars-list/courtesy-cars-list.component.jsx @@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import { alphaSort } from "../../utils/sorters"; -export default function JobsList({ loading, courtesycars }) { +export default function CourtesyCarsList({ loading, courtesycars }) { const [state, setState] = useState({ sortedInfo: {}, filteredInfo: { text: "" } diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx new file mode 100644 index 000000000..7b585db89 --- /dev/null +++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx @@ -0,0 +1,30 @@ +import React from "react"; +import { Menu, Dropdown, Button } from "antd"; +import { useTranslation } from "react-i18next"; +import { DownCircleFilled } from "@ant-design/icons"; +import { Link } from "react-router-dom"; + +export default function JobsDetailHeaderActions({ job }) { + const { t } = useTranslation(); + const statusmenu = ( + + + + {t("menus.jobsactions.newcccontract")} + + + + ); + return ( + + + + ); +} diff --git a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx index cd79fd4a8..03269ccd5 100644 --- a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx +++ b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx @@ -6,7 +6,6 @@ import { Checkbox, Descriptions, Dropdown, - List, Menu, notification, PageHeader, @@ -16,6 +15,7 @@ import React from "react"; import { useTranslation } from "react-i18next"; import Moment from "react-moment"; import { connect } from "react-redux"; +import { Link } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import CarImage from "../../assets/car.svg"; import { selectBodyshop } from "../../redux/user/user.selectors"; @@ -23,7 +23,7 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter"; import BarcodePopup from "../barcode-popup/barcode-popup.component"; import OwnerTagPopoverComponent from "../owner-tag-popover/owner-tag-popover.component"; import VehicleTagPopoverComponent from "../vehicle-tag-popover/vehicle-tag-popover.component"; -import { Link } from "react-router-dom"; +import JobsDetailHeaderActions from "../jobs-detail-header-actions/jobs-detail-header-actions.component"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop @@ -36,7 +36,6 @@ export default connect( job, mutationConvertJob, refetch, - handleFinish, scheduleModalState, bodyshop, updateJobStatus @@ -99,6 +98,7 @@ export default connect( > {t("jobs.actions.convert")} , + , @@ -156,7 +156,7 @@ export default connect( key={item.id} to={`/manage/courtesycars/contracts/${item.id}`} > -
{`${item.start} - ${item.scheduledreturn}`}
+
{`${item.agreementnumber} - ${item.start} - ${item.scheduledreturn}`}
))} diff --git a/client/src/graphql/cccontracts.queries.js b/client/src/graphql/cccontracts.queries.js index 8fab495ee..5cc47d328 100644 --- a/client/src/graphql/cccontracts.queries.js +++ b/client/src/graphql/cccontracts.queries.js @@ -74,3 +74,36 @@ export const QUERY_CONTRACT_BY_PK = gql` } } `; + +export const QUERY_ACTIVE_CONTRACTS = gql` + query QUERY_ACTIVE_CONTRACTS { + cccontracts(where: { status: { _neq: "contracts.status.returned" } }) { + agreementnumber + courtesycarid + driver_fn + driver_ln + driver_ph1 + id + jobid + job { + id + est_number + ro_number + ownr_fn + ownr_ln + ownr_co_nm + } + scheduledreturn + start + status + courtesycar { + id + fleetnumber + make + model + year + plate + } + } + } +`; diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index b24961d05..6e18f1e83 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -301,6 +301,7 @@ export const QUERY_JOB_CARD_DETAILS = gql` ded_amt cccontracts { id + agreementnumber status start scheduledreturn diff --git a/client/src/pages/contract-create/contract-create.page.container.jsx b/client/src/pages/contract-create/contract-create.page.container.jsx index 4f4515b8f..6a4163334 100644 --- a/client/src/pages/contract-create/contract-create.page.container.jsx +++ b/client/src/pages/contract-create/contract-create.page.container.jsx @@ -8,7 +8,7 @@ import { Form, notification } from "antd"; import { useTranslation } from "react-i18next"; import { INSERT_NEW_CONTRACT } from "../../graphql/cccontracts.queries"; import { useMutation } from "@apollo/react-hooks"; -import { useHistory } from "react-router-dom"; +import { useHistory, useLocation } from "react-router-dom"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop }); @@ -16,10 +16,15 @@ const mapStateToProps = createStructuredSelector({ export function ContractCreatePageContainer({ bodyshop }) { const [form] = Form.useForm(); const { t } = useTranslation(); - const selectedCarState = useState(null); - const selectedJobState = useState(null); - const [insertContract] = useMutation(INSERT_NEW_CONTRACT); const history = useHistory(); + const location = useLocation(); + const selectedCarState = useState(null); + const selectedJobState = useState( + (location.state && location.state.jobId) || null + ); + const [insertContract] = useMutation(INSERT_NEW_CONTRACT); + + console.log("location", location); const handleFinish = values => { if (!!selectedCarState[0] && !!selectedJobState[0]) { diff --git a/client/src/pages/contract-detail/contract-detail.page.container.jsx b/client/src/pages/contract-detail/contract-detail.page.container.jsx index b125bedf0..6842fd67c 100644 --- a/client/src/pages/contract-detail/contract-detail.page.container.jsx +++ b/client/src/pages/contract-detail/contract-detail.page.container.jsx @@ -36,7 +36,7 @@ export default function ContractDetailPageContainer() { variables: { cccontract: { ...values }, contractId: contractId } }) .then(response => { - notification["success"]({ message: t("contracts.successess.saved") }); + notification["success"]({ message: t("contracts.successes.saved") }); }) .catch(error => notification["error"]({ diff --git a/client/src/pages/contracts/contracts.page.component.jsx b/client/src/pages/contracts/contracts.page.component.jsx new file mode 100644 index 000000000..a881401eb --- /dev/null +++ b/client/src/pages/contracts/contracts.page.component.jsx @@ -0,0 +1,10 @@ +import React from "react"; +import ContractsList from "../../components/contracts-list/contracts-list.component"; + +export default function ContractsPageComponent({ loading, data }) { + return ( +
+ +
+ ); +} diff --git a/client/src/pages/contracts/contracts.page.container.jsx b/client/src/pages/contracts/contracts.page.container.jsx new file mode 100644 index 000000000..08fc143ff --- /dev/null +++ b/client/src/pages/contracts/contracts.page.container.jsx @@ -0,0 +1,19 @@ +import React from "react"; +import ContractsPageComponent from "./contracts.page.component"; +import { useQuery } from "@apollo/react-hooks"; +import { QUERY_ACTIVE_CONTRACTS } from "../../graphql/cccontracts.queries"; +import AlertComponent from "../../components/alert/alert.component"; + +export default function ContractsPageContainer() { + const { loading, error, data } = useQuery(QUERY_ACTIVE_CONTRACTS); + + if (error) return ; + return ( +
+ +
+ ); +} diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index add936f32..fed64173c 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -61,7 +61,9 @@ const ContractCreatePage = lazy(() => const ContractDetailPage = lazy(() => import("../contract-detail/contract-detail.page.container") ); - +const ContractsList = lazy(() => + import("../contracts/contracts.page.container") +); const { Header, Content, Footer } = Layout; export default function Manage({ match }) { @@ -117,7 +119,7 @@ export default function Manage({ match }) {
HOLD
} + component={ContractsList} />