Most functionality is restored after antd upgrade. WIP on invoice enter screen.

This commit is contained in:
Patrick Fic
2020-02-28 17:56:36 -08:00
parent 6e0d9da257
commit 8c54de9a9f
10 changed files with 128 additions and 122 deletions

View File

@@ -23,7 +23,6 @@ export default connect(
const { t } = useTranslation();
const onChange = e => {
console.log("e", e);
setAssignment({ ...assignment, employeeid: e });
};

View File

@@ -1,4 +1,4 @@
import { Button, Modal, notification } from "antd";
import { Modal, notification } from "antd";
import axios from "axios";
import React, { useEffect, useState } from "react";
import { useLazyQuery } from "react-apollo";
@@ -7,10 +7,7 @@ import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { toggleEmailOverlayVisible } from "../../redux/email/email.actions";
import {
selectEmailConfig,
selectEmailVisible
} from "../../redux/email/email.selectors.js";
import { selectEmailConfig, selectEmailVisible } from "../../redux/email/email.selectors.js";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import EmailOverlayComponent from "./email-overlay.component";
@@ -89,24 +86,20 @@ export default connect(
};
return (
<div>
<Modal
destroyOnClose={true}
visible={modalVisible}
width={"80%"}
onOk={handleOk}
onCancel={() => toggleEmailOverlayVisible()}
>
<LoadingSpinner loading={loading}>
<EmailOverlayComponent
handleConfigChange={handleConfigChange}
messageOptions={messageOptions}
handleHtmlChange={handleHtmlChange}
/>
</LoadingSpinner>
</Modal>
<Button onClick={() => toggleEmailOverlayVisible()}>Show</Button>
</div>
<Modal
destroyOnClose={true}
visible={modalVisible}
width={"80%"}
onOk={handleOk}
onCancel={() => toggleEmailOverlayVisible()}
>
<LoadingSpinner loading={loading}>
<EmailOverlayComponent
handleConfigChange={handleConfigChange}
messageOptions={messageOptions}
handleHtmlChange={handleHtmlChange}
/>
</LoadingSpinner>
</Modal>
);
});

View File

@@ -0,0 +1,15 @@
import { InputNumber } from "antd";
import React, { forwardRef } from "react";
function FormItemCurrency(props, ref) {
return (
<InputNumber
{...props}
formatter={value => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
parser={value => value.replace(/\$\s?|(,*)/g, "")}
precision={2}
/>
);
}
export default forwardRef(FormItemCurrency);

View File

@@ -1,5 +1,5 @@
import {
AutoComplete,
Select,
Button,
DatePicker,
Form,
@@ -20,10 +20,9 @@ export default function InvoiceEnterModalComponent({
handleCancel,
handleFinish,
handleRoAutoComplete,
handleRoSelect,
roAutoCompleteOptions,
handleVendorAutoComplete,
handleVendorSelect,
vendorAutoCompleteOptions,
lineData,
@@ -48,7 +47,7 @@ export default function InvoiceEnterModalComponent({
width={"90%"}
visible={visible}
okText={t("general.labels.save")}
onOk={handleFinish}
onOk={() => form.submit()}
okButtonProps={{ htmlType: "submit" }}
onCancel={handleCancel}
>
@@ -59,21 +58,31 @@ export default function InvoiceEnterModalComponent({
rules={[
{
required: true,
pattern: new RegExp(
"[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"
),
message: t("invoices.errors.invalidro")
message: t("general.validation.required")
}
]}
>
<AutoComplete
options={roAutoCompleteOptions}
onSearch={handleRoAutoComplete}
<Select
showSearch
autoFocus
style={{ width: "300px" }}
onSelect={handleRoSelect}
backfill
/>
>
{roAutoCompleteOptions
? roAutoCompleteOptions.map(o => (
<Select.Option
key={o.id}
value={o.ro_number ? o.ro_number : o.est_number}
>
{`${
o.ro_number ? o.ro_number : o.est_number
} | ${o.ownr_ln || ""} ${o.ownr_fn || ""} | ${o.vehicle
.v_model_yr || ""} ${o.vehicle.v_make_desc || ""} ${o
.vehicle.v_model_desc || ""}`}
</Select.Option>
))
: null}
</Select>
</Form.Item>
<Form.Item
label={t("invoices.fields.vendor")}
@@ -81,20 +90,23 @@ export default function InvoiceEnterModalComponent({
rules={[
{
required: true,
pattern: new RegExp(
"[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"
),
message: t("invoices.errors.invalidvendor")
message: t("general.validation.required")
}
]}
>
<AutoComplete
options={vendorAutoCompleteOptions}
<Select
showSearch
onSelect={handleVendorSelect}
style={{ width: "300px" }}
onSearch={handleVendorAutoComplete}
backfill
/>
>
{vendorAutoCompleteOptions
? vendorAutoCompleteOptions.map(o => (
<Select.Option key={o.id} value={o.name}>
{o.name}
</Select.Option>
))
: null}
</Select>
</Form.Item>
<Button onClick={() => resetFields()}>
{t("general.actions.reset")}

View File

@@ -3,7 +3,7 @@ import { useLazyQuery, useQuery } from "react-apollo";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { GET_JOB_LINES_TO_ENTER_INVOICE } from "../../graphql/jobs-lines.queries";
import { SEARCH_RO_AUTOCOMPLETE } from "../../graphql/jobs.queries";
import { ACTIVE_JOBS_FOR_AUTOCOMPLETE } from "../../graphql/jobs.queries";
import { SEARCH_VENDOR_AUTOCOMPLETE } from "../../graphql/vendors.queries";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectInvoiceEnterModal } from "../../redux/modals/modals.selectors";
@@ -27,13 +27,11 @@ function InvoiceEnterModalContainer({
const linesState = useState([]);
const roSearchState = useState({ text: "", selectedId: null });
const [roSearch, setRoSearch] = roSearchState;
const handleRoAutoComplete = e => {
setRoSearch({ ...roSearch, text: e });
};
const { data: RoAutoCompleteData } = useQuery(SEARCH_RO_AUTOCOMPLETE, {
const { data: RoAutoCompleteData } = useQuery(ACTIVE_JOBS_FOR_AUTOCOMPLETE, {
fetchPolicy: "network-only",
variables: { search: `%${roSearch.text}%` },
skip: !roSearch.text || roSearch.text.length < 3
variables: { statuses: bodyshop.md_ro_statuses.open_statuses || ["Open"] },
skip: !invoiceEnterModal.visible
});
const vendorSearchState = useState({
@@ -41,15 +39,11 @@ function InvoiceEnterModalContainer({
selectedId: null
});
const [vendorSearch, setVendorSearch] = vendorSearchState;
const handleVendorAutoComplete = e => {
setVendorSearch({ ...vendorSearch, text: e });
};
const { data: VendorAutoCompleteData } = useQuery(
SEARCH_VENDOR_AUTOCOMPLETE,
{
fetchPolicy: "network-only",
variables: { search: `%${vendorSearch.text}%` },
skip: !vendorSearch.text || vendorSearch.text.length < 3
skip: !invoiceEnterModal.visible
}
);
@@ -65,14 +59,15 @@ function InvoiceEnterModalContainer({
if (!called) loadLines();
}
const handleRoSelect = (value, obj) => {
setRoSearch({ ...roSearch, selectedId: obj.id });
setRoSearch({ ...roSearch, selectedId: obj.key });
};
const handleVendorSelect = (value, obj) => {
setVendorSearch({ ...vendorSearch, selectedId: obj.id });
setVendorSearch({ ...vendorSearch, selectedId: obj.key });
};
const handleFinish = values => {
console.log("values", values);
alert("Closing this modal.");
toggleModalVisible();
// if (!jobLineEditModal.context.id) {
@@ -131,34 +126,11 @@ function InvoiceEnterModalContainer({
invoice={invoiceEnterModal.context}
handleFinish={handleFinish}
handleCancel={handleCancel}
handleRoAutoComplete={handleRoAutoComplete}
handleRoSelect={handleRoSelect}
roAutoCompleteOptions={
RoAutoCompleteData
? RoAutoCompleteData.jobs.reduce((acc, value) => {
acc.push({
id: value.id,
value: `${value.ro_number || ""} | ${value.ownr_ln ||
""} ${value.ownr_fn || ""} | ${value.vehicle.v_model_yr ||
""} ${value.vehicle.v_make_desc || ""} ${value.vehicle
.v_model_desc || ""}`
});
return acc;
}, [])
: null
}
handleVendorAutoComplete={handleVendorAutoComplete}
roAutoCompleteOptions={RoAutoCompleteData && RoAutoCompleteData.jobs}
handleVendorSelect={handleVendorSelect}
vendorAutoCompleteOptions={
VendorAutoCompleteData
? VendorAutoCompleteData.vendors.reduce((acc, value) => {
acc.push({
id: value.id,
value: `${value.name || ""}`
});
return acc;
}, [])
: null
VendorAutoCompleteData && VendorAutoCompleteData.vendors
}
linesState={linesState}
lineData={lineData ? lineData.joblines : null}

View File

@@ -1,6 +1,7 @@
import { Form, Input, InputNumber, Modal } from "antd";
import { Form, Input, Modal } from "antd";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import InputCurrency from "../form-items-formatted/currency-form-item.component";
export default function JobLinesUpsertModalComponent({
visible,
@@ -14,27 +15,35 @@ export default function JobLinesUpsertModalComponent({
useEffect(() => {
form.resetFields();
}, [visible, form]);
console.log("jobLine", jobLine);
return (
<Modal
title={
jobLine && jobLine.id
? t("joblines.labels.edit")
: t("joblines.labels.new")
}
visible={visible}
okText={t("general.labels.save")}
onOk={handleFinish}
forceRender={true}
onCancel={handleCancel}
<Form
onFinish={handleFinish}
initialValues={jobLine}
autoComplete="off"
form={form}
>
<Form
onFinish={handleFinish}
initialValues={jobLine}
autoComplete={"off"}
form={form}
<Modal
title={
jobLine && jobLine.id
? t("joblines.labels.edit")
: t("joblines.labels.new")
}
visible={visible}
okText={t("general.labels.save")}
onOk={() => form.submit()}
onCancel={handleCancel}
>
<Form.Item label={t("joblines.fields.line_desc")} name="line_desc">
<Form.Item
label={t("joblines.fields.line_desc")}
rules={[
{
required: true,
message: t("general.validation.required")
}
]}
name="line_desc"
>
<Input />
</Form.Item>
<Form.Item label={t("joblines.fields.oem_partno")} name="oem_partno">
@@ -53,12 +62,12 @@ export default function JobLinesUpsertModalComponent({
<Input />
</Form.Item>
<Form.Item label={t("joblines.fields.mod_lb_hrs")} name="mod_lb_hrs">
<InputNumber />
<InputCurrency />
</Form.Item>
<Form.Item label={t("joblines.fields.act_price")} name="act_price">
<InputNumber />
<InputCurrency />
</Form.Item>
</Form>
</Modal>
</Modal>
</Form>
);
}

View File

@@ -335,13 +335,14 @@ export const UPDATE_JOB_STATUS = gql`
}
`;
export const SEARCH_RO_AUTOCOMPLETE = gql`
query SEARCH_RO_AUTOCOMPLETE($search: String!) {
jobs(where: { ro_number: { _ilike: $search } }) {
export const ACTIVE_JOBS_FOR_AUTOCOMPLETE = gql`
query ACTIVE_JOBS_FOR_AUTOCOMPLETE($statuses: [String!]!) {
jobs(where: { status: { _in: $statuses } }) {
id
ownr_fn
ownr_ln
ro_number
est_number
vehicle {
id
v_make_desc

View File

@@ -78,8 +78,8 @@ export const QUERY_ALL_VENDORS_FOR_ORDER = gql`
`;
export const SEARCH_VENDOR_AUTOCOMPLETE = gql`
query SEARCH_VENDOR_AUTOCOMPLETE($search: String!) {
vendors(where: { name: { _ilike: $search } }) {
query SEARCH_VENDOR_AUTOCOMPLETE {
vendors {
name
discount
id

View File

@@ -1,9 +1,20 @@
import Icon, { BarsOutlined, CalendarFilled, DollarCircleOutlined, FileImageFilled, ToolFilled } from "@ant-design/icons";
import Icon, {
BarsOutlined,
CalendarFilled,
DollarCircleOutlined,
FileImageFilled,
ToolFilled
} from "@ant-design/icons";
import { Form, notification, Tabs } from "antd";
import moment from "moment";
import React, { lazy, Suspense } from "react";
import { useTranslation } from "react-i18next";
import { FaHardHat, FaInfo, FaRegStickyNote, FaShieldAlt } from "react-icons/fa";
import {
FaHardHat,
FaInfo,
FaRegStickyNote,
FaShieldAlt
} from "react-icons/fa";
//import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container";
//import JobsDetailClaims from "../../components/jobs-detail-claims/jobs-detail-claims.component";
//import JobsDetailDatesComponent from "../../components/jobs-detail-dates/jobs-detail-dates.component";
@@ -143,9 +154,6 @@ export default function JobsDetailPage({
date_exported: job.date_exported ? moment(job.date_exported) : null
}}
>
<Form.Item name="updated_at">
<input />
</Form.Item>
<JobsDetailHeader
job={job}
mutationConvertJob={mutationConvertJob}

View File

@@ -8,7 +8,6 @@ import FooterComponent from "../../components/footer/footer.component";
import HeaderContainer from "../../components/header/header.container";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
import "./manage.page.styles.scss";
import Test from "../../components/_test/test.component";
const ManageRootPage = lazy(() =>
import("../manage-root/manage-root.page.container")
@@ -74,8 +73,6 @@ export default function Manage({ match }) {
<LoadingSpinner message={t("general.labels.loadingapp")} />
}
>
DELETE THIS
<Test />
<EmailOverlayContainer />
<Route exact path={`${match.path}`} component={ManageRootPage} />
<Route exact path={`${match.path}/jobs`} component={JobsPage} />