Added some additional save indiactors BOD-134
This commit is contained in:
@@ -3,10 +3,7 @@ import { Select } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
const { Option } = Select;
|
||||
|
||||
const ContractStatusComponent = (
|
||||
{ value = "contracts.status.new", onChange },
|
||||
ref
|
||||
) => {
|
||||
const ContractStatusComponent = ({ value, onChange }, ref) => {
|
||||
const [option, setOption] = useState(value);
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
||||
@@ -3,15 +3,15 @@ import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel-select.component";
|
||||
import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.component";
|
||||
import FormDatePicker from '../form-date-picker/form-date-picker.component';
|
||||
import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
||||
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
|
||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||
|
||||
export default function CourtesyCarCreateFormComponent({ form }) {
|
||||
export default function CourtesyCarCreateFormComponent({ form, saveLoading }) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div>
|
||||
<Button type="primary" htmlType="submit">
|
||||
<Button type="primary" loading={saveLoading} htmlType="submit">
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
<div className="imex-flex-row__grow imex-flex-row__margin-large">
|
||||
|
||||
@@ -41,7 +41,7 @@ export function JobsDetailHeaderActions({
|
||||
const client = useApolloClient();
|
||||
const history = useHistory();
|
||||
const statusmenu = (
|
||||
<Menu key='popovermenu'>
|
||||
<Menu key="popovermenu">
|
||||
<Menu.Item
|
||||
onClick={() => {
|
||||
logImEXEvent("job_header_schedule");
|
||||
@@ -53,16 +53,21 @@ export function JobsDetailHeaderActions({
|
||||
job: job,
|
||||
},
|
||||
});
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{t("jobs.actions.schedule")}
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<Link to={`/manage/jobs/${job.id}/intake`}>
|
||||
{t("jobs.actions.intake")}
|
||||
</Link>
|
||||
<Menu.Item disabled={!!job.intakechecklist}>
|
||||
{!!job.intakechecklist ? (
|
||||
t("jobs.actions.intake")
|
||||
) : (
|
||||
<Link to={`/manage/jobs/${job.id}/intake`}>
|
||||
{t("jobs.actions.intake")}
|
||||
</Link>
|
||||
)}
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
key='enterpayments'
|
||||
key="enterpayments"
|
||||
onClick={() => {
|
||||
logImEXEvent("job_header_enter_payment");
|
||||
|
||||
@@ -70,29 +75,32 @@ export function JobsDetailHeaderActions({
|
||||
actions: {},
|
||||
context: { jobId: job.id },
|
||||
});
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{t("menus.header.enterpayment")}
|
||||
</Menu.Item>
|
||||
<Menu.Item key='cccontract'>
|
||||
<Menu.Item key="cccontract">
|
||||
<Link
|
||||
to={{
|
||||
pathname: "/manage/courtesycars/contracts/new",
|
||||
state: { jobId: job.id },
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{t("menus.jobsactions.newcccontract")}
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
key='addtoproduction'
|
||||
key="addtoproduction"
|
||||
disabled={!!!job.converted || !!job.inproduction}
|
||||
onClick={() => AddToProduction(client, job.id, refetch)}>
|
||||
onClick={() => AddToProduction(client, job.id, refetch)}
|
||||
>
|
||||
{t("jobs.actions.addtoproduction")}
|
||||
</Menu.Item>
|
||||
<Menu.Item key='duplicatejob'>
|
||||
<Menu.Item key="duplicatejob">
|
||||
<Popconfirm
|
||||
title={t("jobs.labels.duplicateconfirm")}
|
||||
okText='Yes'
|
||||
cancelText='No'
|
||||
okText="Yes"
|
||||
cancelText="No"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onConfirm={() =>
|
||||
DuplicateJob(
|
||||
@@ -104,12 +112,13 @@ export function JobsDetailHeaderActions({
|
||||
}
|
||||
)
|
||||
}
|
||||
getPopupContainer={(trigger) => trigger.parentNode}>
|
||||
getPopupContainer={(trigger) => trigger.parentNode}
|
||||
>
|
||||
{t("menus.jobsactions.duplicate")}
|
||||
</Popconfirm>
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
key='postinvoices'
|
||||
key="postinvoices"
|
||||
onClick={() => {
|
||||
logImEXEvent("job_header_enter_invoice");
|
||||
|
||||
@@ -119,20 +128,22 @@ export function JobsDetailHeaderActions({
|
||||
job: job,
|
||||
},
|
||||
});
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{t("jobs.actions.postInvoices")}
|
||||
</Menu.Item>
|
||||
<Menu.Item key='closejob'>
|
||||
<Menu.Item key="closejob">
|
||||
<Link
|
||||
to={{
|
||||
pathname: `/manage/jobs/${job.id}/close`,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{t("menus.jobsactions.closejob")}
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
<JobsDetaiLheaderCsi job={job} />
|
||||
<Menu.Item
|
||||
key='jobcosting'
|
||||
key="jobcosting"
|
||||
onClick={() => {
|
||||
logImEXEvent("job_header_job_costing");
|
||||
|
||||
@@ -142,17 +153,19 @@ export function JobsDetailHeaderActions({
|
||||
jobId: job.id,
|
||||
},
|
||||
});
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{t("jobs.labels.jobcosting")}
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<Dropdown
|
||||
className='imex-flex-row__margin'
|
||||
className="imex-flex-row__margin"
|
||||
overlay={statusmenu}
|
||||
trigger={["click"]}
|
||||
key='changestatus'>
|
||||
key="changestatus"
|
||||
>
|
||||
<Button>
|
||||
{t("general.labels.actions")} <DownCircleFilled />
|
||||
</Button>
|
||||
|
||||
@@ -6,35 +6,37 @@ import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||
import FormItemPhone from "../form-items-formatted/phone-form-item.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
|
||||
export default function OwnerDetailFormComponent({ form }) {
|
||||
export default function OwnerDetailFormComponent({ form, loading }) {
|
||||
const { t } = useTranslation();
|
||||
const { getFieldValue } = form;
|
||||
return (
|
||||
<div>
|
||||
<div className='imex-flex-row imex-flex-row__flex-space-around'>
|
||||
<div className="imex-flex-row imex-flex-row__flex-space-around">
|
||||
<Button
|
||||
className='imex-flex-row__margin-large'
|
||||
type='primary'
|
||||
key='submit'
|
||||
htmlType='submit'>
|
||||
className="imex-flex-row__margin-large"
|
||||
type="primary"
|
||||
key="submit"
|
||||
loading={loading}
|
||||
htmlType="submit"
|
||||
>
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
<div className='imex-flex-row__grow imex-flex-row__margin-large'>
|
||||
<div className="imex-flex-row__grow imex-flex-row__margin-large">
|
||||
<FormFieldsChanged form={form} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LayoutFormRow header={t("owners.forms.name")}>
|
||||
<Form.Item label={t("owners.fields.ownr_title")} name='ownr_title'>
|
||||
<Form.Item label={t("owners.fields.ownr_title")} name="ownr_title">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_ln")} name='ownr_ln'>
|
||||
<Form.Item label={t("owners.fields.ownr_ln")} name="ownr_ln">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_fn")} name='ownr_fn'>
|
||||
<Form.Item label={t("owners.fields.ownr_fn")} name="ownr_fn">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_co_nm")} name='ownr_co_nm'>
|
||||
<Form.Item label={t("owners.fields.ownr_co_nm")} name="ownr_co_nm">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
@@ -42,52 +44,56 @@ export default function OwnerDetailFormComponent({ form }) {
|
||||
<LayoutFormRow header={t("owners.forms.address")}>
|
||||
<Form.Item
|
||||
label={t("owners.fields.ownr_addr1")}
|
||||
name='ownr_addr1'
|
||||
name="ownr_addr1"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("general.validation.required"),
|
||||
},
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_addr2")} name='ownr_addr2'>
|
||||
<Form.Item label={t("owners.fields.ownr_addr2")} name="ownr_addr2">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("owners.fields.ownr_city")}
|
||||
name='ownr_city'
|
||||
name="ownr_city"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("general.validation.required"),
|
||||
},
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("owners.fields.ownr_st")}
|
||||
name='ownr_st'
|
||||
name="ownr_st"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("general.validation.required"),
|
||||
},
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("owners.fields.ownr_zip")}
|
||||
name='ownr_zip'
|
||||
name="ownr_zip"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("general.validation.required"),
|
||||
},
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_ctry")} name='ownr_ctry'>
|
||||
<Form.Item label={t("owners.fields.ownr_ctry")} name="ownr_ctry">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
@@ -95,27 +101,30 @@ export default function OwnerDetailFormComponent({ form }) {
|
||||
<LayoutFormRow header={t("owners.forms.contact")}>
|
||||
<Form.Item
|
||||
label={t("owners.fields.allow_text_message")}
|
||||
name='allow_text_message'
|
||||
valuePropName='checked'>
|
||||
name="allow_text_message"
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("owners.fields.ownr_ea")}
|
||||
name='ownr_ea'
|
||||
name="ownr_ea"
|
||||
rules={[
|
||||
{
|
||||
type: "email",
|
||||
message: "This is not a valid email address.",
|
||||
},
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<FormItemEmail email={getFieldValue("ownr_ea")} />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_ph1")} name='ownr_ph1'>
|
||||
<Form.Item label={t("owners.fields.ownr_ph1")} name="ownr_ph1">
|
||||
<FormItemPhone customInput={Input} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("owners.fields.preferred_contact")}
|
||||
name='preferred_contact'>
|
||||
name="preferred_contact"
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Form, notification } from "antd";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useMutation } from "@apollo/react-hooks";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UPDATE_OWNER } from "../../graphql/owners.queries";
|
||||
@@ -8,10 +8,11 @@ import OwnerDetailFormComponent from "./owner-detail-form.component";
|
||||
function OwnerDetailFormContainer({ owner, refetch }) {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [updateOwner] = useMutation(UPDATE_OWNER);
|
||||
|
||||
const handleFinish = async (values) => {
|
||||
setLoading(true);
|
||||
const result = await updateOwner({
|
||||
variables: { ownerId: owner.id, owner: values },
|
||||
});
|
||||
@@ -32,6 +33,7 @@ function OwnerDetailFormContainer({ owner, refetch }) {
|
||||
if (refetch) await refetch();
|
||||
form.resetFields();
|
||||
form.resetFields();
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -42,7 +44,7 @@ function OwnerDetailFormContainer({ owner, refetch }) {
|
||||
layout="vertical"
|
||||
initialValues={owner}
|
||||
>
|
||||
<OwnerDetailFormComponent form={form} />
|
||||
<OwnerDetailFormComponent loading={loading} form={form} />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
||||
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
|
||||
export default function VehicleDetailFormComponent({ form }) {
|
||||
export default function VehicleDetailFormComponent({ form, loading }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@@ -16,6 +16,7 @@ export default function VehicleDetailFormComponent({ form }) {
|
||||
type="primary"
|
||||
key="submit"
|
||||
htmlType="submit"
|
||||
loading={loading}
|
||||
>
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { Form, notification } from "antd";
|
||||
import { useMutation } from "@apollo/react-hooks";
|
||||
import VehicleDetailFormComponent from "./vehicle-detail-form.component";
|
||||
@@ -10,8 +10,10 @@ function VehicleDetailFormContainer({ vehicle, refetch }) {
|
||||
const { t } = useTranslation();
|
||||
const [updateVehicle] = useMutation(UPDATE_VEHICLE);
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleFinish = async (values) => {
|
||||
setLoading(true);
|
||||
const result = await updateVehicle({
|
||||
variables: { vehId: vehicle.id, vehicle: values },
|
||||
});
|
||||
@@ -31,6 +33,7 @@ function VehicleDetailFormContainer({ vehicle, refetch }) {
|
||||
if (refetch) await refetch();
|
||||
form.resetFields();
|
||||
form.resetFields();
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -44,7 +47,7 @@ function VehicleDetailFormContainer({ vehicle, refetch }) {
|
||||
v_prod_dt: vehicle.v_prod_dt ? moment(vehicle.v_prod_dt) : null,
|
||||
}}
|
||||
>
|
||||
<VehicleDetailFormComponent form={form} />
|
||||
<VehicleDetailFormComponent form={form} loading={loading} />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ export const GET_JOB_BY_PK = gql`
|
||||
first_name
|
||||
last_name
|
||||
}
|
||||
intakechecklist
|
||||
csr
|
||||
loss_desc
|
||||
kmin
|
||||
|
||||
@@ -9,11 +9,14 @@ export default function ContractCreatePageComponent({
|
||||
form,
|
||||
selectedJobState,
|
||||
selectedCarState,
|
||||
loading,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div>
|
||||
<Button htmlType="submit">{t("general.actions.create")}</Button>
|
||||
<Button type="primary" onClick={() => form.submit()} loading={loading}>
|
||||
{t("general.actions.create")}
|
||||
</Button>
|
||||
<ContractJobsContainer selectedJobState={selectedJobState} />
|
||||
<ContractCarsContainer selectedCarState={selectedCarState} />
|
||||
<ContractLicenseDecodeButton form={form} />
|
||||
|
||||
@@ -23,6 +23,7 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs }) {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const selectedCarState = useState(null);
|
||||
const selectedJobState = useState(
|
||||
(location.state && location.state.jobId) || null
|
||||
@@ -31,6 +32,7 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs }) {
|
||||
|
||||
const handleFinish = (values) => {
|
||||
if (!!selectedCarState[0] && !!selectedJobState[0]) {
|
||||
setLoading(true);
|
||||
insertContract({
|
||||
variables: {
|
||||
contract: {
|
||||
@@ -61,6 +63,7 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs }) {
|
||||
message: t("contracts.errors.selectjobandcar"),
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -84,9 +87,11 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs }) {
|
||||
form={form}
|
||||
layout="vertical"
|
||||
autoComplete="no"
|
||||
initialValues={{ status: "contracts.status.new" }}
|
||||
onFinish={handleFinish}
|
||||
>
|
||||
<ContractCreatePageComponent
|
||||
loading={loading}
|
||||
form={form}
|
||||
selectedJobState={selectedJobState}
|
||||
selectedCarState={selectedCarState}
|
||||
|
||||
@@ -2,10 +2,14 @@ import React from "react";
|
||||
import CourtesyCarCreateFormComponent from "../../components/courtesy-car-form/courtesy-car-form.component";
|
||||
import CourtesyCarContractListComponent from "../../components/courtesy-car-contract-list/courtesy-car-contract-list.component";
|
||||
|
||||
export default function CourtesyCarDetailPageComponent({ contracts, form }) {
|
||||
export default function CourtesyCarDetailPageComponent({
|
||||
contracts,
|
||||
form,
|
||||
saveLoading,
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<CourtesyCarCreateFormComponent form={form} />
|
||||
<CourtesyCarCreateFormComponent form={form} saveLoading={saveLoading} />
|
||||
<CourtesyCarContractListComponent contracts={contracts} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useMutation, useQuery } from "@apollo/react-hooks";
|
||||
import { Form, notification } from "antd";
|
||||
import moment from "moment";
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { useParams } from "react-router-dom";
|
||||
@@ -27,7 +27,7 @@ export function CourtesyCarDetailPageContainer({
|
||||
const [insertCourtesyCar] = useMutation(UPDATE_CC);
|
||||
const [form] = Form.useForm();
|
||||
const { ccId } = useParams();
|
||||
|
||||
const [saveLoading, setSaveLoading] = useState(false);
|
||||
const { loading, error, data } = useQuery(QUERY_CC_BY_PK, {
|
||||
variables: { id: ccId },
|
||||
});
|
||||
@@ -63,18 +63,24 @@ export function CourtesyCarDetailPageContainer({
|
||||
);
|
||||
}, [t, data, error, loading, setBreadcrumbs, ccId, addRecentItem]);
|
||||
|
||||
const handleFinish = (values) => {
|
||||
insertCourtesyCar({
|
||||
const handleFinish = async (values) => {
|
||||
setSaveLoading(true);
|
||||
|
||||
const result = await insertCourtesyCar({
|
||||
variables: { cc: { ...values }, ccId: ccId },
|
||||
})
|
||||
.then((response) => {
|
||||
notification["success"]({ message: t("courtesycars.successes.saved") });
|
||||
})
|
||||
.catch((error) =>
|
||||
notification["error"]({
|
||||
message: t("courtesycars.errors.saving", { error: error }),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
if (!!result.errors) {
|
||||
notification["error"]({
|
||||
message: t("courtesycars.errors.saving", { error: error }),
|
||||
});
|
||||
}
|
||||
|
||||
notification["success"]({
|
||||
message: t("courtesycars.successes.saved"),
|
||||
});
|
||||
|
||||
setSaveLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -120,6 +126,7 @@ export function CourtesyCarDetailPageContainer({
|
||||
<CourtesyCarDetailPageComponent
|
||||
contracts={data ? data.courtesycars_by_pk.cccontracts : []}
|
||||
form={form}
|
||||
saveLoading={saveLoading}
|
||||
/>
|
||||
</Form>
|
||||
</RbacWrapper>
|
||||
|
||||
@@ -8,9 +8,10 @@ export function DateFormatter(props) {
|
||||
<Moment format="MM/DD/YYYY ">{props.children}</Moment>
|
||||
) : null;
|
||||
}
|
||||
|
||||
export function DateTimeFormatter(props) {
|
||||
return props.children ? (
|
||||
<Moment format="MM/DD/YYYY @ HH:mm">{props.children}</Moment>
|
||||
<Moment format="MM/DD/YYYY hh:mm a">{props.children}</Moment>
|
||||
) : null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user