generalized job checklist functionality & created deliver checklist. BOD-376

This commit is contained in:
Patrick Fic
2020-09-02 15:32:29 -07:00
parent ed788a4b5c
commit 51b6a560a6
39 changed files with 2646 additions and 378 deletions

View File

@@ -0,0 +1,162 @@
import { useMutation } from "@apollo/react-hooks";
import { Button, Form, notification, Switch } from "antd";
import queryString from "query-string";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useHistory, useLocation, useParams } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { MARK_LATEST_APPOINTMENT_AS_ARRIVED } from "../../../../graphql/appointments.queries";
import { UPDATE_JOB } from "../../../../graphql/jobs.queries";
import { selectBodyshop } from "../../../../redux/user/user.selectors";
import DateTimePicker from "../../../form-date-time-picker/form-date-time-picker.component";
import ConfigFormComponents from "../../../config-form-components/config-form-components.component";
import { logImEXEvent } from "../../../../firebase/firebase.utils";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function JobChecklistForm({ formItems, bodyshop, type }) {
const { t } = useTranslation();
const [intakeJob] = useMutation(UPDATE_JOB);
const [loading, setLoading] = useState(false);
const [markAptArrived] = useMutation(MARK_LATEST_APPOINTMENT_AS_ARRIVED);
const { jobId } = useParams();
const history = useHistory();
const search = queryString.parse(useLocation().search);
const handleFinish = async (values) => {
setLoading(true);
logImEXEvent("job_complete_intake");
const result = await intakeJob({
variables: {
jobId: jobId,
job: {
...(type === "intake" && { inproduction: values.addToProduction }),
status:
(type === "intake" && bodyshop.md_ro_statuses.default_arrived) ||
(type === "deliver" && bodyshop.md_ro_statuses.default_delivered),
...(type === "intake" && { actual_in: new Date() }),
...(type === "intake" && {
scheduled_completion: values.scheduledCompletion,
}),
[(type === "intake" && "intakechecklist") ||
(type === "deliver" && "deliverchecklist")]: values,
...(type === "deliver" && {
scheduled_delivery: values.scheduledDelivery,
}),
...(type === "deliver" &&
values.removeFromProduction && {
inproduction: false,
}),
},
},
});
if (!!search.appointmentId) {
const appUpdate = await markAptArrived({
variables: { appointmentId: search.appointmentId },
});
if (!!appUpdate.errors) {
notification["error"]({
message: t("checklist.errors.complete", {
error: JSON.stringify(result.errors),
}),
});
}
}
setLoading(false);
if (!!!result.errors) {
notification["success"]({ message: t("checklist.successes.completed") });
history.push(`/manage/jobs/${jobId}`);
} else {
notification["error"]({
message: t("checklist.errors.complete", {
error: JSON.stringify(result.errors),
}),
});
}
};
const [form] = Form.useForm();
return (
<Form
form={form}
onFinish={handleFinish}
initialValues={{ ...(type === "intake" && { addToProduction: true }) }}
>
{t("checklist.labels.checklist")}
<ConfigFormComponents componentList={formItems} />
{type === "intake" && (
<div>
<Form.Item
name="addToProduction"
valuePropName="checked"
label={t("checklist.labels.addtoproduction")}
>
<Switch />
</Form.Item>
<Form.Item
name="scheduledCompletion"
label={t("jobs.fields.scheduled_completion")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<DateTimePicker />
</Form.Item>
<Form.Item
name="scheduledDelivery"
label={t("jobs.fields.scheduled_delivery")}
>
<DateTimePicker />
</Form.Item>
</div>
)}
{type === "deliver" && (
<div>
<Form.Item
name="actualCompletion"
label={t("jobs.fields.actual_completion")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<DateTimePicker />
</Form.Item>
<Form.Item
name="removeFromProduction"
valuePropName="checked"
label={t("checklist.labels.removefromproduction")}
>
<Switch />
</Form.Item>
</div>
)}
<Button loading={loading} htmlType="submit">
{t("general.actions.submit")}
</Button>
</Form>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(JobChecklistForm);

View File

@@ -0,0 +1,13 @@
import React from "react";
import { PrinterFilled } from "@ant-design/icons";
export default function JobChecklistTemplateItem({
templateKey,
renderTemplate,
}) {
return (
<div>
{templateKey}
<PrinterFilled onClick={() => renderTemplate(templateKey)} />
</div>
);
}

View File

@@ -0,0 +1,63 @@
import React from "react";
import JobIntakeTemplateItem from "../job-checklist-template-item/job-checklist-template-item.component";
import { useParams } from "react-router-dom";
import RenderTemplate, {
displayTemplateInWindow,
} from "../../../../utils/RenderTemplate";
import { Button } from "antd";
import { selectBodyshop } from "../../../../redux/user/user.selectors";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { useTranslation } from "react-i18next";
import { logImEXEvent } from "../../../../firebase/firebase.utils";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function JobIntakeTemplateList({ bodyshop, templates }) {
const { jobId } = useParams();
const { t } = useTranslation();
const renderTemplate = async (templateKey) => {
logImEXEvent("job_checklist_template_render");
const html = await RenderTemplate(
{
name: templateKey,
variables: { id: jobId },
},
bodyshop
);
displayTemplateInWindow(html);
};
const renderAllTemplates = () => {
logImEXEvent("job_checklist_render_all_templates");
templates.forEach((template) => renderTemplate(template));
};
return (
<div>
{t("intake.labels.printpack")}
<Button onClick={renderAllTemplates}>
{t("checklist.actions.printall")}
</Button>
{templates.map((template) => (
<JobIntakeTemplateItem
key={template}
templateKey={template}
renderTemplate={renderTemplate}
/>
))}
</div>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(JobIntakeTemplateList);

View File

@@ -0,0 +1,18 @@
import React from "react";
import JobChecklistTemplateList from "./components/job-checklist-template-list/job-checklist-template-list.component";
import JobChecklistForm from "./components/job-checklist-form/job-checklist-form.component";
import { Row, Col } from "antd";
export default function JobIntakeComponent({ checklistConfig, type }) {
const { form, templates } = checklistConfig;
return (
<Row>
<Col span={12}>
<JobChecklistTemplateList templates={templates} type={type} />
</Col>
<Col span={12}>
<JobChecklistForm formItems={form} type={type} />
</Col>
</Row>
);
}