Finished speed print setup + addition to print center modal. BOD-229

This commit is contained in:
Patrick Fic
2020-07-31 09:46:03 -07:00
parent 4130bd0bdb
commit 23f8243002
13 changed files with 498 additions and 106 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project be_version="2.7.1" version="1.2"> <babeledit_project version="1.2" be_version="2.7.1">
<!-- <!--
BabelEdit project file BabelEdit project file
@@ -886,6 +886,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>addspeedprint</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>addtemplate</name> <name>addtemplate</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -2077,6 +2098,74 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<folder_node>
<name>speedprint</name>
<children>
<concept_node>
<name>id</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>
<name>label</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>
<name>templates</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<folder_node> <folder_node>
<name>ssbuckets</name> <name>ssbuckets</name>
<children> <children>
@@ -2937,6 +3026,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>speedprint</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children> </children>
</folder_node> </folder_node>
<folder_node> <folder_node>
@@ -10414,6 +10524,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>required</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>type</name> <name>type</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -17440,6 +17571,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>speedprint</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>title</name> <name>title</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -21,7 +21,7 @@ export default function FormsFieldChanged({ form }) {
<Prompt <Prompt
when={true} when={true}
message={(location) => { message={(location) => {
console.log("location", location); //console.log("location", location);
if (loc.pathname === location.pathname) return false; if (loc.pathname === location.pathname) return false;
return t("general.messages.unsavedchangespopup"); return t("general.messages.unsavedchangespopup");
}} }}

View File

@@ -0,0 +1,21 @@
import React from "react";
import { UpOutlined, DownOutlined } from "@ant-design/icons";
export default function FormListMoveArrows({ move, index, total }) {
const upDisabled = index === 0;
const downDisabled = index === total - 1;
const handleUp = () => {
move(index, index - 1);
};
const handleDown = () => {
move(index, index - 1);
};
return (
<div>
<UpOutlined disabled={upDisabled} onClick={handleUp} />
<DownOutlined disabled={downDisabled} onClick={handleDown} />
</div>
);
}

View File

@@ -1,4 +1,4 @@
import { Collapse } from "antd"; import { Collapse, Row, Col } from "antd";
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
@@ -7,7 +7,7 @@ import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectPrintCenter } from "../../redux/modals/modals.selectors"; import { selectPrintCenter } from "../../redux/modals/modals.selectors";
import { import {
selectBodyshop, selectBodyshop,
selectCurrentUser selectCurrentUser,
} from "../../redux/user/user.selectors"; } from "../../redux/user/user.selectors";
import PrintCenterItem from "../print-center-item/print-center-item.component"; import PrintCenterItem from "../print-center-item/print-center-item.component";
import PrintCenterSpeedPrint from "../print-center-speed-print/print-center-speed-print.component"; import PrintCenterSpeedPrint from "../print-center-speed-print/print-center-speed-print.component";
@@ -24,29 +24,37 @@ const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("printCenter")), toggleModalVisible: () => dispatch(toggleModalVisible("printCenter")),
}); });
const colSpan = { md: { span: 24 }, lg: { span: 12 } };
export function PrintCenterJobsComponent({ bodyshop, printCenterModal }) { export function PrintCenterJobsComponent({ bodyshop, printCenterModal }) {
const { id: jobId } = printCenterModal.context; const { id: jobId } = printCenterModal.context;
const JobsReportsList = JobsReports(null); const JobsReportsList = JobsReports(null);
return ( return (
<div> <div>
<PrintCenterSpeedPrint job={jobId} /> <Row gutter={[16, 16]}>
<Collapse accordion> <Col {...colSpan}>
{JobsReportsList.map((section) => ( <PrintCenterSpeedPrint jobId={jobId} />
<Collapse.Panel key={section.key} header={section.title}> </Col>
<ul style={{ columns: "2 auto" }}> <Col {...colSpan}>
{section.items.map((item) => ( <Collapse accordion>
<PrintCenterItem {JobsReportsList.map((section) => (
key={item.key} <Collapse.Panel key={section.key} header={section.title}>
item={item} <ul style={{ columns: "2 auto" }}>
id={jobId} {section.items.map((item) => (
disabled={item.disabled} <PrintCenterItem
/> key={item.key}
))} item={item}
</ul> id={jobId}
</Collapse.Panel> disabled={item.disabled}
))} />
</Collapse> ))}
</ul>
</Collapse.Panel>
))}
</Collapse>
</Col>
</Row>
</div> </div>
); );
} }

View File

@@ -1,13 +1,14 @@
import { Button, Typography, List } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import { selectBodyshop } from "../../redux/user/user.selectors";
import RenderTemplate, { import RenderTemplate, {
displayTemplateInWindow, displayTemplateInWindow,
} from "../../utils/RenderTemplate"; } from "../../utils/RenderTemplate";
import { Button } from "antd"; import { TemplateList } from "../../utils/TemplateConstants";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, //currentUser: selectCurrentUser bodyshop: selectBodyshop, //currentUser: selectCurrentUser
@@ -16,16 +17,16 @@ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
}); });
export function PrintCenterSpeedPrint({ bodyshop, job }) { export function PrintCenterSpeedPrint({ bodyshop, jobId }) {
const { speedprint } = bodyshop; const { speedprint } = bodyshop;
const { t } = useTranslation();
const renderTemplate = async (templateKey) => { const renderTemplate = async (templateKey) => {
logImEXEvent("speed_print_template_render"); logImEXEvent("speed_print_template_render");
const html = await RenderTemplate( const html = await RenderTemplate(
{ {
name: templateKey, name: templateKey,
variables: { id: job.id }, variables: { id: jobId },
}, },
bodyshop bodyshop
); );
@@ -40,18 +41,41 @@ export function PrintCenterSpeedPrint({ bodyshop, job }) {
return ( return (
<div> <div>
{speedprint.map((sp) => ( <Typography.Title level={2}>
<div> {t("printcenter.labels.speedprint")}
{JSON.stringify(sp)} </Typography.Title>
<Button onClick={() => renderAllTemplates(sp.templates)}>
Print All <List
</Button> itemLayout="horizontal"
</div> dataSource={speedprint}
))} renderItem={(sp) => (
<List.Item
actions={[
<Button onClick={() => renderAllTemplates(sp.templates)}>
Print All
</Button>,
]}
>
<List.Item.Meta
title={sp.label}
description={renderTemplateList(sp.templates)}
/>
</List.Item>
)}
/>
</div> </div>
); );
} }
const renderTemplateList = (templates) => (
<span className="imex-flex-row__margin">
{templates.map((template, idx) => {
if (idx === templates.length - 1) return TemplateList[template].title;
return `${TemplateList[template].title}, `;
})}
</span>
);
export default connect( export default connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps

View File

@@ -16,78 +16,86 @@ import ShopInfoResponsibilityCenterComponent from "./shop-info.responsibilitycen
import ShopInfoSchedulingComponent from "./shop-info.scheduling.component"; import ShopInfoSchedulingComponent from "./shop-info.scheduling.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import ShopInfoIntakeChecklistComponent from "./shop-info.intake.component"; import ShopInfoIntakeChecklistComponent from "./shop-info.intake.component";
import ShopInfoSpeedPrint from "./shop-info.speedprint.component";
export default function ShopInfoComponent({ form, saveLoading }) { export default function ShopInfoComponent({ form, saveLoading }) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div> <div>
<Button type='primary' loading={saveLoading} htmlType='submit'> <Button type="primary" loading={saveLoading} htmlType="submit">
{t("general.actions.save")} {t("general.actions.save")}
</Button> </Button>
<Collapse defaultActiveKey='shopinfo'> <Collapse>
<Collapse.Panel key='shopinfo' header={t("bodyshop.labels.shopinfo")}> <Collapse.Panel key="shopinfo" header={t("bodyshop.labels.shopinfo")}>
<LayoutFormRow> <LayoutFormRow>
<Form.Item label={t("bodyshop.fields.shopname")} name='shopname'> <Form.Item label={t("bodyshop.fields.shopname")} name="shopname">
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item label={t("bodyshop.fields.address1")} name='address1'> <Form.Item label={t("bodyshop.fields.address1")} name="address1">
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item label={t("bodyshop.fields.address2")} name='address2'> <Form.Item label={t("bodyshop.fields.address2")} name="address2">
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item label={t("bodyshop.fields.city")} name='city'> <Form.Item label={t("bodyshop.fields.city")} name="city">
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item label={t("bodyshop.fields.state")} name='state'> <Form.Item label={t("bodyshop.fields.state")} name="state">
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item label={t("bodyshop.fields.zip_post")} name='zip_post'> <Form.Item label={t("bodyshop.fields.zip_post")} name="zip_post">
<Input /> <Input />
</Form.Item> </Form.Item>
</LayoutFormRow> </LayoutFormRow>
<LayoutFormRow> <LayoutFormRow>
<Form.Item label={t("bodyshop.fields.country")} name='country'> <Form.Item label={t("bodyshop.fields.country")} name="country">
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item label={t("bodyshop.fields.email")} name='email'> <Form.Item label={t("bodyshop.fields.email")} name="email">
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.federal_tax_id")} label={t("bodyshop.fields.federal_tax_id")}
name='federal_tax_id'> name="federal_tax_id"
>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.insurance_vendor_id")} label={t("bodyshop.fields.insurance_vendor_id")}
name='insurance_vendor_id'> name="insurance_vendor_id"
>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.logo_img_path")} label={t("bodyshop.fields.logo_img_path")}
name='logo_img_path'> name="logo_img_path"
>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.state_tax_id")} label={t("bodyshop.fields.state_tax_id")}
name='state_tax_id'> name="state_tax_id"
>
<Input /> <Input />
</Form.Item> </Form.Item>
</LayoutFormRow> </LayoutFormRow>
<LayoutFormRow> <LayoutFormRow>
<Form.Item <Form.Item
label={t("bodyshop.fields.invoice_federal_tax_rate")} label={t("bodyshop.fields.invoice_federal_tax_rate")}
name={["invoice_tax_rates", "federal_tax_rate"]}> name={["invoice_tax_rates", "federal_tax_rate"]}
>
<InputNumber /> <InputNumber />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.invoice_state_tax_rate")} label={t("bodyshop.fields.invoice_state_tax_rate")}
name={["invoice_tax_rates", "state_tax_rate"]}> name={["invoice_tax_rates", "state_tax_rate"]}
>
<InputNumber /> <InputNumber />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.invoice_local_tax_rate")} label={t("bodyshop.fields.invoice_local_tax_rate")}
name={["invoice_tax_rates", "local_tax_rate"]}> name={["invoice_tax_rates", "local_tax_rate"]}
>
<InputNumber /> <InputNumber />
</Form.Item> </Form.Item>
@@ -99,7 +107,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<InputNumber min={15} precision={0} /> <InputNumber min={15} precision={0} />
</Form.Item> </Form.Item>
</LayoutFormRow> </LayoutFormRow>
@@ -112,7 +121,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<InputNumber min={0} precision={0} /> <InputNumber min={0} precision={0} />
</Form.Item> </Form.Item>
@@ -124,7 +134,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<InputNumber min={0} precision={0} /> <InputNumber min={0} precision={0} />
</Form.Item> </Form.Item>
@@ -136,7 +147,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<InputNumber min={0} max={12} precision={0} /> <InputNumber min={0} max={12} precision={0} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@@ -148,8 +160,9 @@ export default function ShopInfoComponent({ form, saveLoading }) {
message: t("general.validation.required"), message: t("general.validation.required"),
type: "array", type: "array",
}, },
]}> ]}
<Select mode='tags' /> >
<Select mode="tags" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.labels.accountingtiers")} label={t("bodyshop.labels.accountingtiers")}
@@ -159,7 +172,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]} ]}
name={["accountingconfig", "tiers"]}> name={["accountingconfig", "tiers"]}
>
<Radio.Group> <Radio.Group>
<Radio value={2}>2</Radio> <Radio value={2}>2</Radio>
<Radio value={3}>3</Radio> <Radio value={3}>3</Radio>
@@ -179,15 +193,17 @@ export default function ShopInfoComponent({ form, saveLoading }) {
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]} ]}
name={["accountingconfig", "twotierpref"]}> name={["accountingconfig", "twotierpref"]}
>
<Radio.Group <Radio.Group
disabled={ disabled={
form.getFieldValue(["accountingconfig", "tiers"]) === 3 form.getFieldValue(["accountingconfig", "tiers"]) === 3
}> }
<Radio value='name'> >
<Radio value="name">
{t("bodyshop.labels.2tiername")} {t("bodyshop.labels.2tiername")}
</Radio> </Radio>
<Radio value='source'> <Radio value="source">
{t("bodyshop.labels.2tiersource")} {t("bodyshop.labels.2tiersource")}
</Radio> </Radio>
</Radio.Group> </Radio.Group>
@@ -203,7 +219,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
{fields.map((field, index) => ( {fields.map((field, index) => (
<Form.Item <Form.Item
key={field.key} key={field.key}
style={{ padding: 0, margin: 2 }}> style={{ padding: 0, margin: 2 }}
>
<div style={{ display: "flex" }}> <div style={{ display: "flex" }}>
<Form.Item <Form.Item
style={{ padding: 0, margin: 2 }} style={{ padding: 0, margin: 2 }}
@@ -215,7 +232,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@@ -228,7 +246,8 @@ export default function ShopInfoComponent({ form, saveLoading }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<Input /> <Input />
</Form.Item> </Form.Item>
<DeleteFilled <DeleteFilled
@@ -241,11 +260,12 @@ export default function ShopInfoComponent({ form, saveLoading }) {
))} ))}
<Form.Item> <Form.Item>
<Button <Button
type='dashed' type="dashed"
onClick={() => { onClick={() => {
add(); add();
}} }}
style={{ width: "100%" }}> style={{ width: "100%" }}
>
{t("general.actions.add")} {t("general.actions.add")}
</Button> </Button>
</Form.Item> </Form.Item>
@@ -255,26 +275,36 @@ export default function ShopInfoComponent({ form, saveLoading }) {
</Form.List> </Form.List>
</Collapse.Panel> </Collapse.Panel>
<Collapse.Panel <Collapse.Panel
key='roStatus' key="speedprint"
header={t("bodyshop.labels.jobstatuses")}> header={t("bodyshop.labels.speedprint")}
>
<ShopInfoSpeedPrint form={form} />
</Collapse.Panel>
<Collapse.Panel
key="roStatus"
header={t("bodyshop.labels.jobstatuses")}
>
<ShopInfoROStatusComponent form={form} /> <ShopInfoROStatusComponent form={form} />
</Collapse.Panel> </Collapse.Panel>
<Collapse.Panel <Collapse.Panel
key='scheduling' key="scheduling"
header={t("bodyshop.labels.scheduling")}> header={t("bodyshop.labels.scheduling")}
>
<ShopInfoSchedulingComponent form={form} /> <ShopInfoSchedulingComponent form={form} />
</Collapse.Panel> </Collapse.Panel>
<Collapse.Panel <Collapse.Panel
key='orderStatus' key="orderStatus"
header={t("bodyshop.labels.orderstatuses")}> header={t("bodyshop.labels.orderstatuses")}
>
<ShopInfoOrderStatusComponent form={form} /> <ShopInfoOrderStatusComponent form={form} />
</Collapse.Panel> </Collapse.Panel>
<Collapse.Panel <Collapse.Panel
key='responsibilityCenters' key="responsibilityCenters"
header={t("bodyshop.labels.responsibilitycenters.title")}> header={t("bodyshop.labels.responsibilitycenters.title")}
>
<ShopInfoResponsibilityCenterComponent form={form} /> <ShopInfoResponsibilityCenterComponent form={form} />
</Collapse.Panel> </Collapse.Panel>
<Collapse.Panel key='intake' header={t("bodyshop.labels.intake")}> <Collapse.Panel key="intake" header={t("bodyshop.labels.intake")}>
<ShopInfoIntakeChecklistComponent form={form} /> <ShopInfoIntakeChecklistComponent form={form} />
</Collapse.Panel> </Collapse.Panel>
</Collapse> </Collapse>

View File

@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
import { TemplateList } from "../../utils/TemplateConstants"; import { TemplateList } from "../../utils/TemplateConstants";
import ConfigFormTypes from "../config-form-components/config-form-types"; import ConfigFormTypes from "../config-form-components/config-form-types";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
const SelectorDiv = styled.div` const SelectorDiv = styled.div`
.ant-form-item .ant-select { .ant-form-item .ant-select {
@@ -18,14 +19,14 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
return ( return (
<div> <div>
<Form.List name={["intakechecklist", "form"]}> <Form.List name={["intakechecklist", "form"]}>
{(fields, { add, remove }) => { {(fields, { add, remove, move }) => {
return ( return (
<div> <div>
{fields.map((field, index) => ( {fields.map((field, index) => (
<Form.Item key={field.key} style={{ padding: 0, margin: 2 }}> <Form.Item key={field.key} style={{ padding: 0, margin: 2 }}>
<div className='imex-flex-row'> <div className="imex-flex-row">
<Form.Item <Form.Item
className='imex-flex-row__margin' className="imex-flex-row__margin"
label={t("jobs.fields.intake.name")} label={t("jobs.fields.intake.name")}
key={`${index}name`} key={`${index}name`}
name={[field.name, "name"]} name={[field.name, "name"]}
@@ -34,12 +35,13 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
className='imex-flex-row__margin' className="imex-flex-row__margin"
label={t("jobs.fields.intake.type")} label={t("jobs.fields.intake.type")}
key={`${index}type`} key={`${index}type`}
name={[field.name, "type"]} name={[field.name, "type"]}
@@ -48,7 +50,8 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<Select> <Select>
{Object.keys(ConfigFormTypes).map((i, idx) => ( {Object.keys(ConfigFormTypes).map((i, idx) => (
<Select.Option key={i} value={i}> <Select.Option key={i} value={i}>
@@ -59,7 +62,7 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
</Form.Item> </Form.Item>
<Form.Item <Form.Item
className='imex-flex-row__margin' className="imex-flex-row__margin"
label={t("jobs.fields.intake.label")} label={t("jobs.fields.intake.label")}
key={`${index}label`} key={`${index}label`}
name={[field.name, "label"]} name={[field.name, "label"]}
@@ -68,16 +71,18 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]}> ]}
>
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
className='imex-flex-row__margin' className="imex-flex-row__margin"
label={t("general.fields.required")} label={t("jobs.fields.intake.required")}
key={`${index}required`} key={`${index}required`}
name={[field.name, "required"]} name={[field.name, "required"]}
valuePropName='checked'> valuePropName="checked"
>
<Switch /> <Switch />
</Form.Item> </Form.Item>
@@ -86,16 +91,22 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
remove(field.name); remove(field.name);
}} }}
/> />
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</div> </div>
</Form.Item> </Form.Item>
))} ))}
<Form.Item> <Form.Item>
<Button <Button
type='dashed' type="dashed"
onClick={() => { onClick={() => {
add(); add();
}} }}
style={{ width: "100%" }}> style={{ width: "100%" }}
>
{t("general.actions.add")} {t("general.actions.add")}
</Button> </Button>
</Form.Item> </Form.Item>
@@ -114,12 +125,14 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
message: t("general.validation.required"), message: t("general.validation.required"),
type: "array", type: "array",
}, },
]}> ]}
<Select mode='multiple'> >
<Select mode="multiple">
{Object.keys(TemplateList).map((i) => ( {Object.keys(TemplateList).map((i) => (
<Select.Option <Select.Option
key={TemplateList[i].key} key={TemplateList[i].key}
value={TemplateList[i].key}> value={TemplateList[i].key}
>
{TemplateList[i].title} {TemplateList[i].title}
</Select.Option> </Select.Option>
))} ))}

View File

@@ -0,0 +1,105 @@
import { DeleteFilled } from "@ant-design/icons";
import { Button, Col, Form, Input, InputNumber, Row, Select } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { TemplateList } from "../../utils/TemplateConstants";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
//TODO Fix up styles.
export default function ShopInfoSpeedPrint({ bodyshop, form }) {
const { t } = useTranslation();
return (
<div>
<Form.List name={["speedprint"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key} style={{ padding: 0, margin: 2 }}>
<div className="imex-flex-row">
<Form.Item
className="imex-flex-row__margin"
label={t("bodyshop.fields.speedprint.id")}
key={`${index}id`}
name={[field.name, "id"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
className="imex-flex-row__margin"
label={t("bodyshop.fields.speedprint.label")}
key={`${index}label`}
name={[field.name, "label"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
className="imex-flex-row__margin"
name={[field.name, "templates"]}
label={t("bodyshop.fields.speedprint.templates")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="multiple">
{Object.keys(TemplateList)
.map((key) => TemplateList[key])
.filter((template) => template.drivingId === "job")
.map((template, idx) => (
<Select.Option key={idx} value={template.key}>
{template.title}
</Select.Option>
))}
</Select>
</Form.Item>
<DeleteFilled
className="imex-flex-row__margin"
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</div>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addspeedprint")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</div>
);
}

View File

@@ -73,6 +73,7 @@
"bodyshop": { "bodyshop": {
"actions": { "actions": {
"addbucket": "Add Bucket", "addbucket": "Add Bucket",
"addspeedprint": "Add Speed Print",
"addtemplate": "Add Template", "addtemplate": "Add Template",
"newstatus": "Add Status" "newstatus": "Add Status"
}, },
@@ -135,6 +136,11 @@
"tow": "Towing" "tow": "Towing"
}, },
"shopname": "Shop Name", "shopname": "Shop Name",
"speedprint": {
"id": "Id",
"label": "Label",
"templates": "Templates"
},
"ssbuckets": { "ssbuckets": {
"gte": "Greater Than/Equal to (hrs)", "gte": "Greater Than/Equal to (hrs)",
"id": "ID", "id": "ID",
@@ -182,7 +188,8 @@
"title": "Responsibility Centers" "title": "Responsibility Centers"
}, },
"scheduling": "SMART Scheduling", "scheduling": "SMART Scheduling",
"shopinfo": "Shop Information" "shopinfo": "Shop Information",
"speedprint": "Speed Print Configuration"
}, },
"successes": { "successes": {
"save": "Bodyshop saved successfully. " "save": "Bodyshop saved successfully. "
@@ -665,6 +672,7 @@
"intake": { "intake": {
"label": "Label", "label": "Label",
"name": "Name", "name": "Name",
"required": "Required?",
"type": "Type" "type": "Type"
}, },
"kmin": "Mileage In", "kmin": "Mileage In",
@@ -1078,6 +1086,7 @@
"labels": { "labels": {
"misc": "Miscellaneous Documents", "misc": "Miscellaneous Documents",
"repairorder": "Repair Order Related", "repairorder": "Repair Order Related",
"speedprint": "Speed Print",
"title": "Print Center" "title": "Print Center"
} }
}, },

View File

@@ -73,6 +73,7 @@
"bodyshop": { "bodyshop": {
"actions": { "actions": {
"addbucket": "", "addbucket": "",
"addspeedprint": "",
"addtemplate": "", "addtemplate": "",
"newstatus": "" "newstatus": ""
}, },
@@ -135,6 +136,11 @@
"tow": "" "tow": ""
}, },
"shopname": "", "shopname": "",
"speedprint": {
"id": "",
"label": "",
"templates": ""
},
"ssbuckets": { "ssbuckets": {
"gte": "", "gte": "",
"id": "", "id": "",
@@ -182,7 +188,8 @@
"title": "" "title": ""
}, },
"scheduling": "", "scheduling": "",
"shopinfo": "" "shopinfo": "",
"speedprint": ""
}, },
"successes": { "successes": {
"save": "" "save": ""
@@ -665,6 +672,7 @@
"intake": { "intake": {
"label": "", "label": "",
"name": "", "name": "",
"required": "",
"type": "" "type": ""
}, },
"kmin": "Kilometraje en", "kmin": "Kilometraje en",
@@ -1078,6 +1086,7 @@
"labels": { "labels": {
"misc": "", "misc": "",
"repairorder": "", "repairorder": "",
"speedprint": "",
"title": "" "title": ""
} }
}, },

View File

@@ -73,6 +73,7 @@
"bodyshop": { "bodyshop": {
"actions": { "actions": {
"addbucket": "", "addbucket": "",
"addspeedprint": "",
"addtemplate": "", "addtemplate": "",
"newstatus": "" "newstatus": ""
}, },
@@ -135,6 +136,11 @@
"tow": "" "tow": ""
}, },
"shopname": "", "shopname": "",
"speedprint": {
"id": "",
"label": "",
"templates": ""
},
"ssbuckets": { "ssbuckets": {
"gte": "", "gte": "",
"id": "", "id": "",
@@ -182,7 +188,8 @@
"title": "" "title": ""
}, },
"scheduling": "", "scheduling": "",
"shopinfo": "" "shopinfo": "",
"speedprint": ""
}, },
"successes": { "successes": {
"save": "" "save": ""
@@ -665,6 +672,7 @@
"intake": { "intake": {
"label": "", "label": "",
"name": "", "name": "",
"required": "",
"type": "" "type": ""
}, },
"kmin": "Kilométrage en", "kmin": "Kilométrage en",
@@ -1078,6 +1086,7 @@
"labels": { "labels": {
"misc": "", "misc": "",
"repairorder": "", "repairorder": "",
"speedprint": "",
"title": "" "title": ""
} }
}, },

View File

@@ -22,7 +22,7 @@ export default async function RenderTemplate(templateObject, bodyshop) {
} else { } else {
//No template found.Uh oh. //No template found.Uh oh.
alert("Error: Template key does not exist."); alert("Error: Template key does not exist.");
//throw new Error("Template key does not exist."); throw new Error("Template key does not exist.");
} }
const { data: contextData } = await client.query({ const { data: contextData } = await client.query({

View File

@@ -7,50 +7,62 @@ export const TemplateList = {
appointment_reminder: { appointment_reminder: {
title: "Appointment Reminder", title: "Appointment Reminder",
description: "Sent to a customer as a reminder of an upcoming appointment.", description: "Sent to a customer as a reminder of an upcoming appointment.",
drivingId: "Appointment Id", drivingId: "appointment",
key: "appointment_reminder", key: "appointment_reminder",
}, },
appointment_confirmation: { appointment_confirmation: {
title: "Appointment Confirmation", title: "Appointment Confirmation",
description: description:
"Sent to a customer as a Confirmation of an upcoming appointment.", "Sent to a customer as a Confirmation of an upcoming appointment.",
drivingId: "Appointment Id", drivingId: "appointment",
key: "appointment_confirmation", key: "appointment_confirmation",
}, },
parts_order_confirmation: { parts_order_confirmation: {
title: "Parts Order Confirmation", title: "Parts Order Confirmation",
description: "Parts order template including part details", description: "Parts order template including part details",
drivingId: "Parts order Id", drivingId: "partsorder",
key: "parts_order_confirmation", key: "parts_order_confirmation",
}, },
estimate_detail: { estimate_detail: {
title: "Estimate Detail Lines", title: "Estimate Detail Lines",
description: "Est Detail", description: "Est Detail",
drivingId: "test does not exist.", drivingId: "job",
key: "estimate_detail", key: "estimate_detail",
}, },
cover_sheet_landscape: {
title: "Cover Sheet - Landscape",
description: "Cover sheet landscape",
drivingId: "job",
key: "cover_sheet_landscape",
},
cover_sheet_portrait: {
title: "Cover Sheet - portrait",
description: "Cover sheet portrait",
drivingId: "job",
key: "cover_sheet_portrait",
},
parts_return_confirmation: { parts_return_confirmation: {
title: "Parts Return Confirmation", title: "Parts Return Confirmation",
description: "Parts Return template including part details", description: "Parts Return template including part details",
drivingId: "Parts order Id", drivingId: "partsorder",
key: "parts_return_confirmation", key: "parts_return_confirmation",
}, },
csi_invitation: { csi_invitation: {
title: "Customer Survey Invitation", title: "Customer Survey Invitation",
description: "Customer Survey Invitation", description: "Customer Survey Invitation",
drivingId: "csi Id", drivingId: "csi",
key: "csi_invitation", key: "csi_invitation",
}, },
payment_receipt: { payment_receipt: {
title: "Payment Receipt", title: "Payment Receipt",
description: "Receipt of payment for customer", description: "Receipt of payment for customer",
drivingId: "Payment Id", drivingId: "payment",
key: "payment_receipt", key: "payment_receipt",
}, },
time_tickets_by_employee: { time_tickets_by_employee: {
title: "Time Tickets by Employee", title: "Time Tickets by Employee",
description: "Time tickets for employee with date range", description: "Time tickets for employee with date range",
drivingId: "Employee ID with start and end date", drivingId: "employee",
key: "time_tickets_by_employee", key: "time_tickets_by_employee",
}, },
}; };