Minor fixes throughout the system.
This commit is contained in:
@@ -17,7 +17,7 @@ export default function JobDetailCardsNotesComponent({ loading, data }) {
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.notes")}
|
||||
extraLink={`/manage/jobs/${data.id}?notes`}
|
||||
extraLink={`/manage/jobs/${data.id}?tab=notes`}
|
||||
>
|
||||
{data ? (
|
||||
<Container>
|
||||
@@ -25,7 +25,7 @@ export default function JobDetailCardsNotesComponent({ loading, data }) {
|
||||
size="small"
|
||||
bordered
|
||||
dataSource={data.notes}
|
||||
renderItem={item => (
|
||||
renderItem={(item) => (
|
||||
<List.Item>
|
||||
{item.critical ? (
|
||||
<EyeInvisibleFilled style={{ margin: 4, color: "red" }} />
|
||||
|
||||
@@ -17,21 +17,21 @@ export default function JobDetailCardsTotalsComponent({ loading, data }) {
|
||||
return (
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.totals")}>
|
||||
{totals ? (
|
||||
<div className='imex-flex-row imex-flex-row__flex-space-around'>
|
||||
<div className="imex-flex-row imex-flex-row__flex-space-around">
|
||||
<Statistic
|
||||
className='imex-flex-row__margin-large'
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.labels.total_repairs")}
|
||||
value={Dinero(totals.totals.total_repairs).toFormat()}
|
||||
/>
|
||||
<Statistic
|
||||
className='imex-flex-row__margin-large'
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.fields.ded_amt")}
|
||||
value={Dinero({
|
||||
amount: Math.round((data.ded_amt || 0) * 100),
|
||||
}).toFormat()}
|
||||
/>
|
||||
<Statistic
|
||||
className='imex-flex-row__margin-large'
|
||||
className="imex-flex-row__margin-large"
|
||||
title={t("jobs.labels.net_repairs")}
|
||||
value={Dinero(totals.totals.net_repairs).toFormat()}
|
||||
/>
|
||||
|
||||
@@ -1,51 +1,38 @@
|
||||
import { useQuery } from "@apollo/react-hooks";
|
||||
import React, { useState } from "react";
|
||||
import { GET_JOB_LINES_BY_PK } from "../../graphql/jobs-lines.queries";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import JobLinesComponent from "./job-lines.component";
|
||||
|
||||
function JobLinesContainer({ jobId }) {
|
||||
const { loading, error, data, refetch } = useQuery(GET_JOB_LINES_BY_PK, {
|
||||
variables: { id: jobId },
|
||||
});
|
||||
|
||||
function JobLinesContainer({ jobId, joblines, refetch }) {
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const [selectedLines, setSelectedLines] = useState([]);
|
||||
|
||||
if (error) return <AlertComponent message={error.message} type='error' />;
|
||||
|
||||
const jobLines =
|
||||
data && data.joblines
|
||||
? searchText
|
||||
? data.joblines.filter(
|
||||
(jl) =>
|
||||
(jl.unq_seq || "")
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.line_desc || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.part_type || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.oem_partno || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.op_code_desc || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.db_price || "")
|
||||
.toString()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.act_price || "").toString().includes(searchText.toLowerCase())
|
||||
)
|
||||
: data.joblines
|
||||
: null;
|
||||
const jobLines = joblines
|
||||
? searchText
|
||||
? joblines.filter(
|
||||
(jl) =>
|
||||
(jl.unq_seq || "")
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.line_desc || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.part_type || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.oem_partno || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.op_code_desc || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.db_price || "").toString().includes(searchText.toLowerCase()) ||
|
||||
(jl.act_price || "").toString().includes(searchText.toLowerCase())
|
||||
)
|
||||
: joblines
|
||||
: null;
|
||||
|
||||
return (
|
||||
<JobLinesComponent
|
||||
loading={loading}
|
||||
refetch={refetch}
|
||||
jobLines={jobLines}
|
||||
setSearchText={setSearchText}
|
||||
|
||||
@@ -23,6 +23,7 @@ import OwnerTagPopoverComponent from "../owner-tag-popover/owner-tag-popover.com
|
||||
import VehicleTagPopoverComponent from "../vehicle-tag-popover/vehicle-tag-popover.component";
|
||||
import JobEmployeeAssignments from "../job-employee-assignments/job-employee-assignments.container";
|
||||
import "./jobs-detail-header.styles.scss";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -48,7 +49,8 @@ export function JobsDetailHeader({
|
||||
<Menu
|
||||
onClick={(e) => {
|
||||
updateJobStatus(e.key);
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{bodyshop.md_ro_statuses.statuses.map((item) => (
|
||||
<Menu.Item key={item}>{item}</Menu.Item>
|
||||
))}
|
||||
@@ -56,19 +58,20 @@ export function JobsDetailHeader({
|
||||
);
|
||||
|
||||
const menuExtra = (
|
||||
<div className='imex-flex-row'>
|
||||
<div className="imex-flex-row">
|
||||
<Dropdown
|
||||
className='imex-flex-row__margin'
|
||||
className="imex-flex-row__margin"
|
||||
overlay={statusmenu}
|
||||
trigger={["click"]}
|
||||
key='changestatus'>
|
||||
key="changestatus"
|
||||
>
|
||||
<Button>
|
||||
{t("jobs.actions.changestatus")} <DownCircleFilled />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
|
||||
<Button
|
||||
className='imex-flex-row__margin'
|
||||
className="imex-flex-row__margin"
|
||||
onClick={() => {
|
||||
setPrintCenterContext({
|
||||
actions: { refetch: refetch },
|
||||
@@ -78,14 +81,15 @@ export function JobsDetailHeader({
|
||||
},
|
||||
});
|
||||
}}
|
||||
key='printing'>
|
||||
key="printing"
|
||||
>
|
||||
<PrinterFilled />
|
||||
{t("jobs.actions.printCenter")}
|
||||
</Button>
|
||||
<Button
|
||||
key='convert'
|
||||
className='imex-flex-row__margin'
|
||||
type='danger'
|
||||
key="convert"
|
||||
className="imex-flex-row__margin"
|
||||
type="danger"
|
||||
style={{ display: job.converted ? "none" : "" }}
|
||||
disabled={job.converted}
|
||||
onClick={() => {
|
||||
@@ -98,15 +102,17 @@ export function JobsDetailHeader({
|
||||
message: t("jobs.successes.converted"),
|
||||
});
|
||||
});
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{t("jobs.actions.convert")}
|
||||
</Button>
|
||||
<JobsDetailHeaderActions key='actions' job={job} refetch={refetch} />
|
||||
<JobsDetailHeaderActions key="actions" job={job} refetch={refetch} />
|
||||
<Button
|
||||
type='primary'
|
||||
className='imex-flex-row__margin'
|
||||
key='submit'
|
||||
htmlType='submit'>
|
||||
type="primary"
|
||||
className="imex-flex-row__margin"
|
||||
key="submit"
|
||||
htmlType="submit"
|
||||
>
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -121,56 +127,73 @@ export function JobsDetailHeader({
|
||||
}
|
||||
subTitle={job.status}
|
||||
tags={[
|
||||
<OwnerTagPopoverComponent key='owner' job={job} />,
|
||||
<VehicleTagPopoverComponent key='vehicle' job={job} />,
|
||||
<OwnerTagPopoverComponent key="owner" job={job} />,
|
||||
<VehicleTagPopoverComponent key="vehicle" job={job} />,
|
||||
<Tag
|
||||
color='#f50'
|
||||
key='production'
|
||||
style={{ display: job.inproduction ? "" : "none" }}>
|
||||
color="#f50"
|
||||
key="production"
|
||||
style={{ display: job.inproduction ? "" : "none" }}
|
||||
>
|
||||
{t("jobs.labels.inproduction")}
|
||||
</Tag>,
|
||||
]}
|
||||
extra={menuExtra}>
|
||||
extra={menuExtra}
|
||||
>
|
||||
<Descriptions
|
||||
size='small'
|
||||
column={{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3, xxl: 6 }}>
|
||||
<Descriptions.Item key='total' label={t("jobs.fields.repairtotal")}>
|
||||
size="small"
|
||||
column={{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3, xxl: 6 }}
|
||||
>
|
||||
<Descriptions.Item key="total" label={t("jobs.fields.repairtotal")}>
|
||||
<CurrencyFormatter>{job.clm_total}</CurrencyFormatter>
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item
|
||||
key='custowing'
|
||||
label={t("jobs.fields.customerowing")}>
|
||||
key="custowing"
|
||||
label={t("jobs.fields.customerowing")}
|
||||
>
|
||||
<CurrencyFormatter>{job.owner_owing}</CurrencyFormatter>
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item
|
||||
key='scp'
|
||||
label={t("jobs.fields.specialcoveragepolicy")}>
|
||||
key="scp"
|
||||
label={t("jobs.fields.specialcoveragepolicy")}
|
||||
>
|
||||
<Checkbox checked={job.special_coverage_policy} />
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item
|
||||
key='sched_comp'
|
||||
label={t("jobs.fields.scheduled_completion")}>
|
||||
key="sched_comp"
|
||||
label={t("jobs.fields.scheduled_completion")}
|
||||
>
|
||||
{job.scheduled_completion ? (
|
||||
<Moment format='MM/DD/YYYY'>{job.scheduled_completion}</Moment>
|
||||
<Moment format="MM/DD/YYYY">{job.scheduled_completion}</Moment>
|
||||
) : null}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item key='servicecar' label={t("jobs.fields.servicecar")}>
|
||||
<Descriptions.Item key="servicecar" label={t("jobs.fields.servicecar")}>
|
||||
{job.cccontracts &&
|
||||
job.cccontracts.map((item) => (
|
||||
<Link
|
||||
key={item.id}
|
||||
to={`/manage/courtesycars/contracts/${item.id}`}>
|
||||
<div>{`${item.agreementnumber} - ${item.start} - ${item.scheduledreturn}`}</div>
|
||||
to={`/manage/courtesycars/contracts/${item.id}`}
|
||||
>
|
||||
<div>
|
||||
<div>{`${item.courtesycar.year} ${item.courtesycar.make} ${item.courtesycar.model} (${item.courtesycar.plate})`}</div>
|
||||
<div style={{ display: "inline-block" }}>
|
||||
<DateTimeFormatter>{item.start}</DateTimeFormatter>
|
||||
<span> -- </span>
|
||||
<DateTimeFormatter>
|
||||
{item.scheduledreturn}
|
||||
</DateTimeFormatter>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item
|
||||
key='assignments'
|
||||
label={t("jobs.labels.employeeassignments")}>
|
||||
key="assignments"
|
||||
label={t("jobs.labels.employeeassignments")}
|
||||
>
|
||||
<JobEmployeeAssignments job={job} />
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useMutation } from "@apollo/react-hooks";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UPDATE_TEMPLATE } from "../../graphql/templates.queries";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import inlineCss from "inline-css";
|
||||
|
||||
export default function ShopTemplateSaveButton({
|
||||
templateId,
|
||||
@@ -17,28 +18,32 @@ export default function ShopTemplateSaveButton({
|
||||
logImEXEvent("shop_template_update");
|
||||
|
||||
emailEditorRef.current.exportHtml(async (data) => {
|
||||
console.log("handleSave -> html", data);
|
||||
const result = await updateTemplate({
|
||||
variables: {
|
||||
templateId: templateId,
|
||||
template: {
|
||||
query: gql,
|
||||
html: data.html,
|
||||
jsontemplate: data.design,
|
||||
console.log(data.html);
|
||||
inlineCss(data.html, {
|
||||
url: `${window.location.protocol}://${window.location.host}`,
|
||||
}).then(async function (inlineHtml) {
|
||||
const result = await updateTemplate({
|
||||
variables: {
|
||||
templateId: templateId,
|
||||
template: {
|
||||
query: gql,
|
||||
html: inlineHtml,
|
||||
jsontemplate: data.design,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!!!result.errors) {
|
||||
notification["success"]({
|
||||
message: t("templates.successes.updated"),
|
||||
});
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: t("templates.errors.updating", {
|
||||
error: JSON.stringify(result.errors),
|
||||
}),
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!!!result.errors) {
|
||||
notification["success"]({
|
||||
message: t("templates.successes.updated"),
|
||||
});
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: t("templates.errors.updating", {
|
||||
error: JSON.stringify(result.errors),
|
||||
}),
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,17 @@ export default function ShopTemplateEditorComponent({
|
||||
/>
|
||||
<button onClick={exportJson}>json</button>
|
||||
<button onClick={exportHtml}>html</button>
|
||||
<EmailEditor ref={emailEditorRef} />
|
||||
<EmailEditor
|
||||
ref={emailEditorRef}
|
||||
options={{
|
||||
customJS: [
|
||||
window.location.protocol +
|
||||
"//" +
|
||||
window.location.host +
|
||||
"/editor.js",
|
||||
],
|
||||
}}
|
||||
/>
|
||||
QUERY
|
||||
<Input.TextArea
|
||||
value={editorContent.gql}
|
||||
|
||||
Reference in New Issue
Block a user