BOD-17 Added Contracts list page + updates and bugfixes on other pages.
This commit is contained in:
@@ -2561,7 +2561,7 @@
|
|||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
<name>successess</name>
|
<name>successes</name>
|
||||||
<children>
|
<children>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>saved</name>
|
<name>saved</name>
|
||||||
@@ -9130,6 +9130,32 @@
|
|||||||
</concept_node>
|
</concept_node>
|
||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>jobsactions</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>newcccontract</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
</children>
|
||||||
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
<name>jobsdetail</name>
|
<name>jobsdetail</name>
|
||||||
<children>
|
<children>
|
||||||
|
|||||||
@@ -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) => (
|
||||||
|
<Link to={`/manage/courtesycars/contracts/${record.id}`}>
|
||||||
|
{record.agreementnumber || ""}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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) => (
|
||||||
|
<Link to={`/manage/jobs/${record.job.id}`}>
|
||||||
|
{record.job.ro_number || ""}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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) => <DateFormatter>{record.start}</DateFormatter>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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) => (
|
||||||
|
<DateFormatter>{record.scheduledreturn}</DateFormatter>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleTableChange = (pagination, filters, sorter) => {
|
||||||
|
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
loading={loading}
|
||||||
|
size="small"
|
||||||
|
pagination={{ position: "top" }}
|
||||||
|
columns={columns.map(item => ({ ...item }))}
|
||||||
|
rowKey="id"
|
||||||
|
dataSource={contracts}
|
||||||
|
onChange={handleTableChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { alphaSort } from "../../utils/sorters";
|
import { alphaSort } from "../../utils/sorters";
|
||||||
|
|
||||||
export default function JobsList({ loading, courtesycars }) {
|
export default function CourtesyCarsList({ loading, courtesycars }) {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
sortedInfo: {},
|
sortedInfo: {},
|
||||||
filteredInfo: { text: "" }
|
filteredInfo: { text: "" }
|
||||||
|
|||||||
@@ -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 = (
|
||||||
|
<Menu key="popovermenu">
|
||||||
|
<Menu.Item key="cccontract">
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
pathname: "/manage/courtesycars/contracts/new",
|
||||||
|
state: { jobId: job.id }
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("menus.jobsactions.newcccontract")}
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Dropdown overlay={statusmenu} key="changestatus">
|
||||||
|
<Button>
|
||||||
|
{t("general.labels.actions")} <DownCircleFilled />
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
Checkbox,
|
Checkbox,
|
||||||
Descriptions,
|
Descriptions,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
List,
|
|
||||||
Menu,
|
Menu,
|
||||||
notification,
|
notification,
|
||||||
PageHeader,
|
PageHeader,
|
||||||
@@ -16,6 +15,7 @@ import React from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Moment from "react-moment";
|
import Moment from "react-moment";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import CarImage from "../../assets/car.svg";
|
import CarImage from "../../assets/car.svg";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
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 BarcodePopup from "../barcode-popup/barcode-popup.component";
|
||||||
import OwnerTagPopoverComponent from "../owner-tag-popover/owner-tag-popover.component";
|
import OwnerTagPopoverComponent from "../owner-tag-popover/owner-tag-popover.component";
|
||||||
import VehicleTagPopoverComponent from "../vehicle-tag-popover/vehicle-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({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
@@ -36,7 +36,6 @@ export default connect(
|
|||||||
job,
|
job,
|
||||||
mutationConvertJob,
|
mutationConvertJob,
|
||||||
refetch,
|
refetch,
|
||||||
handleFinish,
|
|
||||||
scheduleModalState,
|
scheduleModalState,
|
||||||
bodyshop,
|
bodyshop,
|
||||||
updateJobStatus
|
updateJobStatus
|
||||||
@@ -99,6 +98,7 @@ export default connect(
|
|||||||
>
|
>
|
||||||
{t("jobs.actions.convert")}
|
{t("jobs.actions.convert")}
|
||||||
</Button>,
|
</Button>,
|
||||||
|
<JobsDetailHeaderActions key="actions" job={job} />,
|
||||||
<Button type="primary" key="submit" htmlType="submit">
|
<Button type="primary" key="submit" htmlType="submit">
|
||||||
{t("general.actions.save")}
|
{t("general.actions.save")}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -156,7 +156,7 @@ export default connect(
|
|||||||
key={item.id}
|
key={item.id}
|
||||||
to={`/manage/courtesycars/contracts/${item.id}`}
|
to={`/manage/courtesycars/contracts/${item.id}`}
|
||||||
>
|
>
|
||||||
<div>{`${item.start} - ${item.scheduledreturn}`}</div>
|
<div>{`${item.agreementnumber} - ${item.start} - ${item.scheduledreturn}`}</div>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -301,6 +301,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
|
|||||||
ded_amt
|
ded_amt
|
||||||
cccontracts {
|
cccontracts {
|
||||||
id
|
id
|
||||||
|
agreementnumber
|
||||||
status
|
status
|
||||||
start
|
start
|
||||||
scheduledreturn
|
scheduledreturn
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Form, notification } from "antd";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { INSERT_NEW_CONTRACT } from "../../graphql/cccontracts.queries";
|
import { INSERT_NEW_CONTRACT } from "../../graphql/cccontracts.queries";
|
||||||
import { useMutation } from "@apollo/react-hooks";
|
import { useMutation } from "@apollo/react-hooks";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
});
|
});
|
||||||
@@ -16,10 +16,15 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
export function ContractCreatePageContainer({ bodyshop }) {
|
export function ContractCreatePageContainer({ bodyshop }) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const selectedCarState = useState(null);
|
|
||||||
const selectedJobState = useState(null);
|
|
||||||
const [insertContract] = useMutation(INSERT_NEW_CONTRACT);
|
|
||||||
const history = useHistory();
|
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 => {
|
const handleFinish = values => {
|
||||||
if (!!selectedCarState[0] && !!selectedJobState[0]) {
|
if (!!selectedCarState[0] && !!selectedJobState[0]) {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export default function ContractDetailPageContainer() {
|
|||||||
variables: { cccontract: { ...values }, contractId: contractId }
|
variables: { cccontract: { ...values }, contractId: contractId }
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
notification["success"]({ message: t("contracts.successess.saved") });
|
notification["success"]({ message: t("contracts.successes.saved") });
|
||||||
})
|
})
|
||||||
.catch(error =>
|
.catch(error =>
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
|
|||||||
10
client/src/pages/contracts/contracts.page.component.jsx
Normal file
10
client/src/pages/contracts/contracts.page.component.jsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ContractsList from "../../components/contracts-list/contracts-list.component";
|
||||||
|
|
||||||
|
export default function ContractsPageComponent({ loading, data }) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ContractsList loading={loading} contracts={data} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
19
client/src/pages/contracts/contracts.page.container.jsx
Normal file
19
client/src/pages/contracts/contracts.page.container.jsx
Normal file
@@ -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 <AlertComponent message={error.message} type="error" />;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ContractsPageComponent
|
||||||
|
loading={loading}
|
||||||
|
data={data ? data.cccontracts : []}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -61,7 +61,9 @@ const ContractCreatePage = lazy(() =>
|
|||||||
const ContractDetailPage = lazy(() =>
|
const ContractDetailPage = lazy(() =>
|
||||||
import("../contract-detail/contract-detail.page.container")
|
import("../contract-detail/contract-detail.page.container")
|
||||||
);
|
);
|
||||||
|
const ContractsList = lazy(() =>
|
||||||
|
import("../contracts/contracts.page.container")
|
||||||
|
);
|
||||||
const { Header, Content, Footer } = Layout;
|
const { Header, Content, Footer } = Layout;
|
||||||
|
|
||||||
export default function Manage({ match }) {
|
export default function Manage({ match }) {
|
||||||
@@ -117,7 +119,7 @@ export default function Manage({ match }) {
|
|||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path={`${match.path}/courtesycars/contracts`}
|
path={`${match.path}/courtesycars/contracts`}
|
||||||
component={() => <div>HOLD</div>}
|
component={ContractsList}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
|
|||||||
@@ -173,7 +173,7 @@
|
|||||||
"out": "Out",
|
"out": "Out",
|
||||||
"returned": "Returned"
|
"returned": "Returned"
|
||||||
},
|
},
|
||||||
"successess": {
|
"successes": {
|
||||||
"saved": "Contract saved successfully. "
|
"saved": "Contract saved successfully. "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -581,6 +581,9 @@
|
|||||||
"shop_vendors": "Vendors",
|
"shop_vendors": "Vendors",
|
||||||
"vehicles": "Vehicles"
|
"vehicles": "Vehicles"
|
||||||
},
|
},
|
||||||
|
"jobsactions": {
|
||||||
|
"newcccontract": "Create Courtesy Car Contract"
|
||||||
|
},
|
||||||
"jobsdetail": {
|
"jobsdetail": {
|
||||||
"claimdetail": "Claim Details",
|
"claimdetail": "Claim Details",
|
||||||
"dates": "Dates",
|
"dates": "Dates",
|
||||||
|
|||||||
@@ -173,7 +173,7 @@
|
|||||||
"out": "",
|
"out": "",
|
||||||
"returned": ""
|
"returned": ""
|
||||||
},
|
},
|
||||||
"successess": {
|
"successes": {
|
||||||
"saved": ""
|
"saved": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -581,6 +581,9 @@
|
|||||||
"shop_vendors": "Vendedores",
|
"shop_vendors": "Vendedores",
|
||||||
"vehicles": "Vehículos"
|
"vehicles": "Vehículos"
|
||||||
},
|
},
|
||||||
|
"jobsactions": {
|
||||||
|
"newcccontract": ""
|
||||||
|
},
|
||||||
"jobsdetail": {
|
"jobsdetail": {
|
||||||
"claimdetail": "Detalles de la reclamación",
|
"claimdetail": "Detalles de la reclamación",
|
||||||
"dates": "fechas",
|
"dates": "fechas",
|
||||||
|
|||||||
@@ -173,7 +173,7 @@
|
|||||||
"out": "",
|
"out": "",
|
||||||
"returned": ""
|
"returned": ""
|
||||||
},
|
},
|
||||||
"successess": {
|
"successes": {
|
||||||
"saved": ""
|
"saved": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -581,6 +581,9 @@
|
|||||||
"shop_vendors": "Vendeurs",
|
"shop_vendors": "Vendeurs",
|
||||||
"vehicles": "Véhicules"
|
"vehicles": "Véhicules"
|
||||||
},
|
},
|
||||||
|
"jobsactions": {
|
||||||
|
"newcccontract": ""
|
||||||
|
},
|
||||||
"jobsdetail": {
|
"jobsdetail": {
|
||||||
"claimdetail": "Détails de la réclamation",
|
"claimdetail": "Détails de la réclamation",
|
||||||
"dates": "Rendez-vous",
|
"dates": "Rendez-vous",
|
||||||
|
|||||||
Reference in New Issue
Block a user