diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 9532b7e87..9074af3c9 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -10733,6 +10733,27 @@ forms + + admindates + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + appraiserinfo false @@ -10796,6 +10817,27 @@ + + estdates + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + inscoinfo false @@ -10859,6 +10901,48 @@ + + repairdates + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + scheddates + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + diff --git a/client/src/App/App.js b/client/src/App/App.js index ef66bb6d1..d8196d1e0 100644 --- a/client/src/App/App.js +++ b/client/src/App/App.js @@ -1,3 +1,4 @@ +import "antd/dist/antd.css"; import React, { lazy, Suspense, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -9,8 +10,8 @@ import LoadingSpinner from "../components/loading-spinner/loading-spinner.compon import { checkUserSession } from "../redux/user/user.actions"; import { selectCurrentUser } from "../redux/user/user.selectors"; import PrivateRoute from "../utils/private-route"; -import "antd/dist/antd.css"; import "./App.styles.scss"; +import { Grid } from "antd"; const LandingPage = lazy(() => import("../pages/landing/landing.page")); const ManagePage = lazy(() => import("../pages/manage/manage.page.container")); @@ -32,6 +33,9 @@ export function App({ checkUserSession, currentUser }) { checkUserSession(); }, [checkUserSession]); + const b = Grid.useBreakpoint(); + console.log("Breakpoints:", b); + const { t } = useTranslation(); if (currentUser.authorized === null) { diff --git a/client/src/App/App.styles.scss b/client/src/App/App.styles.scss index 362e2a58c..bab426d77 100644 --- a/client/src/App/App.styles.scss +++ b/client/src/App/App.styles.scss @@ -4,6 +4,7 @@ display: flex; flex-wrap: wrap; justify-content: center; + &__search { flex: 1; } @@ -21,4 +22,7 @@ &__margin { margin: 0.2rem 0.2rem; } + &__margin-large { + margin: 0.5rem 0.5rem; + } } diff --git a/client/src/components/data-label/data-label.component.jsx b/client/src/components/data-label/data-label.component.jsx new file mode 100644 index 000000000..3e28c056e --- /dev/null +++ b/client/src/components/data-label/data-label.component.jsx @@ -0,0 +1,25 @@ +import React from "react"; + +export default function DataLabel({ + label, + hideIfNull, + children, + vertical, + visible = true, + ...props +}) { + if (!visible || (hideIfNull && !!!children)) return null; + + return ( +
+
{`${label}: `}
+
+ {children} +
+
+ ); +} diff --git a/client/src/components/job-detail-cards/job-detail-cards.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.component.jsx index eb401d1ac..94a5f7c15 100644 --- a/client/src/components/job-detail-cards/job-detail-cards.component.jsx +++ b/client/src/components/job-detail-cards/job-detail-cards.component.jsx @@ -1,75 +1,99 @@ -import { - EditFilled, - FileImageFilled, - PrinterFilled, - ShoppingFilled -} from "@ant-design/icons"; +import { PrinterFilled } from "@ant-design/icons"; import { useQuery } from "@apollo/react-hooks"; -import { Button, PageHeader, Tag } from "antd"; +import { Button, Col, Drawer, Grid, PageHeader, Row, Tag } from "antd"; +import queryString from "query-string"; import React from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; -import { Link } from "react-router-dom"; +import { Link, useHistory, useLocation } from "react-router-dom"; import { QUERY_JOB_CARD_DETAILS } from "../../graphql/jobs.queries"; import { setModalContext } from "../../redux/modals/modals.actions"; import AlertComponent from "../alert/alert.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component"; -import NoteUpsertModal from "../note-upsert-modal/note-upsert-modal.container"; -import JobDetailCardsCustomerComponent from "./job-detail-cards.customer.component"; +import OwnerTagPopoverComponent from "../owner-tag-popover/owner-tag-popover.component"; +import VehicleTagPopoverComponent from "../vehicle-tag-popover/vehicle-tag-popover.component"; import JobDetailCardsDamageComponent from "./job-detail-cards.damage.component"; import JobDetailCardsDatesComponent from "./job-detail-cards.dates.component"; import JobDetailCardsDocumentsComponent from "./job-detail-cards.documents.component"; import JobDetailCardsInsuranceComponent from "./job-detail-cards.insurance.component"; import JobDetailCardsNotesComponent from "./job-detail-cards.notes.component"; import JobDetailCardsPartsComponent from "./job-detail-cards.parts.component"; -import "./job-detail-cards.styles.scss"; import JobDetailCardsTotalsComponent from "./job-detail-cards.totals.component"; const mapDispatchToProps = (dispatch) => ({ - setInvoiceEnterContext: (context) => - dispatch(setModalContext({ context: context, modal: "invoiceEnter" })), - setNoteUpsertContext: (context) => - dispatch(setModalContext({ context: context, modal: "noteUpsert" })), setPrintCenterContext: (context) => dispatch(setModalContext({ context: context, modal: "printCenter" })), }); -export function JobDetailCards({ - selectedJob, - setInvoiceEnterContext, - setNoteUpsertContext, - setPrintCenterContext, -}) { +const colBreakPoints = { + xs: { + span: 24, + }, + sm: { + span: 12, + }, +}; + +export function JobDetailCards({ setPrintCenterContext }) { + const selectedBreakpoint = Object.entries(Grid.useBreakpoint()) + .filter((screen) => !!screen[1]) + .slice(-1)[0]; + + const bpoints = { + xs: "100%", + sm: "100%", + md: "100%", + lg: "50%", + xl: "50%", + xxl: "45%", + }; + const drawerPercentage = selectedBreakpoint + ? bpoints[selectedBreakpoint[0]] + : "100%"; + + const searchParams = queryString.parse(useLocation().search); + const { selected } = searchParams; + const history = useHistory(); const { loading, error, data, refetch } = useQuery(QUERY_JOB_CARD_DETAILS, { fetchPolicy: "network-only", - variables: { id: selectedJob }, - skip: !selectedJob, + variables: { id: selected }, + skip: !selected, }); const { t } = useTranslation(); - - if (!selectedJob) { - return
{t("jobs.errors.nojobselected")}
; - } - if (loading) return ; - if (error) return ; + const handleDrawerClose = () => { + delete searchParams.selected; + history.push({ + search: queryString.stringify({ + ...searchParams, + }), + }); + }; return ( -
- - - {data.jobs_by_pk.status ? ( - {data.jobs_by_pk.status} - ) : null} - - } - title={ - loading ? ( - t("general.labels.loading") - ) : ( + The footer.
}> + {loading ? : null} + {error ? : null} + {data ? ( + , + , + + {t("jobs.labels.inproduction")} + , + ]} + title={ {data.jobs_by_pk.ro_number ? `${t("jobs.fields.ro_number")} ${data.jobs_by_pk.ro_number}` @@ -77,102 +101,70 @@ export function JobDetailCards({ data.jobs_by_pk.est_number }`} - ) - } - extra={[ - , - - - , - , - , - , - ]}> -
- - - - - - - - - -
-
- + }> + + + + + + + + + + + + + + + + + + + + + + + + + ) : null} + ); } export default connect(null, mapDispatchToProps)(JobDetailCards); diff --git a/client/src/components/job-detail-cards/job-detail-cards.customer.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.customer.component.jsx deleted file mode 100644 index 76acbb7c3..000000000 --- a/client/src/components/job-detail-cards/job-detail-cards.customer.component.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from "react"; -import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; -import PhoneFormatter from "../../utils/PhoneFormatter"; -import CardTemplate from "./job-detail-cards.template.component"; - -export default function JobDetailCardsCustomerComponent({ loading, data }) { - const { t } = useTranslation(); - - return ( - - {data ? ( - -
- {`${data.ownr_fn || - ""} ${data.ownr_ln || ""}`} -
-
- {t("jobs.fields.phoneshort")}: - {`${data.ownr_ph1 || - t("general.labels.na")}`} -
-
- {t("jobs.fields.ownr_ea")}: - {data.ownr_ea ? ( - - {`${data.ownr_ea || ""}`} - - ) : ( - t("general.labels.na") - )} -
-
{`${(data.owner && data.owner.preferred_contact) || ""}`}
-
- {data.vehicle ? ( - - {`${data.v_model_yr || ""} ${data.v_make_desc || - ""} ${data.v_model_desc || ""}`} - a - - ) : ( - - {`${data.v_model_yr || ""} ${data.v_make_desc || - ""} ${data.v_model_desc || ""}`} - b - - )} - e -
-
- ) : null} -
- ); -} diff --git a/client/src/components/job-detail-cards/job-detail-cards.dates.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.dates.component.jsx index 5c0b7fff8..c5155d058 100644 --- a/client/src/components/job-detail-cards/job-detail-cards.dates.component.jsx +++ b/client/src/components/job-detail-cards/job-detail-cards.dates.component.jsx @@ -27,87 +27,86 @@ export default function JobDetailCardsDatesComponent({ loading, data }) { ) ? (
{t("jobs.errors.nodates")}
) : null} + {data.date_open ? ( + + + {data.date_open} + + ) : null} + + {data.date_estimated ? ( + + + {data.date_estimated} + + ) : null} + + {data.date_scheduled ? ( + + + {data.date_scheduled} + + ) : null} + + {data.scheduled_in ? ( + + + {data.scheduled_in} + + ) : null} {data.actual_in ? ( - {t("jobs.fields.actual_in")} + {data.actual_in} ) : null} {data.scheduled_completion ? ( - {t("jobs.fields.scheduled_completion")} + {data.scheduled_completion} ) : null} - {data.scheduled_in ? ( - - {t("jobs.fields.scheduled_in")} - {data.scheduled_in} - - ) : null} - {data.actual_completion ? ( - {t("jobs.fields.actual_completion")} + {data.actual_completion} ) : null} {data.scheduled_delivery ? ( - {t("jobs.fields.scheduled_delivery")} + {data.scheduled_delivery} ) : null} {data.actual_delivery ? ( - {t("jobs.fields.actual_delivery")} + {data.actual_delivery} ) : null} - {data.date_estimated ? ( - - {t("jobs.fields.date_estimated")} - {data.date_estimated} - - ) : null} - - {data.date_open ? ( - - {t("jobs.fields.date_open")} - {data.date_open} - - ) : null} - - {data.date_scheduled ? ( - - {t("jobs.fields.date_scheduled")} - {data.date_scheduled} - - ) : null} - {data.date_invoiced ? ( - {t("jobs.fields.date_invoiced")} + {data.date_invoiced} ) : null} {data.date_closed ? ( - {t("jobs.fields.date_closed")} + {data.date_closed} ) : null} {data.date_exported ? ( - {t("jobs.fields.date_exported")} + {data.date_exported} ) : null} diff --git a/client/src/components/job-detail-cards/job-detail-cards.documents.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.documents.component.jsx index 4cdec4c27..3fd8ad8a4 100644 --- a/client/src/components/job-detail-cards/job-detail-cards.documents.component.jsx +++ b/client/src/components/job-detail-cards/job-detail-cards.documents.component.jsx @@ -1,7 +1,6 @@ import { Carousel } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; -import "./job-detail-cards.styles.scss"; import CardTemplate from "./job-detail-cards.template.component"; export default function JobDetailCardsDocumentsComponent({ loading, data }) { diff --git a/client/src/components/job-detail-cards/job-detail-cards.insurance.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.insurance.component.jsx index 5e29e3fdb..281b9369a 100644 --- a/client/src/components/job-detail-cards/job-detail-cards.insurance.component.jsx +++ b/client/src/components/job-detail-cards/job-detail-cards.insurance.component.jsx @@ -1,8 +1,7 @@ import React from "react"; import { useTranslation } from "react-i18next"; +import DataLabel from "../data-label/data-label.component"; import CardTemplate from "./job-detail-cards.template.component"; -import PhoneFormatter from "../../utils/PhoneFormatter"; - export default function JobDetailCardsInsuranceComponent({ loading, data }) { const { t } = useTranslation(); @@ -10,10 +9,15 @@ export default function JobDetailCardsInsuranceComponent({ loading, data }) { {data ? ( -
{data.ins_co_nm || t("general.labels.unknown")}
-
{data.clm_no || t("general.labels.unknown")}
- - - - -
- {t("jobs.labels.cards.estimator")} - {data.est_ea ? ( + + + {data.ins_ea ? (
{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}
) : (
{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}
)} - {data.est_ph1 ? ( - {data.est_ph1} - ) : null} -
+
) : null}
diff --git a/client/src/components/job-detail-cards/job-detail-cards.styles.scss b/client/src/components/job-detail-cards/job-detail-cards.styles.scss deleted file mode 100644 index 33f1d1eff..000000000 --- a/client/src/components/job-detail-cards/job-detail-cards.styles.scss +++ /dev/null @@ -1,31 +0,0 @@ -.job-cards { - display: flex; - flex-wrap: wrap; -} - -.job-card { - margin: 0.5em; -} - -@media screen and (min-width: 40em) { - .card { - max-width: calc(50% - 1em); - } -} - -@media screen and (min-width: 60em) { - .card { - max-width: calc(25% - 1em); - } -} - -.centered { - margin: 0 auto; - padding: 0 1em; -} - -@media screen and (min-width: 52em) { - .centered { - max-width: 52em; - } -} diff --git a/client/src/components/job-detail-cards/job-detail-cards.template.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.template.component.jsx index 30a854346..a2e9e78aa 100644 --- a/client/src/components/job-detail-cards/job-detail-cards.template.component.jsx +++ b/client/src/components/job-detail-cards/job-detail-cards.template.component.jsx @@ -9,16 +9,14 @@ export default function JobDetailCardTemplate({ ...otherProps }) { let extra; - if (extraLink) extra = { extra: More }; + if (extraLink) extra = { extra: More }; return ( + {...extra}> {otherProps.children} ); diff --git a/client/src/components/job-detail-cards/job-detail-cards.totals.component.jsx b/client/src/components/job-detail-cards/job-detail-cards.totals.component.jsx index eb82564e7..e1e9768bd 100644 --- a/client/src/components/job-detail-cards/job-detail-cards.totals.component.jsx +++ b/client/src/components/job-detail-cards/job-detail-cards.totals.component.jsx @@ -1,17 +1,44 @@ +import { Statistic } from "antd"; +import Dinero from "dinero.js"; import React from "react"; import { useTranslation } from "react-i18next"; import CardTemplate from "./job-detail-cards.template.component"; export default function JobDetailCardsTotalsComponent({ loading, data }) { const { t } = useTranslation(); + let totals; + + try { + totals = JSON.parse(data.job_totals); + } catch (error) { + console.log("Error in CardsTotal component", error); + } return ( - {data ? ( - - Totals stuff here. - - ) : null} + {totals ? ( +
+ + + +
+ ) : ( + t("jobs.errors.nofinancial") + )}
); } diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx index 1cab65ce9..1b64c1214 100644 --- a/client/src/components/job-detail-lines/job-lines.component.jsx +++ b/client/src/components/job-detail-lines/job-lines.component.jsx @@ -1,16 +1,16 @@ -import { Button, Input, Table, Dropdown, Menu } from "antd"; +import { Button, Dropdown, Input, Menu, Table } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Link } from "react-router-dom"; import { setModalContext } from "../../redux/modals/modals.actions"; +import { onlyUnique } from "../../utils/arrayHelper"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { alphaSort } from "../../utils/sorters"; import AllocationsAssignmentContainer from "../allocations-assignment/allocations-assignment.container"; import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container"; import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container"; import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container"; -import { onlyUnique } from "../../utils/arrayHelper"; const mapDispatchToProps = (dispatch) => ({ setJobLineEditContext: (context) => diff --git a/client/src/components/job-totals-table/job-totals-table.component.jsx b/client/src/components/job-totals-table/job-totals-table.component.jsx index bde7fbf45..37426d850 100644 --- a/client/src/components/job-totals-table/job-totals-table.component.jsx +++ b/client/src/components/job-totals-table/job-totals-table.component.jsx @@ -22,7 +22,6 @@ export function JobsTotalsTableComponent({ bodyshop, job }) { }, [bodyshop, job]); if (!!!totals) { - console.log("Totals was falsey."); return ; } @@ -179,7 +178,17 @@ export function JobsTotalsTableComponent({ bodyshop, job }) { -
+
{ + if (e.detail === 3) { + try { + console.log("Job", job); + } catch { + console.log("Unable to show job."); + } + } + }}> - - - diff --git a/client/src/components/jobs-detail-dates/jobs-detail-dates.component.jsx b/client/src/components/jobs-detail-dates/jobs-detail-dates.component.jsx index fe6355e23..61b031ab8 100644 --- a/client/src/components/jobs-detail-dates/jobs-detail-dates.component.jsx +++ b/client/src/components/jobs-detail-dates/jobs-detail-dates.component.jsx @@ -2,61 +2,70 @@ import { DatePicker, Form } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component"; +import FormRow from "../layout-form-row/layout-form-row.component"; export default function JobsDetailDatesComponent({ job }) { const { t } = useTranslation(); return (
- - - - CAA # seems not correct based on field mapping Class seems not correct - based on field mapping - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
); } diff --git a/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx b/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx index 61191031b..89dbd8792 100644 --- a/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx +++ b/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx @@ -25,8 +25,6 @@ export default function JobsDetailInsurance({ job, form }) { -
- diff --git a/client/src/components/jobs-list/jobs-list.component.jsx b/client/src/components/jobs-list/jobs-list.component.jsx index 865af88e0..cc79d6913 100644 --- a/client/src/components/jobs-list/jobs-list.component.jsx +++ b/client/src/components/jobs-list/jobs-list.component.jsx @@ -1,24 +1,35 @@ -import { Button, Input, Table } from "antd"; import { SyncOutlined } from "@ant-design/icons"; +import { useQuery } from "@apollo/react-hooks"; +import { Button, Input, Table } from "antd"; +import queryString from "query-string"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; -import { Link, withRouter } from "react-router-dom"; +import { connect } from "react-redux"; +import { Link, useHistory, useLocation } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import { onlyUnique } from "../../utils/arrayHelper"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import PhoneFormatter from "../../utils/PhoneFormatter"; import { alphaSort } from "../../utils/sorters"; +import AlertComponent from "../alert/alert.component"; import StartChatButton from "../chat-open-button/chat-open-button.component"; -import { useHistory } from "react-router-dom"; -import queryString from "query-string"; -export default withRouter(function JobsList({ - searchTextState, - refetch, - loading, - jobs, - searchParams, -}) { +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop, +}); + +export function JobsList({ bodyshop }) { + const searchParams = queryString.parse(useLocation().search); const { selected } = searchParams; + const { loading, error, data, refetch } = useQuery(QUERY_ALL_ACTIVE_JOBS, { + variables: { + statuses: bodyshop.md_ro_statuses.open_statuses || ["Open", "Open*"], + }, + }); + const [state, setState] = useState({ sortedInfo: {}, filteredInfo: { text: "" }, @@ -26,7 +37,55 @@ export default withRouter(function JobsList({ const { t } = useTranslation(); const history = useHistory(); - const setSearchText = searchTextState[1]; + const [searchText, setSearchText] = useState(""); + + if (error) return ; + + const jobs = data + ? searchText === "" + ? data.jobs + : data.jobs.filter( + (j) => + (j.ro_number || "") + .toString() + .toLowerCase() + .includes(searchText.toLowerCase()) || + (j.ownr_fn || "") + .toLowerCase() + .includes(searchText.toLowerCase()) || + (j.ownr_ln || "") + .toLowerCase() + .includes(searchText.toLowerCase()) || + (j.clm_no || "").toLowerCase().includes(searchText.toLowerCase()) || + (j.plate_no || "") + .toLowerCase() + .includes(searchText.toLowerCase()) || + (j.v_model_desc || "") + .toLowerCase() + .includes(searchText.toLowerCase()) || + (j.v_make_desc || "") + .toLowerCase() + .includes(searchText.toLowerCase()) + ) + : []; + + const handleTableChange = (pagination, filters, sorter) => { + setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); + }; + + const handleOnRowClick = (record) => { + if (record) { + if (record.id) { + history.push({ + search: queryString.stringify({ + ...searchParams, + selected: record.id, + }), + }); + } + } + }; + const columns = [ { title: t("jobs.fields.ro_number"), @@ -91,6 +150,19 @@ export default withRouter(function JobsList({ sorter: (a, b) => alphaSort(a.status, b.status), sortOrder: state.sortedInfo.columnKey === "status" && state.sortedInfo.order, + filters: + (jobs && + jobs + .map((j) => j.status) + .filter(onlyUnique) + .map((s) => { + return { + text: s || "No Status*", + value: [s], + }; + })) || + [], + onFilter: (value, record) => value.includes(record.status), render: (text, record) => { return record.status || t("general.labels.na"); }, @@ -167,69 +239,51 @@ export default withRouter(function JobsList({ }, ]; - const handleTableChange = (pagination, filters, sorter) => { - setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); - }; - - const handleOnRowClick = (record) => { - if (record) { - if (record.id) { - console.log("searchParams", searchParams); - history.push({ - search: queryString.stringify({ - ...searchParams, - selected: record.id, - }), - }); - } - } - }; - return ( -
- { - return ( -
- - { - setSearchText(e.target.value); - }} - enterButton - /> -
- ); - }} - size='small' - pagination={{ position: "top" }} - columns={columns.map((item) => ({ ...item }))} - rowKey='id' - dataSource={jobs} - rowSelection={{ - onSelect: (record) => { +
{ + return ( +
+ + { + setSearchText(e.target.value); + }} + vale={searchText} + enterButton + /> +
+ ); + }} + rowSelection={{ + onSelect: (record) => { + handleOnRowClick(record); + }, + selectedRowKeys: [selected], + type: "radio", + }} + onChange={handleTableChange} + onRow={(record, rowIndex) => { + return { + onClick: (event) => { handleOnRowClick(record); }, - selectedRowKeys: [selected], - type: "radio", - }} - onChange={handleTableChange} - onRow={(record, rowIndex) => { - return { - onClick: (event) => { - handleOnRowClick(record); - }, // click row - onDoubleClick: (event) => {}, // double click row - onContextMenu: (event) => {}, // right button click row - onMouseEnter: (event) => {}, // mouse enter row - onMouseLeave: (event) => {}, // mouse leave row - }; - }} - /> - + }; + }} + /> ); -}); +} + +export default connect(mapStateToProps, null)(JobsList); diff --git a/client/src/components/layout-form-row/layout-form-row.component.jsx b/client/src/components/layout-form-row/layout-form-row.component.jsx index 6ce27493b..65130b7ab 100644 --- a/client/src/components/layout-form-row/layout-form-row.component.jsx +++ b/client/src/components/layout-form-row/layout-form-row.component.jsx @@ -7,19 +7,24 @@ export default function LayoutFormRow({ header, children }) { //We have only one element. It's going to get the whole thing. return children; } - const rowGutter = { gutter: [32, 32] }; - const colSpan = (maxspan) => { + const rowGutter = { gutter: [16, 16] }; + + const colSpan = (spanOverride) => { return { xs: { span: 24, }, + sm: { + span: 12, + }, md: { - span: !!maxspan ? Math.min(12, maxspan) : 12, + span: 8, }, lg: { - span: !!maxspan - ? Math.min(Math.max(24 / children.length, 6), maxspan) - : Math.max(24 / children.length, 6), + span: 6, + }, + xl: { + span: 4, }, }; }; @@ -29,7 +34,7 @@ export default function LayoutFormRow({ header, children }) { {header ? {header} : null} {children.map((c, idx) => ( - + {c} ))} @@ -37,3 +42,40 @@ export default function LayoutFormRow({ header, children }) { ); } + +// export default function LayoutFormRow({ header, children }) { +// if (!!!children.length) { +// //We have only one element. It's going to get the whole thing. +// return children; +// } +// const rowGutter = { gutter: [16, 16] }; + +// const colSpan = (maxspan) => { +// return { +// xs: { +// span: 24, +// }, +// md: { +// span: !!maxspan ? Math.min(12, maxspan) : 12, +// }, +// lg: { +// span: !!maxspan +// ? Math.min(Math.max(24 / children.length, 6), maxspan) +// : Math.max(24 / children.length, 6), +// }, +// }; +// }; + +// return ( +//
+// {header ? {header} : null} +// +// {children.map((c, idx) => ( +//
+// {c} +// +// ))} +// +// +// ); +// } diff --git a/client/src/components/layout-form-row/layout-form-row.styles.scss b/client/src/components/layout-form-row/layout-form-row.styles.scss index 921828efa..faf24ccf1 100644 --- a/client/src/components/layout-form-row/layout-form-row.styles.scss +++ b/client/src/components/layout-form-row/layout-form-row.styles.scss @@ -2,5 +2,19 @@ .imex-form-row { .ant-row { margin-bottom: 0rem; + + .ant-form-item-label { + padding: 0rem; + } + + label { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; + display: inline-block; + padding: 0rem; + margin: 0rem; + } } } diff --git a/client/src/components/production-list-table/production-list-table.container.jsx b/client/src/components/production-list-table/production-list-table.container.jsx index e357807f9..b92fe8b0f 100644 --- a/client/src/components/production-list-table/production-list-table.container.jsx +++ b/client/src/components/production-list-table/production-list-table.container.jsx @@ -4,20 +4,13 @@ import { SUBSCRIPTION_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries"; import ProductionListTable from "./production-list-table.component"; export default function ProductionListTableContainer({ columnState }) { - // const { loading, data, refetch } = useQuery(QUERY_JOBS_IN_PRODUCTION, { - // pollInterval: 30000, - // }); - const { loading, data } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION); return ( - - - + ); } diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index d07ad8e1b..778beb580 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -324,11 +324,18 @@ export const QUERY_JOB_CARD_DETAILS = gql` est_ct_ln clm_no status + job_totals area_of_damage ro_number scheduled_completion scheduled_in scheduled_delivery + date_invoiced + date_open + date_exported + date_closed + date_scheduled + date_estimated notes { id text @@ -336,7 +343,6 @@ export const QUERY_JOB_CARD_DETAILS = gql` private created_at } - updated_at clm_total ded_amt diff --git a/client/src/pages/jobs/jobs.page.jsx b/client/src/pages/jobs/jobs.page.jsx index fdd2988fb..390b63b7c 100644 --- a/client/src/pages/jobs/jobs.page.jsx +++ b/client/src/pages/jobs/jobs.page.jsx @@ -1,88 +1,30 @@ -import { useQuery } from "@apollo/react-hooks"; -import queryString from "query-string"; -import React, { useEffect, useState } from "react"; +import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; -import { createStructuredSelector } from "reselect"; -import AlertComponent from "../../components/alert/alert.component"; -import EnterInvoiceModalContainer from "../../components/invoice-enter-modal/invoice-enter-modal.container"; import JobDetailCards from "../../components/job-detail-cards/job-detail-cards.component"; import JobsList from "../../components/jobs-list/jobs-list.component"; -import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries"; -import { selectBodyshop } from "../../redux/user/user.selectors"; - import { setBreadcrumbs } from "../../redux/application/application.actions"; -const mapStateToProps = createStructuredSelector({ - bodyshop: selectBodyshop, -}); - const mapDispatchToProps = (dispatch) => ({ setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), }); -export function JobsPage({ location, bodyshop, setBreadcrumbs }) { - const { loading, error, data, refetch } = useQuery(QUERY_ALL_ACTIVE_JOBS, { - variables: { - statuses: bodyshop.md_ro_statuses.open_statuses || ["Open"], - }, - }); +export function JobsPage({ setBreadcrumbs }) { const { t } = useTranslation(); useEffect(() => { document.title = t("titles.jobs"); - setBreadcrumbs([{ link: "/manage/jobs", label: t("titles.bc.jobs-active") }]); + setBreadcrumbs([ + { link: "/manage/jobs", label: t("titles.bc.jobs-active") }, + ]); }, [t, setBreadcrumbs]); - const search = queryString.parse(location.search); - const searchTextState = useState(""); - const searchText = searchTextState[0]; - if (error) return ; - return ( -
- - - (j.ro_number || "") - .toString() - .toLowerCase() - .includes(searchText.toLowerCase()) || - (j.ownr_fn || "") - .toLowerCase() - .includes(searchText.toLowerCase()) || - (j.ownr_ln || "") - .toLowerCase() - .includes(searchText.toLowerCase()) || - (j.clm_no || "") - .toLowerCase() - .includes(searchText.toLowerCase()) || - (j.plate_no || "") - .toLowerCase() - .includes(searchText.toLowerCase()) || - (j.v_model_desc || "") - .toLowerCase() - .includes(searchText.toLowerCase()) || - (j.v_make_desc || "") - .toLowerCase() - .includes(searchText.toLowerCase()) - ) - : null - } - /> - +
+ +
); } -export default connect(mapStateToProps, mapDispatchToProps)(JobsPage); +export default connect(null, mapDispatchToProps)(JobsPage); diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 7b147c8fa..9eab8fdcf 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -667,12 +667,16 @@ "vehicle": "Vehicle" }, "forms": { + "admindates": "Administrative Dates", "appraiserinfo": "Appraiser Info", "claiminfo": "Claim Information", "dedinfo": "Deductible Info", + "estdates": "Estimate Dates", "inscoinfo": "Insurance Company Information", "laborrates": "Labor Rates", - "lossinfo": "Loss Information" + "lossinfo": "Loss Information", + "repairdates": "Repair Dates", + "scheddates": "Schedule Dates" }, "labels": { "allocations": "Allocations", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index bb037f735..6bf9ece44 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -667,12 +667,16 @@ "vehicle": "Vehículo" }, "forms": { + "admindates": "", "appraiserinfo": "", "claiminfo": "", "dedinfo": "", + "estdates": "", "inscoinfo": "", "laborrates": "", - "lossinfo": "" + "lossinfo": "", + "repairdates": "", + "scheddates": "" }, "labels": { "allocations": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 8c3f69390..e255d2d54 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -667,12 +667,16 @@ "vehicle": "Véhicule" }, "forms": { + "admindates": "", "appraiserinfo": "", "claiminfo": "", "dedinfo": "", + "estdates": "", "inscoinfo": "", "laborrates": "", - "lossinfo": "" + "lossinfo": "", + "repairdates": "", + "scheddates": "" }, "labels": { "allocations": "",