Cleanup Shop Config.

This commit is contained in:
Patrick Fic
2021-04-07 17:39:46 -07:00
parent bac671ff5c
commit 54e5129fd4
16 changed files with 2682 additions and 2585 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project version="1.2" be_version="2.7.1"> <babeledit_project be_version="2.7.1" version="1.2">
<!-- <!--
BabelEdit project file BabelEdit project file
@@ -6451,6 +6451,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>accountingsetup</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>accountingtiers</name> <name>accountingtiers</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -6535,6 +6556,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>businessinformation</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>checklists</name> <name>checklists</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -6682,6 +6724,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>insurancecos</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>intakechecklist</name> <name>intakechecklist</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -6766,6 +6829,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>messagingpresets</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>notemplatesavailable</name> <name>notemplatesavailable</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -6787,6 +6871,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>notespresets</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>orderstatuses</name> <name>orderstatuses</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -6808,6 +6913,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>partslocations</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>rbac</name> <name>rbac</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -6960,6 +7086,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>scoreboardsetup</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>shopinfo</name> <name>shopinfo</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -7002,6 +7149,48 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>ssbuckets</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>systemsettings</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>workingdays</name> <name>workingdays</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -1,14 +1,14 @@
import React, { forwardRef } from "react"; import React from "react";
import { BlockPicker } from "react-color"; import { SliderPicker } from "react-color";
//To be used as a form element only. //To be used as a form element only.
const ColorPickerFormItem = ({ value, onChange, style, ...restProps }, ref) => { const ColorPickerFormItem = ({ value, onChange, style, ...restProps }) => {
const handleChangeComplete = (color) => { const handleChangeComplete = (color) => {
if (onChange) onChange(color); if (onChange) onChange(color);
}; };
return ( return (
<BlockPicker <SliderPicker
{...restProps} {...restProps}
style={{ width: "100%", ...style }} style={{ width: "100%", ...style }}
color={value} color={value}
@@ -17,4 +17,4 @@ const ColorPickerFormItem = ({ value, onChange, style, ...restProps }, ref) => {
/> />
); );
}; };
export default forwardRef(ColorPickerFormItem); export default ColorPickerFormItem;

View File

@@ -1,4 +1,4 @@
import { Col, Divider, Row, Typography } from "antd"; import { Col, Divider, Row } from "antd";
import React from "react"; import React from "react";
import "./layout-form-row.styles.scss"; import "./layout-form-row.styles.scss";
@@ -9,13 +9,26 @@ export default function LayoutFormRow({
noDivider = false, noDivider = false,
...restProps ...restProps
}) { }) {
const DividerHeader = () =>
!noDivider && (
<Divider
orientation="left"
type="horizontal"
style={{ marginTop: ".8rem" }}
>
{header}
</Divider>
);
if (!!!children.length) { if (!!!children.length) {
//We have only one element. It's going to get the whole thing. //We have only one element. It's going to get the whole thing.
return ( return (
<div className="imex-form-row"> <div
{header ? ( className="imex-form-row"
<Typography.Title level={4}>{header}</Typography.Title> {...restProps}
) : null} style={{ marginBottom: ".8rem", ...restProps.style }}
>
<DividerHeader />
{children} {children}
</div> </div>
); );
@@ -44,12 +57,12 @@ export default function LayoutFormRow({
}; };
//{header ? <Typography.Title level={4}>{header}</Typography.Title> : null} //{header ? <Typography.Title level={4}>{header}</Typography.Title> : null}
return ( return (
<div className="imex-form-row" {...restProps}> <div
{!noDivider && ( className="imex-form-row"
<Divider orientation="left" type="horizontal"> {...restProps}
{header} style={{ marginBottom: ".8rem", ...restProps.style }}
</Divider> >
)} <DividerHeader />
<Row {...rowGutter}> <Row {...rowGutter}>
{children.map( {children.map(
(c, idx) => (c, idx) =>

View File

@@ -1,21 +1,7 @@
import { DeleteFilled } from "@ant-design/icons"; import { Button, Card, Tabs } from "antd";
import {
Button,
Collapse,
Form,
Input,
InputNumber,
Radio,
Select,
Switch,
} from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import PhoneFormItem, { import ShopInfoGeneral from "./shop-info.general.component";
PhoneItemFormatterValidation,
} from "../form-items-formatted/phone-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.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 ShopInfoLaborRates from "./shop-info.laborrates.component"; import ShopInfoLaborRates from "./shop-info.laborrates.component";
import ShopInfoOrderStatusComponent from "./shop-info.orderstatus.component"; import ShopInfoOrderStatusComponent from "./shop-info.orderstatus.component";
@@ -28,814 +14,52 @@ 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> <Card
<Button extra={
type="primary" <Button
loading={saveLoading} type="primary"
onClick={() => form.submit()} loading={saveLoading}
> onClick={() => form.submit()}
{t("general.actions.save")}
</Button>
<Collapse>
<Collapse.Panel key="shopinfo" header={t("bodyshop.labels.shopinfo")}>
<LayoutFormRow>
<Form.Item
label={t("bodyshop.fields.shopname")}
name="shopname"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.address1")}
name="address1"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item label={t("bodyshop.fields.address2")} name="address2">
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.city")}
name="city"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.state")}
name="state"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item label={t("bodyshop.fields.zip_post")} name="zip_post">
<Input />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow>
<Form.Item label={t("bodyshop.fields.country")} name="country">
<Input />
</Form.Item>
<Form.Item label={t("bodyshop.fields.email")} name="email">
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.phone")}
name="phone"
rules={[
({ getFieldValue }) =>
PhoneItemFormatterValidation(getFieldValue, "phone"),
]}
>
<PhoneFormItem />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.federal_tax_id")}
name="federal_tax_id"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.insurance_vendor_id")}
name="insurance_vendor_id"
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.logo_img_path")}
name={["logo_img_path", "src"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.logo_img_path_height")}
name={["logo_img_path", "height"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.logo_img_path_width")}
name={["logo_img_path", "width"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.state_tax_id")}
name="state_tax_id"
>
<Input />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow>
<Form.Item
label={t("bodyshop.fields.invoice_federal_tax_rate")}
name={["bill_tax_rates", "federal_tax_rate"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.invoice_state_tax_rate")}
name={["bill_tax_rates", "state_tax_rate"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.invoice_local_tax_rate")}
name={["bill_tax_rates", "local_tax_rate"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.appt_length")}
name={"appt_length"}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={15} precision={0} />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow header={t("bodyshop.labels.workingdays")}>
<Form.Item
label={t("general.labels.sunday")}
name={["workingdays", "sunday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.monday")}
name={["workingdays", "monday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.tuesday")}
name={["workingdays", "tuesday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.wednesday")}
name={["workingdays", "wednesday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.thursday")}
name={["workingdays", "thursday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.friday")}
name={["workingdays", "friday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.saturday")}
name={["workingdays", "saturday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow>
<Form.Item
label={t("bodyshop.fields.dailypainttarget")}
name={["scoreboard_target", "dailyPaintTarget"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} precision={0} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.dailybodytarget")}
name={["scoreboard_target", "dailyBodyTarget"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} precision={0} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.lastnumberworkingdays")}
name={["scoreboard_target", "lastNumberWorkingDays"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} max={12} precision={0} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.prodtargethrs")}
name={["prodtargethrs"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={1} precision={1} />
</Form.Item>
<Form.Item
name={["md_referral_sources"]}
label={t("bodyshop.fields.md_referral_sources")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
label={t("bodyshop.labels.accountingtiers")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
name={["accountingconfig", "tiers"]}
>
<Radio.Group>
<Radio value={2}>2</Radio>
<Radio value={3}>3</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
label={t("bodyshop.fields.inhousevendorid")}
name={"inhousevendorid"}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.default_adjustment_rate")}
name={"default_adjustment_rate"}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} precision={2} />
</Form.Item>
<Form.Item shouldUpdate>
{() => {
return (
<Form.Item
label={t("bodyshop.labels.2tiersetup")}
shouldUpdate
rules={[
{
required:
form.getFieldValue(["accountingconfig", "tiers"]) ===
2,
message: t("general.validation.required"),
},
]}
name={["accountingconfig", "twotierpref"]}
>
<Radio.Group
disabled={
form.getFieldValue(["accountingconfig", "tiers"]) === 3
}
>
<Radio value="name">
{t("bodyshop.labels.2tiername")}
</Radio>
<Radio value="source">
{t("bodyshop.labels.2tiersource")}
</Radio>
</Radio.Group>
</Form.Item>
);
}}
</Form.Item>
</LayoutFormRow>
<Form.List name={["md_messaging_presets"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item
key={field.key}
style={{ padding: 0, margin: 2 }}
>
<div style={{ display: "flex" }}>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.messaginglabel")}
key={`${index}label`}
name={[field.name, "label"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.messagingtext")}
key={`${index}text`}
name={[field.name, "text"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<DeleteFilled
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("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
<Form.List name={["md_notes_presets"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item
key={field.key}
style={{ padding: 0, margin: 2 }}
>
<div style={{ display: "flex" }}>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.noteslabel")}
key={`${index}label`}
name={[field.name, "label"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.notestext")}
key={`${index}text`}
name={[field.name, "text"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<DeleteFilled
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("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
<Form.List name={["md_parts_locations"]}>
{(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.partslocation")}
key={`${index}`}
name={[field.name]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</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.addpartslocation")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
<Form.List name={["md_ins_cos"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item
key={field.key}
style={{ padding: 0, margin: 2 }}
>
<div style={{ display: "flex" }}>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.md_ins_co.name")}
key={`${index}name`}
name={[field.name, "name"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.md_ins_co.street1")}
key={`${index}street1`}
name={[field.name, "street1"]}
>
<Input />
</Form.Item>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.md_ins_co.street2")}
key={`${index}street2`}
name={[field.name, "street2"]}
>
<Input />
</Form.Item>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.md_ins_co.city")}
key={`${index}city`}
name={[field.name, "city"]}
>
<Input />
</Form.Item>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.md_ins_co.state")}
key={`${index}state`}
name={[field.name, "state"]}
>
<Input />
</Form.Item>
<Form.Item
style={{ padding: 0, margin: 2 }}
label={t("bodyshop.fields.md_ins_co.zip")}
key={`${index}zip`}
name={[field.name, "zip"]}
>
<Input />
</Form.Item>
<DeleteFilled
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("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
<LayoutFormRow>
<Form.Item
name={["md_payment_types"]}
label={t("bodyshop.fields.md_payment_types")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
name={["md_classes"]}
label={t("bodyshop.fields.md_classes")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
name={["md_categories"]}
label={t("bodyshop.fields.md_categories")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
name={["enforce_class"]}
label={t("bodyshop.fields.enforce_class")}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
name={["target_touchtime"]}
label={t("bodyshop.fields.target_touchtime")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0.1} precision={1} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.use_fippa")}
name={["use_fippa"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_hour_split.prep")}
name={["md_hour_split", "prep"]}
dependencies={[["md_hour_split", "paint"]]}
rules={[
({ getFieldValue }) => ({
validator(rule, value) {
if (!value && !getFieldValue(["md_hour_split", "paint"])) {
return Promise.resolve();
}
if (
value + getFieldValue(["md_hour_split", "paint"]) ===
1
) {
return Promise.resolve();
}
return Promise.reject(t("bodyshop.validation.larsplit"));
},
}),
]}
>
<InputNumber min={0} max={1} precision={2} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_hour_split.paint")}
name={["md_hour_split", "paint"]}
dependencies={[["md_hour_split", "prep"]]}
rules={[
({ getFieldValue }) => ({
validator(rule, value) {
if (!value && !getFieldValue(["md_hour_split", "paint"])) {
return Promise.resolve();
}
if (
value + getFieldValue(["md_hour_split", "prep"]) ===
1
) {
return Promise.resolve();
}
return Promise.reject(t("bodyshop.validation.larsplit"));
},
}),
]}
>
<InputNumber min={0} max={1} precision={2} />
</Form.Item>
</LayoutFormRow>
</Collapse.Panel>
<Collapse.Panel
key="speedprint"
header={t("bodyshop.labels.speedprint")}
> >
{t("general.actions.save")}
</Button>
}
>
<Tabs>
<Tabs.TabPane key="general" tab={t("bodyshop.labels.shopinfo")}>
<ShopInfoGeneral form={form} />
</Tabs.TabPane>
<Tabs.TabPane key="speedprint" tab={t("bodyshop.labels.speedprint")}>
<ShopInfoSpeedPrint form={form} /> <ShopInfoSpeedPrint form={form} />
</Collapse.Panel> </Tabs.TabPane>
<Collapse.Panel key="rbac" header={t("bodyshop.labels.rbac")}> <Tabs.TabPane key="rbac" tab={t("bodyshop.labels.rbac")}>
<ShopInfoRbacComponent form={form} /> <ShopInfoRbacComponent form={form} />
</Collapse.Panel> </Tabs.TabPane>
<Collapse.Panel <Tabs.TabPane key="roStatus" tab={t("bodyshop.labels.jobstatuses")}>
key="roStatus"
header={t("bodyshop.labels.jobstatuses")}
>
<ShopInfoROStatusComponent form={form} /> <ShopInfoROStatusComponent form={form} />
</Collapse.Panel> </Tabs.TabPane>
<Collapse.Panel <Tabs.TabPane key="scheduling" tab={t("bodyshop.labels.scheduling")}>
key="scheduling"
header={t("bodyshop.labels.scheduling")}
>
<ShopInfoSchedulingComponent form={form} /> <ShopInfoSchedulingComponent form={form} />
</Collapse.Panel> </Tabs.TabPane>
<Collapse.Panel <Tabs.TabPane
key="orderStatus" key="orderStatus"
header={t("bodyshop.labels.orderstatuses")} tab={t("bodyshop.labels.orderstatuses")}
> >
<ShopInfoOrderStatusComponent form={form} /> <ShopInfoOrderStatusComponent form={form} />
</Collapse.Panel> </Tabs.TabPane>
<Collapse.Panel <Tabs.TabPane
key="responsibilityCenters" key="responsibilityCenters"
header={t("bodyshop.labels.responsibilitycenters.title")} tab={t("bodyshop.labels.responsibilitycenters.title")}
> >
<ShopInfoResponsibilityCenterComponent form={form} /> <ShopInfoResponsibilityCenterComponent form={form} />
</Collapse.Panel> </Tabs.TabPane>
<Collapse.Panel <Tabs.TabPane key="checklists" tab={t("bodyshop.labels.checklists")}>
key="checklists"
header={t("bodyshop.labels.checklists")}
>
<ShopInfoIntakeChecklistComponent form={form} /> <ShopInfoIntakeChecklistComponent form={form} />
</Collapse.Panel> </Tabs.TabPane>
<Collapse.Panel <Tabs.TabPane key="laborrates" tab={t("bodyshop.labels.laborrates")}>
key="laborrates"
header={t("bodyshop.labels.laborrates")}
>
<ShopInfoLaborRates form={form} /> <ShopInfoLaborRates form={form} />
</Collapse.Panel> </Tabs.TabPane>
</Collapse> </Tabs>
</div> </Card>
); );
} }

View File

@@ -0,0 +1,690 @@
import { DeleteFilled } from "@ant-design/icons";
import {
Button,
Form,
Input,
InputNumber,
Radio,
Select,
Space,
Switch,
} from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import PhoneFormItem, {
PhoneItemFormatterValidation,
} from "../form-items-formatted/phone-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function ShopInfoGeneral({ form }) {
const { t } = useTranslation();
return (
<div>
<LayoutFormRow header={t("bodyshop.labels.businessinformation")}>
<Form.Item
label={t("bodyshop.fields.shopname")}
name="shopname"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.address1")}
name="address1"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item label={t("bodyshop.fields.address2")} name="address2">
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.city")}
name="city"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.state")}
name="state"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item label={t("bodyshop.fields.zip_post")} name="zip_post">
<Input />
</Form.Item>
<Form.Item label={t("bodyshop.fields.country")} name="country">
<Input />
</Form.Item>
<Form.Item label={t("bodyshop.fields.email")} name="email">
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.phone")}
name="phone"
rules={[
({ getFieldValue }) =>
PhoneItemFormatterValidation(getFieldValue, "phone"),
]}
>
<PhoneFormItem />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.insurance_vendor_id")}
name="insurance_vendor_id"
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.logo_img_path")}
name={["logo_img_path", "src"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.logo_img_path_height")}
name={["logo_img_path", "height"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.logo_img_path_width")}
name={["logo_img_path", "width"]}
>
<Input />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow header={t("bodyshop.labels.accountingsetup")}>
<Form.Item
label={t("bodyshop.labels.accountingtiers")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
name={["accountingconfig", "tiers"]}
>
<Radio.Group>
<Radio value={2}>2</Radio>
<Radio value={3}>3</Radio>
</Radio.Group>
</Form.Item>
<Form.Item shouldUpdate>
{() => {
return (
<Form.Item
label={t("bodyshop.labels.2tiersetup")}
shouldUpdate
rules={[
{
required:
form.getFieldValue(["accountingconfig", "tiers"]) === 2,
message: t("general.validation.required"),
},
]}
name={["accountingconfig", "twotierpref"]}
>
<Radio.Group
disabled={
form.getFieldValue(["accountingconfig", "tiers"]) === 3
}
>
<Radio value="name">{t("bodyshop.labels.2tiername")}</Radio>
<Radio value="source">
{t("bodyshop.labels.2tiersource")}
</Radio>
</Radio.Group>
</Form.Item>
);
}}
</Form.Item>
<Form.Item
label={t("bodyshop.fields.inhousevendorid")}
name={"inhousevendorid"}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.default_adjustment_rate")}
name={"default_adjustment_rate"}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} precision={2} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.federal_tax_id")}
name="federal_tax_id"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.state_tax_id")}
name="state_tax_id"
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.invoice_federal_tax_rate")}
name={["bill_tax_rates", "federal_tax_rate"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.invoice_state_tax_rate")}
name={["bill_tax_rates", "state_tax_rate"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.invoice_local_tax_rate")}
name={["bill_tax_rates", "local_tax_rate"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
name={["md_payment_types"]}
label={t("bodyshop.fields.md_payment_types")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
name={["md_categories"]}
label={t("bodyshop.fields.md_categories")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
name={["md_classes"]}
label={t("bodyshop.fields.md_classes")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
name={["enforce_class"]}
label={t("bodyshop.fields.enforce_class")}
valuePropName="checked"
>
<Switch />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow header={t("bodyshop.labels.scoreboardsetup")}>
<Form.Item
label={t("bodyshop.fields.dailypainttarget")}
name={["scoreboard_target", "dailyPaintTarget"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} precision={0} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.dailybodytarget")}
name={["scoreboard_target", "dailyBodyTarget"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} precision={0} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.lastnumberworkingdays")}
name={["scoreboard_target", "lastNumberWorkingDays"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0} max={12} precision={0} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.prodtargethrs")}
name={["prodtargethrs"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={1} precision={1} />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow header={t("bodyshop.labels.systemsettings")}>
<Form.Item
name={["md_referral_sources"]}
label={t("bodyshop.fields.md_referral_sources")}
rules={[
{
required: true,
message: t("general.validation.required"),
type: "array",
},
]}
>
<Select mode="tags" />
</Form.Item>
<Form.Item
name={["target_touchtime"]}
label={t("bodyshop.fields.target_touchtime")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber min={0.1} precision={1} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.use_fippa")}
name={["use_fippa"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_hour_split.prep")}
name={["md_hour_split", "prep"]}
dependencies={[["md_hour_split", "paint"]]}
rules={[
({ getFieldValue }) => ({
validator(rule, value) {
if (!value && !getFieldValue(["md_hour_split", "paint"])) {
return Promise.resolve();
}
if (value + getFieldValue(["md_hour_split", "paint"]) === 1) {
return Promise.resolve();
}
return Promise.reject(t("bodyshop.validation.larsplit"));
},
}),
]}
>
<InputNumber min={0} max={1} precision={2} />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_hour_split.paint")}
name={["md_hour_split", "paint"]}
dependencies={[["md_hour_split", "prep"]]}
rules={[
({ getFieldValue }) => ({
validator(rule, value) {
if (!value && !getFieldValue(["md_hour_split", "paint"])) {
return Promise.resolve();
}
if (value + getFieldValue(["md_hour_split", "prep"]) === 1) {
return Promise.resolve();
}
return Promise.reject(t("bodyshop.validation.larsplit"));
},
}),
]}
>
<InputNumber min={0} max={1} precision={2} />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow header={t("bodyshop.labels.messagingpresets")}>
<Form.List name={["md_messaging_presets"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<LayoutFormRow noDivider>
<Form.Item
label={t("bodyshop.fields.messaginglabel")}
key={`${index}label`}
name={[field.name, "label"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.messagingtext")}
key={`${index}text`}
name={[field.name, "text"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Space wrap>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</Space>
</LayoutFormRow>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</LayoutFormRow>
<LayoutFormRow grow header={t("bodyshop.labels.notespresets")}>
<Form.List name={["md_notes_presets"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<LayoutFormRow noDivider>
<Form.Item
label={t("bodyshop.fields.noteslabel")}
key={`${index}label`}
name={[field.name, "label"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.notestext")}
key={`${index}text`}
name={[field.name, "text"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Space wrap>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</Space>
</LayoutFormRow>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</LayoutFormRow>
<LayoutFormRow grow header={t("bodyshop.labels.partslocations")}>
<Form.List name={["md_parts_locations"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<LayoutFormRow noDivider>
<Form.Item
className="imex-flex-row__margin"
label={t("bodyshop.fields.partslocation")}
key={`${index}`}
name={[field.name]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Space wrap>
<DeleteFilled
className="imex-flex-row__margin"
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</Space>
</LayoutFormRow>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addpartslocation")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</LayoutFormRow>
<LayoutFormRow grow header={t("bodyshop.labels.insurancecos")}>
<Form.List name={["md_ins_cos"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<LayoutFormRow noDivider>
<Form.Item
label={t("bodyshop.fields.md_ins_co.name")}
key={`${index}name`}
name={[field.name, "name"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_ins_co.street1")}
key={`${index}street1`}
name={[field.name, "street1"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_ins_co.street2")}
key={`${index}street2`}
name={[field.name, "street2"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_ins_co.city")}
key={`${index}city`}
name={[field.name, "city"]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_ins_co.state")}
key={`${index}state`}
name={[field.name, "state"]}
>
<Input />
</Form.Item>
<Space wrap>
<Form.Item
label={t("bodyshop.fields.md_ins_co.zip")}
key={`${index}zip`}
name={[field.name, "zip"]}
>
<Input />
</Form.Item>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</Space>
</LayoutFormRow>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</LayoutFormRow>
</div>
);
}

View File

@@ -1,13 +1,5 @@
import { DeleteFilled } from "@ant-design/icons"; import { DeleteFilled } from "@ant-design/icons";
import { import { Button, Form, Input, InputNumber, Select, Space, Switch } from "antd";
Button,
Form,
Input,
InputNumber,
Select,
Switch,
Typography,
} from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
@@ -28,149 +20,143 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
const TemplateListGenerated = TemplateList(); const TemplateListGenerated = TemplateList();
return ( return (
<div> <div>
<Typography.Title level={4}> <LayoutFormRow header={t("bodyshop.labels.intakechecklist")}>
{t("bodyshop.labels.intakechecklist")} <Form.List name={["intakechecklist", "form"]}>
</Typography.Title> {(fields, { add, remove, move }) => {
<Form.List name={["intakechecklist", "form"]}> return (
{(fields, { add, remove, move }) => { <div>
return ( {fields.map((field, index) => (
<div> <Form.Item key={field.key}>
{fields.map((field, index) => ( <LayoutFormRow noDivider>
<Form.Item key={field.key} style={{ padding: 0, margin: 2 }}> <Form.Item
<LayoutFormRow grow> label={t("jobs.fields.intake.name")}
<Form.Item key={`${index}name`}
className="imex-flex-row__margin" name={[field.name, "name"]}
label={t("jobs.fields.intake.name")} rules={[
key={`${index}name`} {
name={[field.name, "name"]} required: true,
rules={[ message: t("general.validation.required"),
{ },
required: true, ]}
message: t("general.validation.required"), >
}, <Input />
]} </Form.Item>
> <Form.Item
<Input /> label={t("jobs.fields.intake.type")}
</Form.Item> key={`${index}type`}
<Form.Item name={[field.name, "type"]}
className="imex-flex-row__margin" rules={[
label={t("jobs.fields.intake.type")} {
key={`${index}type`} required: true,
name={[field.name, "type"]} message: t("general.validation.required"),
rules={[ },
{ ]}
required: true, >
message: t("general.validation.required"), <Select>
}, {Object.keys(ConfigFormTypes).map((i, idx) => (
]} <Select.Option key={i} value={i}>
> {i}
<Select> </Select.Option>
{Object.keys(ConfigFormTypes).map((i, idx) => ( ))}
<Select.Option key={i} value={i}> </Select>
{i} </Form.Item>
</Select.Option> <Form.Item
))} label={t("jobs.fields.intake.label")}
</Select> key={`${index}label`}
</Form.Item> name={[field.name, "label"]}
<Form.Item rules={[
className="imex-flex-row__margin" {
label={t("jobs.fields.intake.label")} required: true,
key={`${index}label`} message: t("general.validation.required"),
name={[field.name, "label"]} },
rules={[ ]}
{ >
required: true, <Input />
message: t("general.validation.required"), </Form.Item>
},
]}
>
<Input />
</Form.Item>
<Form.Item
className="imex-flex-row__margin"
label={t("jobs.fields.intake.required")}
key={`${index}required`}
name={[field.name, "required"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item shouldUpdate>
{() => {
if (
form.getFieldValue([
"intakechecklist",
"form",
index,
"type",
]) !== "slider"
)
return null;
return (
<>
<Form.Item
className="imex-flex-row__margin"
label={t("jobs.fields.intake.min")}
key={`${index}min`}
name={[field.name, "min"]}
dependencies={[[field.name, "type"]]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
className="imex-flex-row__margin"
label={t("jobs.fields.intake.max")}
key={`${index}max`}
name={[field.name, "max"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
</>
);
}}
</Form.Item>
<DeleteFilled <Form.Item shouldUpdate>
onClick={() => { {() => {
remove(field.name); if (
}} form.getFieldValue([
/> "intakechecklist",
<FormListMoveArrows "form",
move={move} index,
index={index} "type",
total={fields.length} ]) !== "slider"
/> )
</LayoutFormRow> return null;
return (
<>
<Form.Item
label={t("jobs.fields.intake.min")}
key={`${index}min`}
name={[field.name, "min"]}
dependencies={[[field.name, "type"]]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("jobs.fields.intake.max")}
key={`${index}max`}
name={[field.name, "max"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
</>
);
}}
</Form.Item>
<Form.Item
label={t("jobs.fields.intake.required")}
key={`${index}required`}
name={[field.name, "required"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Space wrap>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</Space>
</LayoutFormRow>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
</Form.Item> </Form.Item>
))} </div>
<Form.Item> );
<Button }}
type="dashed" </Form.List>
onClick={() => { </LayoutFormRow>
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
<SelectorDiv> <SelectorDiv>
<Form.Item <Form.Item
name={["intakechecklist", "templates"]} name={["intakechecklist", "templates"]}
@@ -195,157 +181,153 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
</Select> </Select>
</Form.Item> </Form.Item>
</SelectorDiv> </SelectorDiv>
<Typography.Title level={4}>
{t("bodyshop.labels.deliverchecklist")}
</Typography.Title>
<Form.List name={["deliverchecklist", "form"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key} style={{ padding: 0, margin: 2 }}>
<LayoutFormRow grow>
<Form.Item
className="imex-flex-row__margin"
label={t("jobs.fields.intake.name")}
key={`${index}named`}
name={[field.name, "name"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item <LayoutFormRow header={t("bodyshop.labels.deliverchecklist")}>
className="imex-flex-row__margin" <Form.List name={["deliverchecklist", "form"]}>
label={t("jobs.fields.intake.type")} {(fields, { add, remove, move }) => {
key={`${index}typed`} return (
name={[field.name, "type"]} <div>
rules={[ {fields.map((field, index) => (
{ <Form.Item key={field.key}>
required: true, <LayoutFormRow noDivider>
message: t("general.validation.required"), <Form.Item
}, label={t("jobs.fields.intake.name")}
]} key={`${index}named`}
> name={[field.name, "name"]}
<Select> rules={[
{Object.keys(ConfigFormTypes).map((i, idx) => ( {
<Select.Option key={i} value={i}> required: true,
{i} message: t("general.validation.required"),
</Select.Option> },
))} ]}
</Select> >
</Form.Item> <Input />
</Form.Item>
<Form.Item <Form.Item
className="imex-flex-row__margin" label={t("jobs.fields.intake.type")}
label={t("jobs.fields.intake.label")} key={`${index}typed`}
key={`${index}labeld`} name={[field.name, "type"]}
name={[field.name, "label"]} rules={[
rules={[ {
{ required: true,
required: true, message: t("general.validation.required"),
message: t("general.validation.required"), },
}, ]}
]} >
> <Select>
<Input /> {Object.keys(ConfigFormTypes).map((i, idx) => (
</Form.Item> <Select.Option key={i} value={i}>
{i}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item <Form.Item
className="imex-flex-row__margin" label={t("jobs.fields.intake.label")}
label={t("jobs.fields.intake.required")} key={`${index}labeld`}
key={`${index}requiredd`} name={[field.name, "label"]}
name={[field.name, "required"]} rules={[
valuePropName="checked" {
> required: true,
<Switch /> message: t("general.validation.required"),
</Form.Item> },
]}
>
<Input />
</Form.Item>
<Form.Item shouldUpdate> <Form.Item shouldUpdate>
{() => { {() => {
if ( if (
form.getFieldValue([ form.getFieldValue([
"deliverchecklist", "deliverchecklist",
"form", "form",
index, index,
"type", "type",
]) !== "slider" ]) !== "slider"
) )
return null; return null;
return ( return (
<> <>
<Form.Item <Form.Item
className="imex-flex-row__margin" label={t("jobs.fields.intake.min")}
label={t("jobs.fields.intake.min")} key={`${index}mind`}
key={`${index}mind`} name={[field.name, "min"]}
name={[field.name, "min"]} dependencies={[[field.name, "type"]]}
dependencies={[[field.name, "type"]]} rules={[
rules={[ {
{ required:
required: form.getFieldValue([
form.getFieldValue([field.name, "type"]) === field.name,
"slider", "type",
message: t("general.validation.required"), ]) === "slider",
}, message: t("general.validation.required"),
]} },
> ]}
<InputNumber /> >
</Form.Item> <InputNumber />
<Form.Item </Form.Item>
className="imex-flex-row__margin" <Form.Item
label={t("jobs.fields.intake.max")} label={t("jobs.fields.intake.max")}
key={`${index}maxd`} key={`${index}maxd`}
name={[field.name, "max"]} name={[field.name, "max"]}
dependencies={[[field.name, "type"]]} dependencies={[[field.name, "type"]]}
rules={[ rules={[
{ {
required: required:
form.getFieldValue([field.name, "type"]) === form.getFieldValue([
"slider", field.name,
message: t("general.validation.required"), "type",
}, ]) === "slider",
]} message: t("general.validation.required"),
> },
<InputNumber /> ]}
</Form.Item> >
</> <InputNumber />
); </Form.Item>
}} </>
</Form.Item> );
<DeleteFilled }}
onClick={() => { </Form.Item>
remove(field.name); <Form.Item
}} label={t("jobs.fields.intake.required")}
/> key={`${index}requiredd`}
<FormListMoveArrows name={[field.name, "required"]}
move={move} valuePropName="checked"
index={index} >
total={fields.length} <Switch />
/> </Form.Item>
</LayoutFormRow> <DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows
move={move}
index={index}
total={fields.length}
/>
</LayoutFormRow>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
</Form.Item> </Form.Item>
))} </div>
<Form.Item> );
<Button }}
type="dashed" </Form.List>
onClick={() => { </LayoutFormRow>
add();
}}
style={{ width: "100%" }}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
<SelectorDiv> <SelectorDiv>
<Form.Item <Form.Item
name={["deliverchecklist", "templates"]} name={["deliverchecklist", "templates"]}

View File

@@ -6,59 +6,56 @@ export default function ShopInfoOrderStatusComponent({ form }) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div> <LayoutFormRow header={t("bodyshop.labels.orderstatuses")}>
<strong>{t("bodyshop.labels.orderstatuses")}</strong> <Form.Item
<LayoutFormRow> label={t("bodyshop.fields.statuses.default_bo")}
<Form.Item rules={[
label={t("bodyshop.fields.statuses.default_bo")} {
rules={[ required: true,
{ message: t("general.validation.required"),
required: true, },
message: t("general.validation.required"), ]}
}, name={["md_order_statuses", "default_bo"]}
]} >
name={["md_order_statuses", "default_bo"]} <Input />
> </Form.Item>
<Input /> <Form.Item
</Form.Item> label={t("bodyshop.fields.statuses.default_ordered")}
<Form.Item rules={[
label={t("bodyshop.fields.statuses.default_ordered")} {
rules={[ required: true,
{ message: t("general.validation.required"),
required: true, },
message: t("general.validation.required"), ]}
}, name={["md_order_statuses", "default_ordered"]}
]} >
name={["md_order_statuses", "default_ordered"]} <Input />
> </Form.Item>
<Input />
</Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.statuses.default_received")} label={t("bodyshop.fields.statuses.default_received")}
rules={[ rules={[
{ {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]} ]}
name={["md_order_statuses", "default_received"]} name={["md_order_statuses", "default_received"]}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.statuses.default_returned")} label={t("bodyshop.fields.statuses.default_returned")}
rules={[ rules={[
{ {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]} ]}
name={["md_order_statuses", "default_returned"]} name={["md_order_statuses", "default_returned"]}
> >
<Input /> <Input />
</Form.Item> </Form.Item>
</LayoutFormRow> </LayoutFormRow>
</div>
); );
} }

View File

@@ -1,9 +1,8 @@
import { DeleteFilled } from "@ant-design/icons"; import { Form, Select } from "antd";
import { Button, Col, Form, Input, Row, Select } from "antd";
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
const SelectorDiv = styled.div` const SelectorDiv = styled.div`
.ant-form-item .ant-select { .ant-form-item .ant-select {
width: 200px; width: 200px;
@@ -22,288 +21,242 @@ export default function ShopInfoROStatusComponent({ form }) {
}; };
return ( return (
<div> <SelectorDiv>
<Row> <Form.Item
<Col span={8}> name={["md_ro_statuses", "statuses"]}
{t("bodyshop.labels.alljobstatuses")} label={t("bodyshop.labels.alljobstatuses")}
<Form.List name={["md_ro_statuses", "statuses"]}> rules={[
{(fields, { add, remove, move }) => { {
return ( required: true,
<div> message: t("general.validation.required"),
{fields.map((field, index) => ( type: "array",
<Form.Item },
key={field.key} ]}
style={{ padding: 0, margin: 2 }} >
> <Select mode="tags" onBlur={handleBlur} />
<div style={{ display: "flex" }}> </Form.Item>
<Form.Item <Form.Item
style={{ padding: 0, margin: 2 }} name={["md_ro_statuses", "active_statuses"]}
label={t("bodyshop.fields.status")} label={t("bodyshop.fields.statuses.active_statuses")}
key={`${index}`} rules={[
name={[field.name]} {
rules={[ required: true,
{ message: t("general.validation.required"),
required: true, type: "array",
message: t("general.validation.required"), },
}, ]}
]} >
> <Select mode="multiple">
<Input onBlur={handleBlur} /> {options.map((item, idx) => (
</Form.Item> <Select.Option key={idx} value={item}>
<DeleteFilled {item}
onClick={() => { </Select.Option>
remove(field.name); ))}
}} </Select>
/> </Form.Item>
<FormListMoveArrows <Form.Item
move={move} name={["md_ro_statuses", "pre_production_statuses"]}
index={index} label={t("bodyshop.fields.statuses.pre_production_statuses")}
total={fields.length} rules={[
/> {
</div> required: true,
</Form.Item> message: t("general.validation.required"),
))} type: "array",
<Form.Item> },
<Button ]}
type="dashed" >
onClick={() => { <Select mode="multiple">
add(); {options.map((item, idx) => (
}} <Select.Option key={idx} value={item}>
style={{ width: "100%" }} {item}
> </Select.Option>
{t("bodyshop.actions.newstatus")} ))}
</Button> </Select>
</Form.Item> </Form.Item>
</div> <Form.Item
); name={["md_ro_statuses", "production_statuses"]}
}} label={t("bodyshop.fields.statuses.production_statuses")}
</Form.List> rules={[
</Col> {
<Col span={12}> required: true,
<SelectorDiv> message: t("general.validation.required"),
<Form.Item type: "array",
name={["md_ro_statuses", "active_statuses"]} },
label={t("bodyshop.fields.statuses.active_statuses")} ]}
rules={[ >
{ <Select mode="multiple">
required: true, {options.map((item, idx) => (
message: t("general.validation.required"), <Select.Option key={idx} value={item}>
type: "array", {item}
}, </Select.Option>
]} ))}
> </Select>
<Select mode="multiple"> </Form.Item>
{options.map((item, idx) => ( <Form.Item
<Select.Option key={idx} value={item}> name={["md_ro_statuses", "post_production_statuses"]}
{item} label={t("bodyshop.fields.statuses.post_production_statuses")}
</Select.Option> rules={[
))} {
</Select> required: true,
</Form.Item> message: t("general.validation.required"),
<Form.Item type: "array",
name={["md_ro_statuses", "pre_production_statuses"]} },
label={t("bodyshop.fields.statuses.pre_production_statuses")} ]}
rules={[ >
{ <Select mode="multiple">
required: true, {options.map((item, idx) => (
message: t("general.validation.required"), <Select.Option key={idx} value={item}>
type: "array", {item}
}, </Select.Option>
]} ))}
> </Select>
<Select mode="multiple"> </Form.Item>
{options.map((item, idx) => ( <LayoutFormRow noDivider>
<Select.Option key={idx} value={item}> <Form.Item
{item} label={t("bodyshop.fields.statuses.default_scheduled")}
</Select.Option> rules={[
))} {
</Select> required: true,
</Form.Item> message: t("general.validation.required"),
<Form.Item },
name={["md_ro_statuses", "production_statuses"]} ]}
label={t("bodyshop.fields.statuses.production_statuses")} name={["md_ro_statuses", "default_scheduled"]}
rules={[ >
{ <Select>
required: true, {options.map((item, idx) => (
message: t("general.validation.required"), <Select.Option key={idx} value={item}>
type: "array", {item}
}, </Select.Option>
]} ))}
> </Select>
<Select mode="multiple"> </Form.Item>
{options.map((item, idx) => ( <Form.Item
<Select.Option key={idx} value={item}> label={t("bodyshop.fields.statuses.default_arrived")}
{item} rules={[
</Select.Option> {
))} required: true,
</Select> message: t("general.validation.required"),
</Form.Item> },
<Form.Item ]}
name={["md_ro_statuses", "post_production_statuses"]} name={["md_ro_statuses", "default_arrived"]}
label={t("bodyshop.fields.statuses.post_production_statuses")} >
rules={[ <Select>
{ {options.map((item, idx) => (
required: true, <Select.Option key={idx} value={item}>
message: t("general.validation.required"), {item}
type: "array", </Select.Option>
}, ))}
]} </Select>
> </Form.Item>
<Select mode="multiple"> <Form.Item
{options.map((item, idx) => ( label={t("bodyshop.fields.statuses.default_exported")}
<Select.Option key={idx} value={item}> rules={[
{item} {
</Select.Option> required: true,
))} message: t("general.validation.required"),
</Select> },
</Form.Item> ]}
<Form.Item name={["md_ro_statuses", "default_exported"]}
label={t("bodyshop.fields.statuses.default_scheduled")} >
rules={[ <Select>
{ {options.map((item, idx) => (
required: true, <Select.Option key={idx} value={item}>
message: t("general.validation.required"), {item}
}, </Select.Option>
]} ))}
name={["md_ro_statuses", "default_scheduled"]} </Select>
> </Form.Item>
<Select> <Form.Item
{options.map((item, idx) => ( label={t("bodyshop.fields.statuses.default_imported")}
<Select.Option key={idx} value={item}> rules={[
{item} {
</Select.Option> required: true,
))} message: t("general.validation.required"),
</Select> },
</Form.Item> ]}
<Form.Item name={["md_ro_statuses", "default_imported"]}
label={t("bodyshop.fields.statuses.default_arrived")} >
rules={[ <Select>
{ {options.map((item, idx) => (
required: true, <Select.Option key={idx} value={item}>
message: t("general.validation.required"), {item}
}, </Select.Option>
]} ))}
name={["md_ro_statuses", "default_arrived"]} </Select>
> </Form.Item>
<Select> <Form.Item
{options.map((item, idx) => ( label={t("bodyshop.fields.statuses.default_invoiced")}
<Select.Option key={idx} value={item}> rules={[
{item} {
</Select.Option> required: true,
))} message: t("general.validation.required"),
</Select> },
</Form.Item> ]}
<Form.Item name={["md_ro_statuses", "default_invoiced"]}
label={t("bodyshop.fields.statuses.default_exported")} >
rules={[ <Select>
{ {options.map((item, idx) => (
required: true, <Select.Option key={idx} value={item}>
message: t("general.validation.required"), {item}
}, </Select.Option>
]} ))}
name={["md_ro_statuses", "default_exported"]} </Select>
> </Form.Item>
<Select> <Form.Item
{options.map((item, idx) => ( label={t("bodyshop.fields.statuses.default_completed")}
<Select.Option key={idx} value={item}> rules={[
{item} {
</Select.Option> required: true,
))} message: t("general.validation.required"),
</Select> },
</Form.Item> ]}
<Form.Item name={["md_ro_statuses", "default_completed"]}
label={t("bodyshop.fields.statuses.default_imported")} >
rules={[ <Select>
{ {options.map((item, idx) => (
required: true, <Select.Option key={idx} value={item}>
message: t("general.validation.required"), {item}
}, </Select.Option>
]} ))}
name={["md_ro_statuses", "default_imported"]} </Select>
> </Form.Item>
<Select> <Form.Item
{options.map((item, idx) => ( label={t("bodyshop.fields.statuses.default_delivered")}
<Select.Option key={idx} value={item}> rules={[
{item} {
</Select.Option> required: true,
))} message: t("general.validation.required"),
</Select> },
</Form.Item> ]}
<Form.Item name={["md_ro_statuses", "default_delivered"]}
label={t("bodyshop.fields.statuses.default_invoiced")} >
rules={[ <Select>
{ {options.map((item, idx) => (
required: true, <Select.Option key={idx} value={item}>
message: t("general.validation.required"), {item}
}, </Select.Option>
]} ))}
name={["md_ro_statuses", "default_invoiced"]} </Select>
> </Form.Item>
<Select> <Form.Item
{options.map((item, idx) => ( label={t("bodyshop.fields.statuses.default_void")}
<Select.Option key={idx} value={item}> rules={[
{item} {
</Select.Option> required: true,
))} message: t("general.validation.required"),
</Select> },
</Form.Item> ]}
<Form.Item name={["md_ro_statuses", "default_void"]}
label={t("bodyshop.fields.statuses.default_completed")} >
rules={[ <Select>
{ {options.map((item, idx) => (
required: true, <Select.Option key={idx} value={item}>
message: t("general.validation.required"), {item}
}, </Select.Option>
]} ))}
name={["md_ro_statuses", "default_completed"]} </Select>
> </Form.Item>
<Select> </LayoutFormRow>
{options.map((item, idx) => ( </SelectorDiv>
<Select.Option key={idx} value={item}>
{item}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
label={t("bodyshop.fields.statuses.default_delivered")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
name={["md_ro_statuses", "default_delivered"]}
>
<Select>
{options.map((item, idx) => (
<Select.Option key={idx} value={item}>
{item}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
label={t("bodyshop.fields.statuses.default_void")}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
name={["md_ro_statuses", "default_void"]}
>
<Select>
{options.map((item, idx) => (
<Select.Option key={idx} value={item}>
{item}
</Select.Option>
))}
</Select>
</Form.Item>
</SelectorDiv>
</Col>
</Row>
</div>
); );
} }

View File

@@ -1,12 +1,13 @@
import { DeleteFilled } from "@ant-design/icons"; import { DeleteFilled } from "@ant-design/icons";
import { import {
Button, Button,
Col, Divider,
Form, Form,
Input, Input,
InputNumber, InputNumber,
Row,
Select, Select,
Space,
Switch,
TimePicker, TimePicker,
} from "antd"; } from "antd";
import React from "react"; import React from "react";
@@ -20,73 +21,144 @@ export default function ShopInfoSchedulingComponent({ form }) {
return ( return (
<div> <div>
<Form.Item <LayoutFormRow>
label={t("bodyshop.fields.schedule_start_time")} <Form.Item
name={"schedule_start_time"} label={t("bodyshop.fields.appt_length")}
rules={[ name={"appt_length"}
{ rules={[
required: true, {
message: t("general.validation.required"), required: true,
}, message: t("general.validation.required"),
]} },
> ]}
<TimePicker showSecond={false} format="hh:mm" /> >
</Form.Item> <InputNumber min={15} precision={0} />
<Form.Item </Form.Item>
label={t("bodyshop.fields.schedule_end_time")} <Form.Item
name={"schedule_end_time"} label={t("bodyshop.fields.schedule_start_time")}
rules={[ name={"schedule_start_time"}
{ rules={[
required: true, {
message: t("general.validation.required"), required: true,
}, message: t("general.validation.required"),
]} },
> ]}
<TimePicker showSecond={false} format="hh:mm" /> >
</Form.Item> <TimePicker showSecond={false} format="hh:mm" />
<strong>{t("bodyshop.labels.apptcolors")}</strong> </Form.Item>
<Row> <Form.Item
<Col span={24}> label={t("bodyshop.fields.schedule_end_time")}
<Form.List name={["appt_colors"]}> name={"schedule_end_time"}
{(fields, { add, remove, move }) => { rules={[
return ( {
<div> required: true,
{fields.map((field, index) => ( message: t("general.validation.required"),
<Form.Item },
key={field.key} ]}
style={{ padding: 0, margin: 2 }} >
> <TimePicker showSecond={false} format="hh:mm" />
<LayoutFormRow> </Form.Item>
<Form.Item <Form.Item
className="imex-flex-row__margin" name={["appt_alt_transport"]}
label={t("bodyshop.fields.appt_colors.label")} label={t("bodyshop.fields.appt_alt_transport")}
key={`${index}aptcolorlabel`} rules={[
name={[field.name, "label"]} {
rules={[ message: t("general.validation.required"),
{ type: "array",
required: true, },
message: t("general.validation.required"), ]}
}, >
]} <Select mode="tags" />
> </Form.Item>
<Input /> </LayoutFormRow>
</Form.Item> <Divider orientation="left">{t("bodyshop.labels.workingdays")}</Divider>
<Form.Item <Space wrap size="large">
className="imex-flex-row__margin" <Form.Item
label={t("bodyshop.fields.appt_colors.color")} label={t("general.labels.sunday")}
key={`${index}aptcolorcolor`} name={["workingdays", "sunday"]}
name={[field.name, "color"]} valuePropName="checked"
rules={[ >
{ <Switch />
required: true, </Form.Item>
message: t("general.validation.required"), <Form.Item
}, label={t("general.labels.monday")}
]} name={["workingdays", "monday"]}
> valuePropName="checked"
<ColorpickerFormItemComponent /> >
</Form.Item> <Switch />
</Form.Item>
<Form.Item
label={t("general.labels.tuesday")}
name={["workingdays", "tuesday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.wednesday")}
name={["workingdays", "wednesday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.thursday")}
name={["workingdays", "thursday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.friday")}
name={["workingdays", "friday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
<Form.Item
label={t("general.labels.saturday")}
name={["workingdays", "saturday"]}
valuePropName="checked"
>
<Switch />
</Form.Item>
</Space>
<LayoutFormRow header={t("bodyshop.labels.apptcolors")}>
<Form.List name={["appt_colors"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<LayoutFormRow noDivider>
<Form.Item
label={t("bodyshop.fields.appt_colors.label")}
key={`${index}aptcolorlabel`}
name={[field.name, "label"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.appt_colors.color")}
key={`${index}aptcolorcolor`}
name={[field.name, "color"]}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<ColorpickerFormItemComponent />
</Form.Item>
<Space wrap>
<DeleteFilled <DeleteFilled
className="imex-flex-row__margin"
onClick={() => { onClick={() => {
remove(field.name); remove(field.name);
}} }}
@@ -96,140 +168,127 @@ export default function ShopInfoSchedulingComponent({ form }) {
index={index} index={index}
total={fields.length} total={fields.length}
/> />
</LayoutFormRow> </Space>
</Form.Item> </LayoutFormRow>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addapptcolor")}
</Button>
</Form.Item> </Form.Item>
</div> ))}
); <Form.Item>
}} <Button
</Form.List> type="dashed"
<Form.Item onClick={() => {
name={["appt_alt_transport"]} add();
label={t("bodyshop.fields.appt_alt_transport")} }}
rules={[ style={{ width: "100%" }}
{ >
message: t("general.validation.required"), {t("bodyshop.actions.addapptcolor")}
type: "array", </Button>
}, </Form.Item>
]} </div>
> );
<Select mode="tags" /> }}
</Form.Item> </Form.List>
<Form.List name={["ssbuckets"]}> </LayoutFormRow>
{(fields, { add, remove, move }) => { <LayoutFormRow header={t("bodyshop.labels.ssbuckets")}>
return ( <Form.List name={["ssbuckets"]}>
<div> {(fields, { add, remove, move }) => {
{fields.map((field, index) => ( return (
<Form.Item <div>
key={field.key} {fields.map((field, index) => (
style={{ padding: 0, margin: 2 }} <Form.Item key={field.key}>
> <LayoutFormRow noDivider>
<LayoutFormRow> <Form.Item
<Form.Item label={t("bodyshop.fields.ssbuckets.id")}
label={t("bodyshop.fields.ssbuckets.id")} key={`${index}id`}
key={`${index}id`} name={[field.name, "id"]}
name={[field.name, "id"]} rules={[
rules={[ {
{ required: true,
required: true, message: t("general.validation.required"),
message: t("general.validation.required"), },
}, ]}
]} >
> <Input />
<Input /> </Form.Item>
</Form.Item> <Form.Item
<Form.Item label={t("bodyshop.fields.ssbuckets.label")}
label={t("bodyshop.fields.ssbuckets.label")} key={`${index}label`}
key={`${index}label`} name={[field.name, "label"]}
name={[field.name, "label"]} rules={[
rules={[ {
{ required: true,
required: true, message: t("general.validation.required"),
message: t("general.validation.required"), },
}, ]}
]} >
> <Input />
<Input /> </Form.Item>
</Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.ssbuckets.gte")} label={t("bodyshop.fields.ssbuckets.gte")}
key={`${index}gte`} key={`${index}gte`}
name={[field.name, "gte"]} name={[field.name, "gte"]}
rules={[ rules={[
{ {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]} ]}
> >
<InputNumber /> <InputNumber />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.ssbuckets.lt")} label={t("bodyshop.fields.ssbuckets.lt")}
key={`${index}lt`} key={`${index}lt`}
name={[field.name, "lt"]} name={[field.name, "lt"]}
> >
<InputNumber /> <InputNumber />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bodyshop.fields.ssbuckets.target")} label={t("bodyshop.fields.ssbuckets.target")}
key={`${index}target`} key={`${index}target`}
name={[field.name, "target"]} name={[field.name, "target"]}
rules={[ rules={[
{ {
required: true, required: true,
message: t("general.validation.required"), message: t("general.validation.required"),
}, },
]} ]}
> >
<InputNumber /> <InputNumber />
</Form.Item> </Form.Item>
<div> <Space wrap>
<DeleteFilled <DeleteFilled
onClick={() => { onClick={() => {
remove(field.name); remove(field.name);
}} }}
/> />
<FormListMoveArrows <FormListMoveArrows
move={move} move={move}
index={index} index={index}
total={fields.length} total={fields.length}
/> />
</div> </Space>
</LayoutFormRow> </LayoutFormRow>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addbucket")}
</Button>
</Form.Item> </Form.Item>
</div> ))}
); <Form.Item>
}} <Button
</Form.List> type="dashed"
</Col> onClick={() => {
</Row> add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addbucket")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</LayoutFormRow>
</div> </div>
); );
} }

View File

@@ -1,5 +1,5 @@
import { DeleteFilled } from "@ant-design/icons"; import { DeleteFilled } from "@ant-design/icons";
import { Button, Form, Input, Select } from "antd"; import { Button, Form, Input, Select, Space } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { TemplateList } from "../../utils/TemplateConstants"; import { TemplateList } from "../../utils/TemplateConstants";
@@ -9,71 +9,66 @@ import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function ShopInfoSpeedPrint({ bodyshop, form }) { export default function ShopInfoSpeedPrint({ bodyshop, form }) {
const { t } = useTranslation(); const { t } = useTranslation();
const TemplateListGenerated = TemplateList(); const TemplateListGenerated = TemplateList();
console.log("TemplateListGenerated", TemplateListGenerated);
return ( return (
<div> <Form.List name={["speedprint"]}>
<Form.List name={["speedprint"]}> {(fields, { add, remove, move }) => {
{(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 }}> <LayoutFormRow grow>
<LayoutFormRow grow> <Form.Item
<Form.Item label={t("bodyshop.fields.speedprint.id")}
className="imex-flex-row__margin" key={`${index}id`}
label={t("bodyshop.fields.speedprint.id")} name={[field.name, "id"]}
key={`${index}id`} rules={[
name={[field.name, "id"]} {
rules={[ required: true,
{ message: t("general.validation.required"),
required: true, },
message: t("general.validation.required"), ]}
}, >
]} <Input />
> </Form.Item>
<Input /> <Form.Item
</Form.Item> label={t("bodyshop.fields.speedprint.label")}
<Form.Item key={`${index}label`}
className="imex-flex-row__margin" name={[field.name, "label"]}
label={t("bodyshop.fields.speedprint.label")} rules={[
key={`${index}label`} {
name={[field.name, "label"]} required: true,
rules={[ message: t("general.validation.required"),
{ },
required: true, ]}
message: t("general.validation.required"), >
}, <Input />
]} </Form.Item>
>
<Input />
</Form.Item>
<Form.Item <Form.Item
className="imex-flex-row__margin" name={[field.name, "templates"]}
name={[field.name, "templates"]} label={t("bodyshop.fields.speedprint.templates")}
label={t("bodyshop.fields.speedprint.templates")} rules={[
rules={[ {
{ required: true,
required: true, message: t("general.validation.required"),
message: t("general.validation.required"), type: "array",
type: "array", },
}, ]}
]} >
> <Select mode="multiple">
<Select mode="multiple"> {Object.keys(TemplateListGenerated).map((key, idx) => (
{Object.keys(TemplateListGenerated).map((key, idx) => ( <Select.Option
<Select.Option key={idx}
key={idx} value={TemplateListGenerated[key].key}
value={TemplateListGenerated[key].key} >
> {TemplateListGenerated[key].title}
{TemplateListGenerated[key].title} </Select.Option>
</Select.Option> ))}
))} </Select>
</Select> </Form.Item>
</Form.Item>
<Space wrap>
<DeleteFilled <DeleteFilled
className="imex-flex-row__margin"
onClick={() => { onClick={() => {
remove(field.name); remove(field.name);
}} }}
@@ -83,24 +78,24 @@ export default function ShopInfoSpeedPrint({ bodyshop, form }) {
index={index} index={index}
total={fields.length} total={fields.length}
/> />
</LayoutFormRow> </Space>
</Form.Item> </LayoutFormRow>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addspeedprint")}
</Button>
</Form.Item> </Form.Item>
</div> ))}
); <Form.Item>
}} <Button
</Form.List> type="dashed"
</div> onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addspeedprint")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
); );
} }

View File

@@ -1,6 +1,6 @@
import { PrinterFilled } from "@ant-design/icons"; import { PrinterFilled } from "@ant-design/icons";
import { useQuery } from "@apollo/client"; import { useQuery } from "@apollo/client";
import { Button, Divider, Drawer, Grid, PageHeader, Tabs, Tag } from "antd"; import { Button, Divider, Drawer, Grid, PageHeader, Tabs } from "antd";
import queryString from "query-string"; import queryString from "query-string";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -14,8 +14,6 @@ import JobsDetailHeader from "../jobs-detail-header/jobs-detail-header.component
import JobsDocumentsGalleryContainer from "../jobs-documents-gallery/jobs-documents-gallery.container"; import JobsDocumentsGalleryContainer from "../jobs-documents-gallery/jobs-documents-gallery.container";
import JobNotesContainer from "../jobs-notes/jobs-notes.container"; import JobNotesContainer from "../jobs-notes/jobs-notes.container";
import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import OwnerTagPopoverComponent from "../owner-tag-popover/owner-tag-popover.component";
import VehicleTagPopoverComponent from "../vehicle-tag-popover/vehicle-tag-popover.component";
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setPrintCenterContext: (context) => setPrintCenterContext: (context) =>

View File

@@ -2,7 +2,6 @@ import { Card, Space, Table } from "antd";
import moment from "moment"; import moment from "moment";
import React, { useMemo, useState } from "react"; import React, { useMemo, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { onlyUnique } from "../../utils/arrayHelper"; import { onlyUnique } from "../../utils/arrayHelper";
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter"; import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters"; import { alphaSort } from "../../utils/sorters";

View File

@@ -172,7 +172,7 @@
"bodyshop": { "bodyshop": {
"actions": { "actions": {
"addapptcolor": "Add Appointment Color", "addapptcolor": "Add Appointment Color",
"addbucket": "Add Bucket", "addbucket": "Add Definition",
"addpartslocation": "Add Parts Location", "addpartslocation": "Add Parts Location",
"addspeedprint": "Add Speed Print", "addspeedprint": "Add Speed Print",
"addtemplate": "Add Template", "addtemplate": "Add Template",
@@ -412,10 +412,12 @@
"2tiername": "Name => RO", "2tiername": "Name => RO",
"2tiersetup": "2 Tier Setup", "2tiersetup": "2 Tier Setup",
"2tiersource": "Source => RO", "2tiersource": "Source => RO",
"accountingsetup": "Accounting Setup",
"accountingtiers": "Number of Tiers to Use for Export", "accountingtiers": "Number of Tiers to Use for Export",
"alljobstatuses": "All Job Statuses", "alljobstatuses": "All Job Statuses",
"allopenjobstatuses": "All Open Job Statuses", "allopenjobstatuses": "All Open Job Statuses",
"apptcolors": "Appointment Colors", "apptcolors": "Appointment Colors",
"businessinformation": "Business Information",
"checklists": "Checklists", "checklists": "Checklists",
"csiq": "CSI Questions", "csiq": "CSI Questions",
"customtemplates": "Custom Templates", "customtemplates": "Custom Templates",
@@ -423,12 +425,16 @@
"defaultprofitsmapping": "Default Profits Mapping", "defaultprofitsmapping": "Default Profits Mapping",
"deliverchecklist": "Delivery Checklist", "deliverchecklist": "Delivery Checklist",
"employees": "Employees", "employees": "Employees",
"insurancecos": "Insurance Companies",
"intakechecklist": "Intake Checklist", "intakechecklist": "Intake Checklist",
"jobstatuses": "Job Statuses", "jobstatuses": "Job Statuses",
"laborrates": "Labor Rates", "laborrates": "Labor Rates",
"licensing": "Licensing", "licensing": "Licensing",
"messagingpresets": "Messaging Presets",
"notemplatesavailable": "No templates available to add.", "notemplatesavailable": "No templates available to add.",
"notespresets": "Notes Presets",
"orderstatuses": "Order Statuses", "orderstatuses": "Order Statuses",
"partslocations": "Parts Locations",
"rbac": "Role Based Access Control", "rbac": "Role Based Access Control",
"responsibilitycenters": { "responsibilitycenters": {
"costs": "Cost Centers", "costs": "Cost Centers",
@@ -438,8 +444,11 @@
"title": "Responsibility Centers" "title": "Responsibility Centers"
}, },
"scheduling": "SMART Scheduling", "scheduling": "SMART Scheduling",
"scoreboardsetup": "Scoreboard Setup",
"shopinfo": "Shop Information", "shopinfo": "Shop Information",
"speedprint": "Speed Print Configuration", "speedprint": "Speed Print Configuration",
"ssbuckets": "Job Size Definitions",
"systemsettings": "System Settings",
"workingdays": "Working Days" "workingdays": "Working Days"
}, },
"successes": { "successes": {

View File

@@ -412,10 +412,12 @@
"2tiername": "", "2tiername": "",
"2tiersetup": "", "2tiersetup": "",
"2tiersource": "", "2tiersource": "",
"accountingsetup": "",
"accountingtiers": "", "accountingtiers": "",
"alljobstatuses": "", "alljobstatuses": "",
"allopenjobstatuses": "", "allopenjobstatuses": "",
"apptcolors": "", "apptcolors": "",
"businessinformation": "",
"checklists": "", "checklists": "",
"csiq": "", "csiq": "",
"customtemplates": "", "customtemplates": "",
@@ -423,12 +425,16 @@
"defaultprofitsmapping": "", "defaultprofitsmapping": "",
"deliverchecklist": "", "deliverchecklist": "",
"employees": "", "employees": "",
"insurancecos": "",
"intakechecklist": "", "intakechecklist": "",
"jobstatuses": "", "jobstatuses": "",
"laborrates": "", "laborrates": "",
"licensing": "", "licensing": "",
"messagingpresets": "",
"notemplatesavailable": "", "notemplatesavailable": "",
"notespresets": "",
"orderstatuses": "", "orderstatuses": "",
"partslocations": "",
"rbac": "", "rbac": "",
"responsibilitycenters": { "responsibilitycenters": {
"costs": "", "costs": "",
@@ -438,8 +444,11 @@
"title": "" "title": ""
}, },
"scheduling": "", "scheduling": "",
"scoreboardsetup": "",
"shopinfo": "", "shopinfo": "",
"speedprint": "", "speedprint": "",
"ssbuckets": "",
"systemsettings": "",
"workingdays": "" "workingdays": ""
}, },
"successes": { "successes": {

View File

@@ -412,10 +412,12 @@
"2tiername": "", "2tiername": "",
"2tiersetup": "", "2tiersetup": "",
"2tiersource": "", "2tiersource": "",
"accountingsetup": "",
"accountingtiers": "", "accountingtiers": "",
"alljobstatuses": "", "alljobstatuses": "",
"allopenjobstatuses": "", "allopenjobstatuses": "",
"apptcolors": "", "apptcolors": "",
"businessinformation": "",
"checklists": "", "checklists": "",
"csiq": "", "csiq": "",
"customtemplates": "", "customtemplates": "",
@@ -423,12 +425,16 @@
"defaultprofitsmapping": "", "defaultprofitsmapping": "",
"deliverchecklist": "", "deliverchecklist": "",
"employees": "", "employees": "",
"insurancecos": "",
"intakechecklist": "", "intakechecklist": "",
"jobstatuses": "", "jobstatuses": "",
"laborrates": "", "laborrates": "",
"licensing": "", "licensing": "",
"messagingpresets": "",
"notemplatesavailable": "", "notemplatesavailable": "",
"notespresets": "",
"orderstatuses": "", "orderstatuses": "",
"partslocations": "",
"rbac": "", "rbac": "",
"responsibilitycenters": { "responsibilitycenters": {
"costs": "", "costs": "",
@@ -438,8 +444,11 @@
"title": "" "title": ""
}, },
"scheduling": "", "scheduling": "",
"scoreboardsetup": "",
"shopinfo": "", "shopinfo": "",
"speedprint": "", "speedprint": "",
"ssbuckets": "",
"systemsettings": "",
"workingdays": "" "workingdays": ""
}, },
"successes": { "successes": {