Merged in release/2021-10-08 (pull request #241)

release/2021-10-08

Approved-by: Patrick Fic
This commit is contained in:
Patrick Fic
2021-10-05 18:48:13 +00:00
32 changed files with 7873 additions and 7734 deletions

View File

@@ -19569,6 +19569,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>date_last_contacted</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>
<concept_node> <concept_node>
<name>date_open</name> <name>date_open</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -22324,6 +22345,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>referral_source_other</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>
<concept_node> <concept_node>
<name>referralsource</name> <name>referralsource</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -4,35 +4,35 @@
"private": true, "private": true,
"proxy": "http://localhost:5000", "proxy": "http://localhost:5000",
"dependencies": { "dependencies": {
"@apollo/client": "^3.4.15", "@apollo/client": "^3.4.16",
"@craco/craco": "^6.3.0", "@craco/craco": "^6.3.0",
"@fingerprintjs/fingerprintjs": "^3.3.0", "@fingerprintjs/fingerprintjs": "^3.3.0",
"@lourenci/react-kanban": "^2.1.0", "@lourenci/react-kanban": "^2.1.0",
"@openreplay/tracker": "^3.4.1", "@openreplay/tracker": "^3.4.4",
"@openreplay/tracker-assist": "^3.4.0", "@openreplay/tracker-assist": "^3.4.3",
"@openreplay/tracker-graphql": "^3.0.0", "@openreplay/tracker-graphql": "^3.0.0",
"@openreplay/tracker-redux": "^3.0.0", "@openreplay/tracker-redux": "^3.0.0",
"@sentry/react": "^6.13.2", "@sentry/react": "^6.13.2",
"@sentry/tracing": "^6.13.2", "@sentry/tracing": "^6.13.2",
"@stripe/react-stripe-js": "^1.5.0", "@stripe/react-stripe-js": "^1.5.0",
"@stripe/stripe-js": "^1.18.0", "@stripe/stripe-js": "^1.19.1",
"@tanem/react-nprogress": "^3.0.79", "@tanem/react-nprogress": "^3.0.79",
"antd": "^4.16.13", "antd": "^4.16.13",
"apollo-link-logger": "^2.0.0", "apollo-link-logger": "^2.0.0",
"axios": "^0.21.4", "axios": "^0.22.0",
"craco-less": "^1.20.0", "craco-less": "^1.20.0",
"dinero.js": "^1.9.0", "dinero.js": "^1.9.0",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"enquire-js": "^0.2.1", "enquire-js": "^0.2.1",
"env-cmd": "^10.1.0", "env-cmd": "^10.1.0",
"exifr": "^7.1.3", "exifr": "^7.1.3",
"firebase": "^9.1.0", "firebase": "^9.1.1",
"graphql": "^15.6.0", "graphql": "^15.6.0",
"i18next": "^21.2.0", "i18next": "^21.2.4",
"i18next-browser-languagedetector": "^6.1.2", "i18next-browser-languagedetector": "^6.1.2",
"jsoneditor": "^9.5.6", "jsoneditor": "^9.5.6",
"jsreport-browser-client-dist": "^1.3.0", "jsreport-browser-client-dist": "^1.3.0",
"libphonenumber-js": "^1.9.34", "libphonenumber-js": "^1.9.36",
"logrocket": "^2.0.0", "logrocket": "^2.0.0",
"markerjs2": "^2.13.0", "markerjs2": "^2.13.0",
"moment-business-days": "^1.2.0", "moment-business-days": "^1.2.0",
@@ -43,7 +43,7 @@
"rc-queue-anim": "^2.0.0", "rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.7.6", "rc-scroll-anim": "^2.7.6",
"react": "^17.0.1", "react": "^17.0.1",
"react-big-calendar": "^0.36.0", "react-big-calendar": "^0.36.1",
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-cookie": "^4.1.1", "react-cookie": "^4.1.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
@@ -51,7 +51,7 @@
"react-grid-gallery": "^0.5.5", "react-grid-gallery": "^0.5.5",
"react-grid-layout": "^1.3.0", "react-grid-layout": "^1.3.0",
"react-i18next": "^11.12.0", "react-i18next": "^11.12.0",
"react-icons": "^4.2.0", "react-icons": "^4.3.1",
"react-number-format": "^4.7.3", "react-number-format": "^4.7.3",
"react-redux": "^7.2.5", "react-redux": "^7.2.5",
"react-resizable": "^3.0.4", "react-resizable": "^3.0.4",
@@ -114,7 +114,7 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@sentry/webpack-plugin": "^1.17.1", "@sentry/webpack-plugin": "^1.17.2",
"patch-package": "^6.4.7", "patch-package": "^6.4.7",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
"source-map-explorer": "^2.5.2" "source-map-explorer": "^2.5.2"

View File

@@ -12,7 +12,18 @@ const BillLineSearchSelect = ({ options, disabled, ...restProps }, ref) => {
disabled={disabled} disabled={disabled}
ref={ref} ref={ref}
showSearch showSearch
optionFilterProp="line_desc" // optionFilterProp="line_desc"
filterOption={(inputValue, option) => {
console.log(inputValue);
return (
(option.line_desc &&
option.line_desc
.toLowerCase()
.includes(inputValue.toLowerCase())) ||
(option.oem_partno &&
option.oem_partno.toLowerCase().includes(inputValue.toLowerCase()))
);
}}
notFoundContent={"Removed."} notFoundContent={"Removed."}
{...restProps} {...restProps}
> >
@@ -29,6 +40,7 @@ const BillLineSearchSelect = ({ options, disabled, ...restProps }, ref) => {
part_type={item.part_type} part_type={item.part_type}
line_desc={item.line_desc} line_desc={item.line_desc}
part_qty={item.part_qty} part_qty={item.part_qty}
oem_partno={item.oem_partno}
style={{ style={{
...(item.removed ? { textDecoration: "line-through" } : {}), ...(item.removed ? { textDecoration: "line-through" } : {}),
}} }}

View File

@@ -167,7 +167,11 @@ export function JobChecklistForm({
title={t("checklist.labels.checklist")} title={t("checklist.labels.checklist")}
extra={ extra={
!readOnly && ( !readOnly && (
<Button loading={loading} onClick={() => form.submit()}> <Button
loading={loading}
type="primary"
onClick={() => form.submit()}
>
{t("general.actions.submit")} {t("general.actions.submit")}
</Button> </Button>
) )

View File

@@ -112,60 +112,46 @@ export function JobDetailCards({ setPrintCenterContext }) {
<Divider type="horizontal" /> <Divider type="horizontal" />
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsInsuranceComponent
<JobDetailCardsInsuranceComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsTotalsComponent
<JobDetailCardsTotalsComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsDatesComponent
<JobDetailCardsDatesComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsPartsComponent
<JobDetailCardsPartsComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsNotesComponent
<JobDetailCardsNotesComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsDocumentsComponent
<JobDetailCardsDocumentsComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
<Col {...span}> <Col {...span}>
<Card.Grid style={{ width: "100%", height: "100%" }}> <JobDetailCardsDamageComponent
<JobDetailCardsDamageComponent loading={loading}
loading={loading} data={data ? data.jobs_by_pk : null}
data={data ? data.jobs_by_pk : null} />
/>
</Card.Grid>
</Col> </Col>
</Row> </Row>
</Card> </Card>

View File

@@ -1,7 +1,7 @@
import { Timeline } from "antd"; import { Timeline } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { DateFormatter } from "../../utils/DateFormatter"; import { DateTimeFormatter } from "../../utils/DateFormatter";
import CardTemplate from "./job-detail-cards.template.component"; import CardTemplate from "./job-detail-cards.template.component";
export default function JobDetailCardsDatesComponent({ loading, data }) { export default function JobDetailCardsDatesComponent({ loading, data }) {
@@ -26,80 +26,86 @@ export default function JobDetailCardsDatesComponent({ loading, data }) {
) ? ( ) ? (
<div>{t("jobs.errors.nodates")}</div> <div>{t("jobs.errors.nodates")}</div>
) : null} ) : null}
{data.date_last_contacted ? (
<Timeline.Item>
<label>{t("jobs.fields.date_last_contacted")}: </label>
<DateTimeFormatter>{data.date_last_contacted}</DateTimeFormatter>
</Timeline.Item>
) : null}
{data.date_open ? ( {data.date_open ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_open")}: </label> <label>{t("jobs.fields.date_open")}: </label>
<DateFormatter>{data.date_open}</DateFormatter> <DateTimeFormatter>{data.date_open}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_estimated ? ( {data.date_estimated ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_estimated")}: </label> <label>{t("jobs.fields.date_estimated")}: </label>
<DateFormatter>{data.date_estimated}</DateFormatter> <DateTimeFormatter>{data.date_estimated}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_scheduled ? ( {data.date_scheduled ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_scheduled")}: </label> <label>{t("jobs.fields.date_scheduled")}: </label>
<DateFormatter>{data.date_scheduled}</DateFormatter> <DateTimeFormatter>{data.date_scheduled}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.scheduled_in ? ( {data.scheduled_in ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.scheduled_in")}: </label> <label>{t("jobs.fields.scheduled_in")}: </label>
<DateFormatter>{data.scheduled_in}</DateFormatter> <DateTimeFormatter>{data.scheduled_in}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.actual_in ? ( {data.actual_in ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.actual_in")}: </label> <label>{t("jobs.fields.actual_in")}: </label>
<DateFormatter>{data.actual_in}</DateFormatter> <DateTimeFormatter>{data.actual_in}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.scheduled_completion ? ( {data.scheduled_completion ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.scheduled_completion")}: </label> <label>{t("jobs.fields.scheduled_completion")}: </label>
<DateFormatter>{data.scheduled_completion}</DateFormatter> <DateTimeFormatter>{data.scheduled_completion}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.actual_completion ? ( {data.actual_completion ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.actual_completion")}: </label> <label>{t("jobs.fields.actual_completion")}: </label>
<DateFormatter>{data.actual_completion}</DateFormatter> <DateTimeFormatter>{data.actual_completion}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.scheduled_delivery ? ( {data.scheduled_delivery ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.scheduled_delivery")}: </label> <label>{t("jobs.fields.scheduled_delivery")}: </label>
<DateFormatter>{data.scheduled_delivery}</DateFormatter> <DateTimeFormatter>{data.scheduled_delivery}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.actual_delivery ? ( {data.actual_delivery ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.actual_delivery")}: </label> <label>{t("jobs.fields.actual_delivery")}: </label>
<DateFormatter>{data.actual_delivery}</DateFormatter> <DateTimeFormatter>{data.actual_delivery}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_invoiced ? ( {data.date_invoiced ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_invoiced")}: </label> <label>{t("jobs.fields.date_invoiced")}: </label>
<DateFormatter>{data.date_invoiced}</DateFormatter> <DateTimeFormatter>{data.date_invoiced}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
{data.date_exported ? ( {data.date_exported ? (
<Timeline.Item> <Timeline.Item>
<label>{t("jobs.fields.date_exported")}: </label> <label>{t("jobs.fields.date_exported")}: </label>
<DateFormatter>{data.date_exported}</DateFormatter> <DateTimeFormatter>{data.date_exported}</DateTimeFormatter>
</Timeline.Item> </Timeline.Item>
) : null} ) : null}
</Timeline> </Timeline>

View File

@@ -1,8 +1,8 @@
import { Carousel } from "antd"; import { Carousel } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { GenerateThumbUrl } from "../jobs-documents-gallery/job-documents.utility";
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();
@@ -22,15 +22,7 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
{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} src={GenerateThumbUrl(item)} alt={item.name} />
key={item.id}
src={`${
process.env.REACT_APP_CLOUDINARY_ENDPOINT
}/${DetermineFileType(item.type)}/upload/${
process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS
}/${item.key}`}
alt={item.name}
/>
))} ))}
</Carousel> </Carousel>
) : ( ) : (

View File

@@ -12,11 +12,13 @@ export default function JobDetailCardTemplate({
if (extraLink) extra = { extra: <Link to={extraLink}>More</Link> }; if (extraLink) extra = { extra: <Link to={extraLink}>More</Link> };
return ( return (
<Card <Card
size='small' size="small"
className='job-card' className="job-card"
title={title} title={title}
loading={loading} loading={loading}
{...extra}> style={{ height: "100%" }}
{...extra}
>
{otherProps.children} {otherProps.children}
</Card> </Card>
); );

View File

@@ -36,6 +36,7 @@ import JobLinesBillRefernece from "../job-lines-bill-reference/job-lines-bill-re
// import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container"; // import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container";
// import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container"; // import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container"; import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
import _ from "lodash";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser //currentUser: selectCurrentUser
@@ -334,10 +335,12 @@ export function JobLinesComponent({
const markedTypes = [e.key]; const markedTypes = [e.key];
if (e.key === "PAN") markedTypes.push("PAP"); if (e.key === "PAN") markedTypes.push("PAP");
if (e.key === "PAS") markedTypes.push("PASL"); if (e.key === "PAS") markedTypes.push("PASL");
setSelectedLines([ setSelectedLines(
...selectedLines, _.uniq([
...jobLines.filter((item) => markedTypes.includes(item.part_type)), ...selectedLines,
]); ...jobLines.filter((item) => markedTypes.includes(item.part_type)),
])
);
} }
}; };

View File

@@ -74,7 +74,12 @@ export default function JobsAdminDatesChange({ job }) {
<Form.Item label={t("jobs.fields.actual_in")} name="actual_in"> <Form.Item label={t("jobs.fields.actual_in")} name="actual_in">
<DateTimePicker /> <DateTimePicker />
</Form.Item> </Form.Item>
<Form.Item
label={t("jobs.fields.date_last_contacted")}
name="date_last_contacted"
>
<DateTimePicker />
</Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.scheduled_completion")} label={t("jobs.fields.scheduled_completion")}
name="scheduled_completion" name="scheduled_completion"

View File

@@ -490,15 +490,14 @@ async function CheckTaxRates(estData, bodyshop) {
//IO-1387 If a sublet line is NOT R&R, use the labor tax. If it is, use the sublet tax rate. //IO-1387 If a sublet line is NOT R&R, use the labor tax. If it is, use the sublet tax rate.
//Currently limited to SK shops only. //Currently limited to SK shops only.
if (bodyshop.region_config === "CA_SK") { //if (bodyshop.region_config === "CA_SK") {
estData.joblines.data.forEach((jl, index) => { estData.joblines.data.forEach((jl, index) => {
if ( if (
(jl.part_type === "PASL" || jl.part_type === "PAS") && (jl.part_type === "PASL" || jl.part_type === "PAS") &&
jl.lbr_op !== "OP11" jl.lbr_op !== "OP11"
) { ) {
estData.joblines.data[index].tax_part = jl.lbr_tax; estData.joblines.data[index].tax_part = jl.lbr_tax;
console.log(estData.joblines.data[index], jl); }
} });
}); //}
}
} }

View File

@@ -69,6 +69,12 @@ export function JobsDetailDatesComponent({ jobRO, job, bodyshop }) {
</Tooltip> </Tooltip>
</FormRow> </FormRow>
<FormRow header={t("jobs.forms.repairdates")}> <FormRow header={t("jobs.forms.repairdates")}>
<Form.Item
label={t("jobs.fields.date_last_contacted")}
name="date_last_contacted"
>
<DateTimePicker />
</Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.scheduled_completion")} label={t("jobs.fields.scheduled_completion")}
name="scheduled_completion" name="scheduled_completion"
@@ -93,7 +99,6 @@ export function JobsDetailDatesComponent({ jobRO, job, bodyshop }) {
); );
}} }}
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.scheduled_delivery")} label={t("jobs.fields.scheduled_delivery")}
name="scheduled_delivery" name="scheduled_delivery"

View File

@@ -29,20 +29,6 @@ function JobsDocumentsComponent({
setIndex(index); setIndex(index);
}; };
// useEffect(() => {
// console.log("Added event listening for reteching.");
// window.addEventListener("storage", (ev) => {
// if (ev.key === "refetch" && ev.newValue === true) {
// refetch && refetch();
// localStorage.setItem("refetch", false);
// }
// });
// return () => {
// window.removeEventListener("storage");
// };
// }, [refetch]);
useEffect(() => { useEffect(() => {
let documents = data.reduce( let documents = data.reduce(
(acc, value) => { (acc, value) => {

View File

@@ -73,7 +73,7 @@ export default function PartsOrderModalComponent({
<Form.Item required={false} key={field.key}> <Form.Item required={false} key={field.key}>
<LayoutFormRow grow noDivider> <LayoutFormRow grow noDivider>
<Form.Item <Form.Item
span={8} //span={8}
label={t("parts_orders.fields.line_desc")} label={t("parts_orders.fields.line_desc")}
key={`${index}line_desc`} key={`${index}line_desc`}
name={[field.name, "line_desc"]} name={[field.name, "line_desc"]}
@@ -132,19 +132,21 @@ export default function PartsOrderModalComponent({
</Form.Item> </Form.Item>
)} )}
<div> <Space wrap align="center">
<DeleteFilled <div>
style={{ margin: "1rem" }} <DeleteFilled
onClick={() => { style={{ margin: "1rem" }}
remove(field.name); onClick={() => {
}} remove(field.name);
/> }}
/>
</div>
<FormListMoveArrows <FormListMoveArrows
move={move} move={move}
index={index} index={index}
total={fields.length} total={fields.length}
/> />
</div> </Space>
</LayoutFormRow> </LayoutFormRow>
</Form.Item> </Form.Item>
))} ))}

View File

@@ -260,7 +260,7 @@ export function PartsOrderModalContainer({
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}
onOk={() => form.submit()} onOk={() => form.submit()}
destroyOnClose destroyOnClose
width="50%" width="75%"
forceRender forceRender
> >
{error ? <AlertComponent message={error.message} type="error" /> : null} {error ? <AlertComponent message={error.message} type="error" /> : null}

View File

@@ -97,6 +97,19 @@ const r = ({ technician, state }) => {
<ProductionListDate record={record} field="scheduled_completion" /> <ProductionListDate record={record} field="scheduled_completion" />
), ),
}, },
{
title: i18n.t("jobs.fields.date_last_contacted"),
dataIndex: "date_last_contacted",
key: "date_last_contacted",
ellipsis: true,
sorter: (a, b) => dateSort(a.date_last_contacted, b.date_last_contacted),
sortOrder:
state.sortedInfo.columnKey === "date_last_contacted" &&
state.sortedInfo.order,
render: (text, record) => (
<ProductionListDate time record={record} field="date_last_contacted" />
),
},
{ {
title: i18n.t("jobs.fields.scheduled_delivery"), title: i18n.t("jobs.fields.scheduled_delivery"),
dataIndex: "scheduled_delivery", dataIndex: "scheduled_delivery",

View File

@@ -1,17 +1,20 @@
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import { DatePicker, Dropdown } from "antd"; import { DatePicker, Dropdown, TimePicker, Button, Card } from "antd";
import moment from "moment"; import moment from "moment";
import React from "react"; import React, { useState } from "react";
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { DateFormatter } from "../../utils/DateFormatter"; import { DateFormatter } from "../../utils/DateFormatter";
import { useTranslation } from "react-i18next";
const OneCalendarDay = 60 * 60 * 24 * 1000; const OneCalendarDay = 60 * 60 * 24 * 1000;
const Now = new Date(); const Now = new Date();
export default function ProductionListDate({ record, field }) { export default function ProductionListDate({ record, field, time }) {
const [updateAlert] = useMutation(UPDATE_JOB); const [updateAlert] = useMutation(UPDATE_JOB);
const [visible, setVisible] = useState(false);
const { t } = useTranslation();
const handleChange = (date) => { const handleChange = (date) => {
logImEXEvent("product_toggle_date", { field }); logImEXEvent("product_toggle_date", { field });
@@ -25,27 +28,47 @@ export default function ProductionListDate({ record, field }) {
}, },
}).then(() => { }).then(() => {
if (record.refetch) record.refetch(); if (record.refetch) record.refetch();
if (!time) {
setVisible(false);
}
}); });
}; };
return ( return (
<div> <div>
<Dropdown <Dropdown
trigger={["click"]} //trigger={["click"]}
visible={visible}
style={{ style={{
height: "19px", height: "19px",
}} }}
overlay={ overlay={
<div onClick={(e) => e.stopPropagation()}> <Card
style={{ padding: "1rem" }}
onClick={(e) => e.stopPropagation()}
>
<DatePicker <DatePicker
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
value={(record[field] && moment(record[field])) || null} value={(record[field] && moment(record[field])) || null}
onChange={handleChange} onChange={handleChange}
format="MM/DD/YYYY"
/> />
</div> {time && (
<TimePicker
onClick={(e) => e.stopPropagation()}
value={(record[field] && moment(record[field])) || null}
onChange={handleChange}
format="hh:mm a"
/>
)}
<Button onClick={() => setVisible(false)}>
{t("general.actions.close")}
</Button>
</Card>
} }
> >
<div <div
onClick={() => setVisible(true)}
style={{ style={{
height: "19px", height: "19px",
}} }}

View File

@@ -66,12 +66,7 @@ export function ProductionListSaveConfigButton({
}; };
const popMenu = ( const popMenu = (
<div> <div>
<Form <Form layout="vertical" form={form} onFinish={handleSaveConfig}>
layout="vertical"
form={form}
onFinish={handleSaveConfig}
initialValues={{ driveable: true, towin: false }}
>
<Form.Item <Form.Item
label={t("production.labels.viewname")} label={t("production.labels.viewname")}
name="name" name="name"

View File

@@ -55,6 +55,19 @@ export function ProductionListTable({
if (assoc) { if (assoc) {
await updateDefaultProdView({ await updateDefaultProdView({
variables: { assocId: assoc.id, view: value }, variables: { assocId: assoc.id, view: value },
update(cache) {
cache.modify({
id: cache.identify(bodyshop),
fields: {
associations(existingAssociations, { readField }) {
return existingAssociations.map((a) => {
if (a.useremail !== currentUser.email) return a;
return { ...a, default_prod_list_view: value };
});
},
},
});
},
}); });
} }
}; };
@@ -85,13 +98,18 @@ export function ProductionListTable({
setState(bodyshop.production_config[0].columns.tableState); setState(bodyshop.production_config[0].columns.tableState);
}; };
const assoc = bodyshop.associations.find(
(a) => a.useremail === currentUser.email
);
const defaultView = assoc && assoc.default_prod_list_view;
return ( return (
<div style={{ width: "10rem" }}> <div style={{ width: "10rem" }}>
<Select <Select
onSelect={handleSelect} onSelect={handleSelect}
placeholder={t("production.labels.selectview")} placeholder={t("production.labels.selectview")}
optionLabelProp="label" optionLabelProp="label"
defaultValue={defaultView}
> >
{bodyshop.production_config.map((config) => ( {bodyshop.production_config.map((config) => (
<Select.Option key={config.name} label={config.name}> <Select.Option key={config.name} label={config.name}>

View File

@@ -32,12 +32,11 @@ export function ProductionListTable({
}) { }) {
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const defaultView = useMemo(() => { const assoc = bodyshop.associations.find(
const assoc = bodyshop.associations.find( (a) => a.useremail === currentUser.email
(a) => a.useremail === currentUser.email );
);
return assoc && assoc.default_prod_list_view; const defaultView = assoc && assoc.default_prod_list_view;
}, [bodyshop.associations, currentUser.email]);
const [state, setState] = useState( const [state, setState] = useState(
(bodyshop.production_config && (bodyshop.production_config &&

View File

@@ -122,6 +122,7 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
actual_in actual_in
scheduled_completion scheduled_completion
scheduled_delivery scheduled_delivery
date_last_contacted
ins_co_nm ins_co_nm
clm_total clm_total
ownr_ph1 ownr_ph1
@@ -509,6 +510,7 @@ export const GET_JOB_BY_PK = gql`
date_open date_open
date_scheduled date_scheduled
date_invoiced date_invoiced
date_last_contacted
date_exported date_exported
status status
owner_owing owner_owing
@@ -688,6 +690,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
ownr_ph1 ownr_ph1
ownr_ea ownr_ea
ca_gst_registrant ca_gst_registrant
owner_owing
special_coverage_policy special_coverage_policy
available_jobs { available_jobs {
id id
@@ -747,6 +750,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
scheduled_in scheduled_in
scheduled_delivery scheduled_delivery
date_invoiced date_invoiced
date_last_contacted
date_open date_open
date_exported date_exported
@@ -832,6 +836,7 @@ export const QUERY_TECH_JOB_DETAILS = gql`
scheduled_in scheduled_in
scheduled_delivery scheduled_delivery
date_invoiced date_invoiced
date_last_contacted
date_open date_open
date_exported date_exported
voided voided

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -144,6 +144,7 @@ export async function RenderTemplates(
// ...rootTemplate.templateObject.context, // ...rootTemplate.templateObject.context,
headerpath: `/${bodyshop.imexshopid}/header.html`, headerpath: `/${bodyshop.imexshopid}/header.html`,
bodyshop: bodyshop, bodyshop: bodyshop,
offset: moment().utcOffset(),
}, },
}; };

View File

@@ -36,10 +36,10 @@
lodash "^4.17.21" lodash "^4.17.21"
resize-observer-polyfill "^1.5.0" resize-observer-polyfill "^1.5.0"
"@apollo/client@^3.4.15": "@apollo/client@^3.4.16":
version "3.4.15" version "3.4.16"
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.4.15.tgz#0aa05ff2bb54092919b501ef348ade6330911670" resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.4.16.tgz#67090d5655aa843fa64d26f1913315e384a5fa0f"
integrity sha512-CnlT9i7TgHagkKQNvti81A9KcbIMqgpUPGJJL6bg5spTsB2R/5J6E7qiPcMvXuuXwR2xe4FmE4Ey4HizStb8Hg== integrity sha512-iF4zEYwvebkri0BZQyv8zfavPfVEafsK0wkOofa6eC2yZu50J18uTutKtC174rjHZ2eyxZ8tV7NvAPKRT+OtZw==
dependencies: dependencies:
"@graphql-typed-document-node/core" "^3.0.0" "@graphql-typed-document-node/core" "^3.0.0"
"@wry/context" "^0.6.0" "@wry/context" "^0.6.0"
@@ -1383,12 +1383,12 @@
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
tslib "^2.1.0" tslib "^2.1.0"
"@firebase/app-compat@0.1.2": "@firebase/app-compat@0.1.3":
version "0.1.2" version "0.1.3"
resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.2.tgz#ed9682325bbec6e177449f4b7403c60b088c89db" resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.3.tgz#4757c8f65d2a067d24afdfef4f736a5f53c66656"
integrity sha512-kF1maoqA8bZqJ4v/ojVvA7kIyyXEPkJmL48otGrC8LIgdcen7xCx3JFDe0DGeQywg+qujvdkJz/TptFN1cvAgw== integrity sha512-+/U2RgRLfLznPuluIMW3bsAehTBTVWKxA6l6jjk9noozPuP99xOulReMqf5kCrXVdW1aMHdRuKfntjbTAR8+aw==
dependencies: dependencies:
"@firebase/app" "0.7.1" "@firebase/app" "0.7.2"
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/logger" "0.3.0" "@firebase/logger" "0.3.0"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
@@ -1399,26 +1399,26 @@
resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f"
integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg== integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==
"@firebase/app@0.7.1": "@firebase/app@0.7.2":
version "0.7.1" version "0.7.2"
resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.1.tgz#b594ac4cd15bf94d2a3b97681354a52fa5cfca29" resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.2.tgz#0df26d6e9861d5ebe038d4e1f10b63111a28a1f7"
integrity sha512-B4z6E1EPQc0mOjF35IPKdDRCFnT/fNQIHfM+v7F9obB7ItPhGILK3LxaQfuampSQpF6GG6TPFDbrWK6myXAq+g== integrity sha512-xKO3KWxVqCLijJToaBGvBnXCaVGvIw+rT2Dtd9B2iyOFJieQQ+xx8/zRWgoSqbMBIZ2crQVr0KdsoyP9D2nQfg==
dependencies: dependencies:
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/logger" "0.3.0" "@firebase/logger" "0.3.0"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
tslib "^2.1.0" tslib "^2.1.0"
"@firebase/auth-compat@0.1.3": "@firebase/auth-compat@0.1.4":
version "0.1.3" version "0.1.4"
resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.3.tgz#0110398e665e7b709dfbb81ab9410f58e3d1a98d" resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.4.tgz#d55084f0d37086d58a1da4748c9bbec2ede0a80a"
integrity sha512-eDDtY5If+ERJxalt+plvX6avZspuwo4/kPXssvV+csm414awhDzQBtSDPDajgbH3YB9V+O3LAFHeWcP3rrHS5w== integrity sha512-Vn7Dsxa7B50ihgDAMQAVb/IxU9tcQyR1JDbWjZzf2b1212hBuuwEs1V1u01xoKunMXMSg+P8ztbG7IRxOj2FdQ==
dependencies: dependencies:
"@firebase/auth" "0.18.0" "@firebase/auth" "0.18.1"
"@firebase/auth-types" "0.11.0" "@firebase/auth-types" "0.11.0"
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
node-fetch "2.6.2" node-fetch "2.6.5"
selenium-webdriver "^4.0.0-beta.2" selenium-webdriver "^4.0.0-beta.2"
tslib "^2.1.0" tslib "^2.1.0"
@@ -1432,15 +1432,15 @@
resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886"
integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw==
"@firebase/auth@0.18.0": "@firebase/auth@0.18.1":
version "0.18.0" version "0.18.1"
resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.18.0.tgz#00de488a43f84bd9b1e2f8e1d9887a499d30b93d" resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.18.1.tgz#2cba86c5ac614aea8ea1bdc55e479530c187b5ce"
integrity sha512-iK+VXkdDkum8SmJNgz9ZcOboRLrUN1VW7AHHkpZb76VJvoYRoCPD+A9O/v/ziI0LpwIZJwi1GFes9XjZTlfLiA== integrity sha512-q455ls7Hjug3yGp7htLL/LABqySoXGXL/ADLJPyiSnVl22a5oQWuTKUL6N5PAXHc5LwygFfHYiHrNhpQDaGm3w==
dependencies: dependencies:
"@firebase/component" "0.5.7" "@firebase/component" "0.5.7"
"@firebase/logger" "0.3.0" "@firebase/logger" "0.3.0"
"@firebase/util" "1.4.0" "@firebase/util" "1.4.0"
node-fetch "2.6.2" node-fetch "2.6.5"
selenium-webdriver "4.0.0-rc-1" selenium-webdriver "4.0.0-rc-1"
tslib "^2.1.0" tslib "^2.1.0"
@@ -2005,10 +2005,10 @@
mkdirp "^1.0.4" mkdirp "^1.0.4"
rimraf "^3.0.2" rimraf "^3.0.2"
"@openreplay/tracker-assist@^3.4.0": "@openreplay/tracker-assist@^3.4.3":
version "3.4.0" version "3.4.3"
resolved "https://registry.yarnpkg.com/@openreplay/tracker-assist/-/tracker-assist-3.4.0.tgz#93a5e5314b3af55c23979cfe654e7617f76844af" resolved "https://registry.yarnpkg.com/@openreplay/tracker-assist/-/tracker-assist-3.4.3.tgz#02eb6c41ec7a78f38e6fc30df9f637e79c4c1877"
integrity sha512-tKxb0FuUmSo76gH7fBeZ+KYj+G7nDe0N8Ii7dwPCmljfi+0gCXNEtju1+ioQM1XVlT0IWl3a3/JUBvE5MXLEAA== integrity sha512-N+HdVdNZiJcIsakxDzhGr4qGrWLeYNaYgfW7kzbAOxZXWJ9hKU5OH/LUZPl74QfYN0cw0/AbXqBi2sJc71a3aw==
dependencies: dependencies:
npm-dragndrop "^1.2.0" npm-dragndrop "^1.2.0"
peerjs "^1.3.2" peerjs "^1.3.2"
@@ -2023,18 +2023,12 @@
resolved "https://registry.yarnpkg.com/@openreplay/tracker-redux/-/tracker-redux-3.0.0.tgz#7d71c8d2b58b08229e6af2c677d53980cee0b9ef" resolved "https://registry.yarnpkg.com/@openreplay/tracker-redux/-/tracker-redux-3.0.0.tgz#7d71c8d2b58b08229e6af2c677d53980cee0b9ef"
integrity sha512-ctybOquoDj8QNj82pETftgXjEoAzwEoKSxIhwstJaUv5xUkBVv0rDIjMBgCSys8cB/vbRkI/QhvksDaFr9hY0g== integrity sha512-ctybOquoDj8QNj82pETftgXjEoAzwEoKSxIhwstJaUv5xUkBVv0rDIjMBgCSys8cB/vbRkI/QhvksDaFr9hY0g==
"@openreplay/tracker-vuex@^3.0.0": "@openreplay/tracker@^3.4.4":
version "3.0.0" version "3.4.4"
resolved "https://registry.yarnpkg.com/@openreplay/tracker-vuex/-/tracker-vuex-3.0.0.tgz#116ee59ffd27d062f9ae9ea9171db2ed3f03f775" resolved "https://registry.yarnpkg.com/@openreplay/tracker/-/tracker-3.4.4.tgz#4d79fb738f7704aefbea55117d52d61999beb571"
integrity sha512-cH5W4dKkYdkSSvOYKApupgGhfDcmV+UOsraaPa7fgOsnmWoczUFOapTyInQDxxgf1Q3HfPJVw7dOI1xdL5HzKg== integrity sha512-IcuxwwTt1RtLZw9QlQVAVNqoybv0ZkD2ZDk2FeHEQ/+BItsMhG61/4/lB2yXKLTLr6ydeKTzwYvxfr1vwxn2dw==
"@openreplay/tracker@^3.4.1":
version "3.4.1"
resolved "https://registry.yarnpkg.com/@openreplay/tracker/-/tracker-3.4.1.tgz#0ceb5deef0ed71483dbac0d282335d12e273d349"
integrity sha512-aeeChCOGx4DpGefKIdGzheBy6btoBVH82qIogROOIcooiFVmONQXGERbgqhyf1a4qYqh8G3ABmzjDm9RpMXLMg==
dependencies: dependencies:
"@medv/finder" "^2.0.0" "@medv/finder" "^2.0.0"
"@openreplay/tracker-vuex" "^3.0.0"
error-stack-parser "^2.0.6" error-stack-parser "^2.0.6"
"@pmmmwh/react-refresh-webpack-plugin@0.4.3": "@pmmmwh/react-refresh-webpack-plugin@0.4.3":
@@ -2273,10 +2267,10 @@
"@sentry/types" "6.13.2" "@sentry/types" "6.13.2"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/webpack-plugin@^1.17.1": "@sentry/webpack-plugin@^1.17.2":
version "1.17.1" version "1.17.2"
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.17.1.tgz#1b3ebbe9991e4d77125ace2b24594059a088268a" resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.17.2.tgz#0076c4b6b57959aa7f43a96904756549af069c23"
integrity sha512-L47a0hxano4a+9jbvQSBzHCT1Ph8fYAvGGUvFg8qc69yXS9si5lXRNIH/pavN6mqJjhQjAcEsEp+vxgvT4xZDQ== integrity sha512-1XKNP6FAzB+V58WPCX7DTRLu8BaB/ho11Y2VweqZn10m/MZuqKlHI1PzjJsf4hLoMOZBTt9KdkRi4vjgI6TmPA==
dependencies: dependencies:
"@sentry/cli" "^1.68.0" "@sentry/cli" "^1.68.0"
@@ -2306,10 +2300,10 @@
dependencies: dependencies:
prop-types "^15.7.2" prop-types "^15.7.2"
"@stripe/stripe-js@^1.18.0": "@stripe/stripe-js@^1.19.1":
version "1.18.0" version "1.19.1"
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.18.0.tgz#687268d7cd68b44b92b86300d7c7f2a6e4df0b98" resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.19.1.tgz#51017bb1c6e12f0e74747534667e42e77b2c9978"
integrity sha512-yBRHAMKHnF3kbzv0tpKB82kSow43wW5qXLK8ofg3V9NaaCyObSTO7wJfktWAtG/NBgkJOdUL+pV8dHBj0qvDkQ== integrity sha512-gvaQ51FXHHKMypXMlSPZbpb7e5671oqySqEfU2MviAQCsikV/+vnvPPxOged4RvNwNM7v4ocsKadQwqIwPhgrQ==
"@surma/rollup-plugin-off-main-thread@^1.1.1": "@surma/rollup-plugin-off-main-thread@^1.1.1":
version "1.4.2" version "1.4.2"
@@ -3498,12 +3492,12 @@ axe-core@^4.0.2:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325"
integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA==
axios@^0.21.4: axios@^0.22.0:
version "0.21.4" version "0.22.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" resolved "https://registry.yarnpkg.com/axios/-/axios-0.22.0.tgz#bf702c41fb50fbca4539589d839a077117b79b25"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== integrity sha512-Z0U3uhqQeg1oNcihswf4ZD57O3NrR1+ZXhxaROaWpDmsDTx7T2HNBV2ulBtie2hwJptu8UvgnJoK+BIqdzh/1w==
dependencies: dependencies:
follow-redirects "^1.14.0" follow-redirects "^1.14.4"
axobject-query@^2.2.0: axobject-query@^2.2.0:
version "2.2.0" version "2.2.0"
@@ -6373,20 +6367,20 @@ find-yarn-workspace-root@^2.0.0:
dependencies: dependencies:
micromatch "^4.0.2" micromatch "^4.0.2"
firebase@^9.1.0: firebase@^9.1.1:
version "9.1.0" version "9.1.1"
resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.1.0.tgz#f284634ae4f4e7c789ff36494f4534cba5dffbf2" resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.1.1.tgz#a2980cf397cdbf9933430576c0413ec5c30e2f62"
integrity sha512-Pj9/FwNzT4pdSS6vpXZzm4mFscI73N+AH70gaWZPnZrQBvyMAPTuKXXscjrFePPlqs94b4Emq+2mSwLGcwod/A== integrity sha512-106PqKLwWo4vINQUwEbk2aU/nAFhRbCBE2IdnQmf7UDaW4wqJGZcgRvy3jSyuZr/dkqnT7ymKX0GGrDSzNLU6g==
dependencies: dependencies:
"@firebase/analytics" "0.7.1" "@firebase/analytics" "0.7.1"
"@firebase/analytics-compat" "0.1.2" "@firebase/analytics-compat" "0.1.2"
"@firebase/app" "0.7.1" "@firebase/app" "0.7.2"
"@firebase/app-check" "0.4.1" "@firebase/app-check" "0.4.1"
"@firebase/app-check-compat" "0.1.2" "@firebase/app-check-compat" "0.1.2"
"@firebase/app-compat" "0.1.2" "@firebase/app-compat" "0.1.3"
"@firebase/app-types" "0.7.0" "@firebase/app-types" "0.7.0"
"@firebase/auth" "0.18.0" "@firebase/auth" "0.18.1"
"@firebase/auth-compat" "0.1.3" "@firebase/auth-compat" "0.1.4"
"@firebase/database" "0.12.1" "@firebase/database" "0.12.1"
"@firebase/database-compat" "0.1.1" "@firebase/database-compat" "0.1.1"
"@firebase/firestore" "3.1.0" "@firebase/firestore" "3.1.0"
@@ -6443,11 +6437,16 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3" inherits "^2.0.3"
readable-stream "^2.3.6" readable-stream "^2.3.6"
follow-redirects@^1.0.0, follow-redirects@^1.14.0: follow-redirects@^1.0.0:
version "1.14.3" version "1.14.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.3.tgz#6ada78118d8d24caee595595accdc0ac6abd022e" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.3.tgz#6ada78118d8d24caee595595accdc0ac6abd022e"
integrity sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw== integrity sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==
follow-redirects@^1.14.4:
version "1.14.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379"
integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==
for-in@^1.0.2: for-in@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -7094,10 +7093,10 @@ i18next-browser-languagedetector@^6.1.2:
dependencies: dependencies:
"@babel/runtime" "^7.14.6" "@babel/runtime" "^7.14.6"
i18next@^21.2.0: i18next@^21.2.4:
version "21.2.0" version "21.2.4"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.2.0.tgz#07346948d8c1e7be91518897839f8158c50dd76d" resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.2.4.tgz#ac56044099c83a0a8e2c596acf57f35da8ca327e"
integrity sha512-I2BLM/YNyEjCzRak1kL3uYYawwkfduQbNramMx7uMjjbos3zGZB1ag6dgbdoTR0baR34fpG4X4oWKaQExNo8wg== integrity sha512-+81XmiwJOLWJFjRZJK5ASFahAo5TXZGz5IrBT4CfLJ3CyXho61A1cj1Kmh8za8TYtGFou0cEkUSjEaqfya7Wfg==
dependencies: dependencies:
"@babel/runtime" "^7.12.0" "@babel/runtime" "^7.12.0"
@@ -8500,10 +8499,10 @@ levn@~0.3.0:
prelude-ls "~1.1.2" prelude-ls "~1.1.2"
type-check "~0.3.2" type-check "~0.3.2"
libphonenumber-js@^1.9.34: libphonenumber-js@^1.9.36:
version "1.9.34" version "1.9.36"
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.34.tgz#ddddc778a9b2f53c70500fcf10c9483596e3574f" resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.36.tgz#ba56c2f5600ba34677389d0acc1a5fe8a1206561"
integrity sha512-gHTNU9xTtVgSp30IDX/57W4pETMXDIYXFfwEOJVXiYosiY7Hc7ogJwlBjOqlCcU04X0aA8DT57hdwUC1sJBJnA== integrity sha512-eaQRvOHmBKOxd2TKNml5lx1/7+nm4MftXTUXPTcBS70mm7U3AUNBNPF99tNBpkrYQNu+YFP553ranMsbshqqTA==
lie@~3.3.0: lie@~3.3.0:
version "3.3.0" version "3.3.0"
@@ -9162,6 +9161,13 @@ node-fetch@2.6.2:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0"
integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==
node-fetch@2.6.5:
version "2.6.5"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd"
integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==
dependencies:
whatwg-url "^5.0.0"
node-fetch@^2.6.0: node-fetch@^2.6.0:
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
@@ -11292,10 +11298,10 @@ react-beautiful-dnd@^13.0.0:
redux "^4.0.4" redux "^4.0.4"
use-memo-one "^1.1.1" use-memo-one "^1.1.1"
react-big-calendar@^0.36.0: react-big-calendar@^0.36.1:
version "0.36.0" version "0.36.1"
resolved "https://registry.yarnpkg.com/react-big-calendar/-/react-big-calendar-0.36.0.tgz#97be7e26f3ed8d49dc988b5fdd716ec62a8f72ba" resolved "https://registry.yarnpkg.com/react-big-calendar/-/react-big-calendar-0.36.1.tgz#3a74db72dc293de899759e01bfb72ec1715f8787"
integrity sha512-imQlz5Db8gLacS6WEFH+LZqd96N9fPD1Ho0wBfRWKvB3PRdXy81FXDUSzv50jF6+TAMqgly66mVX05GhUxhPzw== integrity sha512-pzg8X/Tc1szg//KoV2GP9YnPPRhE3uCIXSP10Jlr46jMcBiMZ/wP7WGhpgaGVKEL30rR/BDLz7rhXaAYDX/UuQ==
dependencies: dependencies:
"@babel/runtime" "^7.1.5" "@babel/runtime" "^7.1.5"
clsx "^1.0.4" clsx "^1.0.4"
@@ -11418,10 +11424,10 @@ react-i18next@^11.12.0:
"@babel/runtime" "^7.14.5" "@babel/runtime" "^7.14.5"
html-parse-stringify "^3.0.1" html-parse-stringify "^3.0.1"
react-icons@^4.2.0: react-icons@^4.3.1:
version "4.2.0" version "4.3.1"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
integrity sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ== integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
react-images@^0.5.16: react-images@^0.5.16:
version "0.5.19" version "0.5.19"
@@ -13484,6 +13490,11 @@ tr46@^2.1.0:
dependencies: dependencies:
punycode "^2.1.1" punycode "^2.1.1"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
tryer@^1.0.1: tryer@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
@@ -13997,6 +14008,11 @@ web-vitals@^2.1.0:
resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.0.tgz#ebf5428875ab5bfc1056c2e80cd177001287de7b" resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.0.tgz#ebf5428875ab5bfc1056c2e80cd177001287de7b"
integrity sha512-npEyJP8jHf3J71t1tRTEtz9FeKp8H2udWJUUq5ykfPhhstr//TUxiYhIEzLNwk4zv2ybAilMn7v7N6Mxmuitmg== integrity sha512-npEyJP8jHf3J71t1tRTEtz9FeKp8H2udWJUUq5ykfPhhstr//TUxiYhIEzLNwk4zv2ybAilMn7v7N6Mxmuitmg==
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
webidl-conversions@^5.0.0: webidl-conversions@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
@@ -14163,6 +14179,14 @@ whatwg-mimetype@^2.3.0:
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
whatwg-url@^8.0.0, whatwg-url@^8.5.0: whatwg-url@^8.0.0, whatwg-url@^8.5.0:
version "8.7.0" version "8.7.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"

View File

@@ -2581,6 +2581,7 @@
- date_estimated - date_estimated
- date_exported - date_exported
- date_invoiced - date_invoiced
- date_last_contacted
- date_open - date_open
- date_scheduled - date_scheduled
- ded_amt - ded_amt
@@ -2829,6 +2830,7 @@
- date_estimated - date_estimated
- date_exported - date_exported
- date_invoiced - date_invoiced
- date_last_contacted
- date_open - date_open
- date_scheduled - date_scheduled
- ded_amt - ded_amt
@@ -3087,6 +3089,7 @@
- date_estimated - date_estimated
- date_exported - date_exported
- date_invoiced - date_invoiced
- date_last_contacted
- date_open - date_open
- date_scheduled - date_scheduled
- ded_amt - ded_amt

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "date_last_contacted" timestamptz
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "date_last_contacted" timestamptz
null;

View File

@@ -17,7 +17,7 @@
"start": "node server.js" "start": "node server.js"
}, },
"dependencies": { "dependencies": {
"aws-sdk": "^2.998.0", "aws-sdk": "^2.1000.0",
"bluebird": "^3.7.2", "bluebird": "^3.7.2",
"body-parser": "^1.18.3", "body-parser": "^1.18.3",
"cloudinary": "^1.27.0", "cloudinary": "^1.27.0",
@@ -50,7 +50,7 @@
"xmlbuilder2": "^3.0.2" "xmlbuilder2": "^3.0.2"
}, },
"devDependencies": { "devDependencies": {
"concurrently": "^6.2.2", "concurrently": "^6.3.0",
"eslint": "^7.31.0", "eslint": "^7.31.0",
"eslint-plugin-promise": "^5.1.0", "eslint-plugin-promise": "^5.1.0",
"source-map-explorer": "^2.5.2" "source-map-explorer": "^2.5.2"

View File

@@ -90,10 +90,12 @@ exports.sendEmail = async (req, res) => {
to: req.body.to, to: req.body.to,
cc: req.body.cc, cc: req.body.cc,
subject: req.body.subject, subject: req.body.subject,
info, // info,
}); });
res.json({ success: true, response: info }); res.json({
success: true, //response: info
});
} else { } else {
logger.log("send-email-failure", "ERROR", req.user.email, null, { logger.log("send-email-failure", "ERROR", req.user.email, null, {
from: `${req.body.from.name} <${req.body.from.address}>`, from: `${req.body.from.name} <${req.body.from.address}>`,

View File

@@ -595,10 +595,10 @@ atob@2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
aws-sdk@^2.998.0: aws-sdk@^2.1000.0:
version "2.998.0" version "2.1000.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.998.0.tgz#e37d98a522c4b6cfbfc41d85bd99fa61b5f90d20" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1000.0.tgz#408e02dd299541b9e35c85244df9df51cbb2f76a"
integrity sha512-jenbMcGxOg9AeH6p1m0vbsJYNaeJXBnOM58GXsaKecPgRnCm/IykTPlB6aQKfNDk0WQnw5BHDcy7iQPnEjEkUQ== integrity sha512-PhL4WPIJ5fyOBbmWdEaskD6+qvu9VD4kVLEBK/SchcZXmivUKhED3POR6dbfskhwTksxwkrwa6G4NNI3yY7d1g==
dependencies: dependencies:
buffer "4.9.2" buffer "4.9.2"
events "1.1.1" events "1.1.1"
@@ -935,10 +935,10 @@ concat-stream@^2.0.0:
readable-stream "^3.0.2" readable-stream "^3.0.2"
typedarray "^0.0.6" typedarray "^0.0.6"
concurrently@^6.2.2: concurrently@^6.3.0:
version "6.2.2" version "6.3.0"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.2.2.tgz#81c11b85d9a7de56ad4388ff6aab4a94ddea51f2" resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.3.0.tgz#63128cb4a6ed54d3c0ed8528728590a5fe54582a"
integrity sha512-7a45BjVakAl3pprLOeqaOoZfIWZRmdC68NkjyzPbKu0/pE6CRmqS3l8RG7Q2cX9LnRHkB0oPM6af8PS7NEQvYQ== integrity sha512-k4k1jQGHHKsfbqzkUszVf29qECBrkvBKkcPJEUDTyVR7tZd1G/JOfnst4g1sYbFvJ4UjHZisj1aWQR8yLKpGPw==
dependencies: dependencies:
chalk "^4.1.0" chalk "^4.1.0"
date-fns "^2.16.1" date-fns "^2.16.1"