Further UI Updates.
This commit is contained in:
@@ -8238,6 +8238,48 @@
|
||||
<folder_node>
|
||||
<name>labels</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>agreement</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>availablecars</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>
|
||||
<folder_node>
|
||||
<name>convertform</name>
|
||||
<children>
|
||||
@@ -8306,6 +8348,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>driverinformation</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>noteconvertedfrom</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -8348,6 +8411,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>rates</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>vehicle</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function AuditTrailListComponent({ loading, data }) {
|
||||
{...formItemLayout}
|
||||
loading={loading}
|
||||
pagination={{ position: "top", defaultPageSize: 25 }}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={data}
|
||||
onChange={handleTableChange}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useMutation, useQuery } from "@apollo/client";
|
||||
import { Button, Form, Popconfirm } from "antd";
|
||||
import { Button, Form, PageHeader, Popconfirm } from "antd";
|
||||
import moment from "moment";
|
||||
import queryString from "query-string";
|
||||
import React, { useEffect, useState } from "react";
|
||||
@@ -112,27 +112,36 @@ export default function BillDetailEditcontainer() {
|
||||
|
||||
return (
|
||||
<LoadingSkeleton loading={loading}>
|
||||
<Popconfirm
|
||||
visible={visible}
|
||||
onConfirm={() => form.submit()}
|
||||
onCancel={() => setVisible(false)}
|
||||
okButtonProps={{ loading: updateLoading }}
|
||||
title={t("bills.labels.editadjwarning")}
|
||||
>
|
||||
<Button
|
||||
htmlType="submit"
|
||||
disabled={exported}
|
||||
onClick={handleSave}
|
||||
loading={updateLoading}
|
||||
type="primary"
|
||||
>
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<PageHeader
|
||||
title={
|
||||
data &&
|
||||
`${data.bills_by_pk.invoice_number} - ${data.bills_by_pk.vendor.name}`
|
||||
}
|
||||
extra={
|
||||
<Popconfirm
|
||||
visible={visible}
|
||||
onConfirm={() => form.submit()}
|
||||
onCancel={() => setVisible(false)}
|
||||
okButtonProps={{ loading: updateLoading }}
|
||||
title={t("bills.labels.editadjwarning")}
|
||||
>
|
||||
<Button
|
||||
htmlType="submit"
|
||||
disabled={exported}
|
||||
onClick={handleSave}
|
||||
loading={updateLoading}
|
||||
type="primary"
|
||||
>
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
}
|
||||
/>
|
||||
<Form
|
||||
form={form}
|
||||
onFinish={handleFinish}
|
||||
initialValues={transformData(data)}
|
||||
layout="vertical"
|
||||
>
|
||||
<BillFormContainer form={form} billEdit disabled={exported} />
|
||||
<JobDocumentsGallery
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Input, Table } from "antd";
|
||||
import { Card, Input, Table } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
@@ -97,32 +97,36 @@ export default function ContractsCarsComponent({
|
||||
);
|
||||
|
||||
return (
|
||||
<Table
|
||||
loading={loading}
|
||||
title={() => (
|
||||
<Card
|
||||
title={t("contracts.labels.availablecars")}
|
||||
extra={
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
value={state.search}
|
||||
onChange={(e) => setState({ ...state, search: e.target.value })}
|
||||
/>
|
||||
)}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
rowKey="id"
|
||||
dataSource={filteredData}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: handleSelect,
|
||||
type: "radio",
|
||||
selectedRowKeys: [selectedCar],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
handleSelect(record);
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={filteredData}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: handleSelect,
|
||||
type: "radio",
|
||||
selectedRowKeys: [selectedCar],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
handleSelect(record);
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,6 @@ export default function ContractCarsContainer({ selectedCarState, form }) {
|
||||
const handleSelect = (record) => {
|
||||
setSelectedCar(record.id);
|
||||
|
||||
console.log(
|
||||
"🚀 ~ file: contract-cars.container.jsx ~ line 19 ~ record",
|
||||
record
|
||||
);
|
||||
form.setFieldsValue({
|
||||
kmstart: record.mileage,
|
||||
dailyrate: record.dailycost,
|
||||
@@ -28,13 +24,11 @@ export default function ContractCarsContainer({ selectedCarState, form }) {
|
||||
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
return (
|
||||
<div>
|
||||
<ContractCarsComponent
|
||||
handleSelect={handleSelect}
|
||||
selectedCar={selectedCar}
|
||||
loading={loading}
|
||||
data={data ? data.courtesycars : []}
|
||||
/>
|
||||
</div>
|
||||
<ContractCarsComponent
|
||||
handleSelect={handleSelect}
|
||||
selectedCar={selectedCar}
|
||||
loading={loading}
|
||||
data={data ? data.courtesycars : []}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
import { Card } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Descriptions, Card } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import DataLabel from "../data-label/data-label.component";
|
||||
|
||||
export default function ContractCourtesyCarBlock({ courtesyCar }) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Link to={`/manage/courtesycars/${courtesyCar && courtesyCar.id}`}>
|
||||
<Card title={t("courtesycars.labels.courtesycar")}>
|
||||
<Descriptions column={1}>
|
||||
<Descriptions.Item label={t("courtesycars.fields.fleetnumber")}>
|
||||
<Card
|
||||
className="ant-card-grid-hoverable"
|
||||
style={{ height: "100%" }}
|
||||
title={t("courtesycars.labels.courtesycar")}
|
||||
>
|
||||
<div>
|
||||
<DataLabel label={t("courtesycars.fields.fleetnumber")}>
|
||||
{(courtesyCar && courtesyCar.fleetnumber) || ""}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t("courtesycars.fields.plate")}>
|
||||
</DataLabel>
|
||||
<DataLabel label={t("courtesycars.fields.plate")}>
|
||||
{(courtesyCar && courtesyCar.plate) || ""}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t("courtesycars.labels.vehicle")}>
|
||||
</DataLabel>
|
||||
<DataLabel label={t("courtesycars.labels.vehicle")}>
|
||||
{`${(courtesyCar && courtesyCar.year) || ""} ${
|
||||
(courtesyCar && courtesyCar.make) || ""
|
||||
} ${(courtesyCar && courtesyCar.model) || ""}`}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</DataLabel>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -12,6 +12,7 @@ import InputPhone, {
|
||||
} from "../form-items-formatted/phone-form-item.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
import ContractFormJobPrefill from "./contract-form-job-prefill.component";
|
||||
|
||||
export default function ContractFormComponent({
|
||||
form,
|
||||
create = false,
|
||||
@@ -83,10 +84,11 @@ export default function ContractFormComponent({
|
||||
</Form.Item>
|
||||
)}
|
||||
</LayoutFormRow>
|
||||
<LayoutFormRow grow>
|
||||
<LayoutFormRow>
|
||||
<Form.Item
|
||||
label={t("contracts.fields.fuelout")}
|
||||
name="fuelout"
|
||||
span={8}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
@@ -97,23 +99,29 @@ export default function ContractFormComponent({
|
||||
<CourtesyCarFuelSlider />
|
||||
</Form.Item>
|
||||
{create ? null : (
|
||||
<Form.Item label={t("contracts.fields.fuelin")} name="fuelin">
|
||||
<Form.Item
|
||||
label={t("contracts.fields.fuelin")}
|
||||
name="fuelin"
|
||||
span={8}
|
||||
>
|
||||
<CourtesyCarFuelSlider />
|
||||
</Form.Item>
|
||||
)}
|
||||
</LayoutFormRow>
|
||||
<Space wrap>
|
||||
{selectedJobState && (
|
||||
<div>
|
||||
<ContractFormJobPrefill
|
||||
jobId={selectedJobState && selectedJobState[0]}
|
||||
form={form}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<ContractLicenseDecodeButton form={form} />
|
||||
</Space>
|
||||
<LayoutFormRow>
|
||||
<div>
|
||||
<Space wrap>
|
||||
{selectedJobState && (
|
||||
<div>
|
||||
<ContractFormJobPrefill
|
||||
jobId={selectedJobState && selectedJobState[0]}
|
||||
form={form}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<ContractLicenseDecodeButton form={form} />
|
||||
</Space>
|
||||
</div>
|
||||
<LayoutFormRow header={t("contracts.labels.driverinformation")}>
|
||||
<Form.Item
|
||||
label={t("contracts.fields.driver_dlnumber")}
|
||||
name="driver_dlnumber"
|
||||
@@ -222,7 +230,7 @@ export default function ContractFormComponent({
|
||||
<FormDatePicker />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
<LayoutFormRow>
|
||||
<LayoutFormRow header={t("contracts.labels.rates")}>
|
||||
<Form.Item label={t("contracts.fields.dailyrate")} name="dailyrate">
|
||||
<InputNumber precision={2} />
|
||||
</Form.Item>
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
import { Card } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Descriptions, Card } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import DataLabel from "../data-label/data-label.component";
|
||||
|
||||
export default function ContractJobBlock({ job }) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Link to={`/manage/jobs/${job && job.id}`}>
|
||||
<Card title={t("jobs.labels.job")}>
|
||||
<Descriptions column={1}>
|
||||
<Descriptions.Item label={t("jobs.fields.ro_number")}>
|
||||
<Card
|
||||
className="ant-card-grid-hoverable"
|
||||
style={{ height: "100%" }}
|
||||
title={t("jobs.labels.job")}
|
||||
>
|
||||
<div>
|
||||
<DataLabel label={t("jobs.fields.ro_number")}>
|
||||
{(job && job.ro_number) || ""}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t("jobs.fields.vehicle")}>
|
||||
</DataLabel>
|
||||
<DataLabel label={t("jobs.fields.vehicle")}>
|
||||
{`${(job && job.v_model_yr) || ""} ${
|
||||
(job && job.v_make_desc) || ""
|
||||
} ${(job && job.v_model_desc) || ""}`}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t("jobs.fields.owner")}>
|
||||
</DataLabel>
|
||||
<DataLabel label={t("jobs.fields.owner")}>
|
||||
{`${(job && job.ownr_fn) || ""} ${(job && job.ownr_ln) || ""} ${
|
||||
(job && job.ownr_co_nm) || ""
|
||||
}`}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</DataLabel>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Input, Table } from "antd";
|
||||
import { Card, Input, Table } from "antd";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
@@ -162,44 +162,48 @@ export default function ContractsJobsComponent({
|
||||
const defaultCurrent = useMemo(() => {
|
||||
const page =
|
||||
Math.floor(
|
||||
(filteredData.findIndex((v) => v.id === selectedJob) || 0) / 3
|
||||
(filteredData.findIndex((v) => v.id === selectedJob) || 0) / 10
|
||||
) + 1;
|
||||
|
||||
if (page === 0) return 1;
|
||||
return page;
|
||||
}, [filteredData, selectedJob]);
|
||||
|
||||
if (loading) return <LoadingSkeleton />;
|
||||
return (
|
||||
<Table
|
||||
loading={loading}
|
||||
title={() => (
|
||||
<Card
|
||||
title={t("jobs.labels.availablejobs")}
|
||||
extra={
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
value={state.search}
|
||||
onChange={(e) => setState({ ...state, search: e.target.value })}
|
||||
/>
|
||||
)}
|
||||
pagination={{
|
||||
position: "top",
|
||||
defaultPageSize: 3,
|
||||
defaultCurrent: defaultCurrent,
|
||||
}}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={filteredData}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: handleSelect,
|
||||
type: "radio",
|
||||
selectedRowKeys: [selectedJob],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
handleSelect(record);
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
pagination={{
|
||||
position: "top",
|
||||
defaultPageSize: 10,
|
||||
defaultCurrent: defaultCurrent,
|
||||
}}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={filteredData}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: handleSelect,
|
||||
type: "radio",
|
||||
selectedRowKeys: [selectedJob],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
handleSelect(record);
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,14 +25,12 @@ export function ContractJobsContainer({ selectedJobState, bodyshop }) {
|
||||
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
return (
|
||||
<div>
|
||||
<ContractJobsComponent
|
||||
handleSelect={handleSelect}
|
||||
selectedJob={selectedJob}
|
||||
loading={loading}
|
||||
data={data ? data.jobs : []}
|
||||
/>
|
||||
</div>
|
||||
<ContractJobsComponent
|
||||
handleSelect={handleSelect}
|
||||
selectedJob={selectedJob}
|
||||
loading={loading}
|
||||
data={data ? data.jobs : []}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export default connect(mapStateToProps, null)(ContractJobsContainer);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { Button, Input, Table } from "antd";
|
||||
import { Button, Card, Input, Space, Table } from "antd";
|
||||
import queryString from "query-string";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -123,38 +123,39 @@ export default function ContractsList({ loading, contracts, refetch, total }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Table
|
||||
loading={loading}
|
||||
title={() => (
|
||||
<div className="imex-table-header">
|
||||
<Card
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<div>
|
||||
<TimeTicketsDatesSelector />
|
||||
</div>
|
||||
<div className="imex-table-header__search">
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
search.search = value;
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
scroll={{ x: "50%", y: "40rem" }}
|
||||
pagination={{
|
||||
position: "top",
|
||||
pageSize: 25,
|
||||
current: parseInt(page || 1),
|
||||
total: total,
|
||||
}}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={contracts}
|
||||
onChange={handleTableChange}
|
||||
/>
|
||||
|
||||
<TimeTicketsDatesSelector />
|
||||
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
search.search = value;
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
scroll={{ x: "50%", y: "40rem" }}
|
||||
pagination={{
|
||||
position: "top",
|
||||
pageSize: 25,
|
||||
current: parseInt(page || 1),
|
||||
total: total,
|
||||
}}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={contracts}
|
||||
onChange={handleTableChange}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,14 @@ const CourtesyCarFuelComponent = (props, ref) => {
|
||||
},
|
||||
};
|
||||
|
||||
return <Slider ref={ref} marks={marks} step={null} {...props} />;
|
||||
return (
|
||||
<Slider
|
||||
ref={ref}
|
||||
marks={marks}
|
||||
step={null}
|
||||
style={{ marginLeft: "2rem", marginRight: "2rem" }}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
export default forwardRef(CourtesyCarFuelComponent);
|
||||
|
||||
@@ -143,7 +143,7 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
|
||||
<Table
|
||||
loading={loading}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={tableData}
|
||||
onChange={handleTableChange}
|
||||
|
||||
@@ -39,7 +39,7 @@ export function JobsTotalsTableComponent({ jobRO, job }) {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Row gutter={[32, 32]}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col {...colSpan}>
|
||||
<Card title={t("jobs.labels.labortotals")}>
|
||||
<JobTotalsTableLabor job={job} />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Col, Row, Typography } from "antd";
|
||||
import React from "react";
|
||||
import { Checkbox, Col, Row } from "antd";
|
||||
import React, { useContext } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
|
||||
import JobsCreateOwnerInfoNewComponent from "./jobs-create-owner-info.new.component";
|
||||
import JobsCreateOwnerInfoSearchComponent from "./jobs-create-owner-info.search.component";
|
||||
|
||||
@@ -11,12 +12,30 @@ const colSpan = {
|
||||
|
||||
export default function JobsCreateOwnerInfoComponent({ loading, owners }) {
|
||||
const { t } = useTranslation();
|
||||
const [state, setState] = useContext(JobCreateContext);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Row>
|
||||
<Typography.Title>{t("jobs.labels.create.ownerinfo")}</Typography.Title>
|
||||
</Row>
|
||||
<Row gutter={[32, 32]}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={24}>
|
||||
<Checkbox
|
||||
defaultChecked={state.owner.new}
|
||||
checked={state.owner.new}
|
||||
onChange={() => {
|
||||
setState({
|
||||
...state,
|
||||
owner: {
|
||||
...state.owner,
|
||||
new: !state.owner.new,
|
||||
selectedid: null,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.labels.create.newowner")}
|
||||
</Checkbox>
|
||||
</Col>
|
||||
|
||||
<Col {...colSpan}>
|
||||
<JobsCreateOwnerInfoSearchComponent
|
||||
loading={loading}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Form, Input, Checkbox, Switch } from "antd";
|
||||
import { Form, Input, Switch } from "antd";
|
||||
import React, { useContext } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
|
||||
@@ -9,28 +9,11 @@ import FormItemPhone, {
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
|
||||
export default function JobsCreateOwnerInfoNewComponent() {
|
||||
const [state, setState] = useContext(JobCreateContext);
|
||||
const [state] = useContext(JobCreateContext);
|
||||
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div>
|
||||
<Checkbox
|
||||
defaultChecked={state.owner.new}
|
||||
checked={state.owner.new}
|
||||
onChange={() => {
|
||||
setState({
|
||||
...state,
|
||||
owner: {
|
||||
...state.owner,
|
||||
new: !state.owner.new,
|
||||
selectedid: null,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.labels.create.newowner")}
|
||||
</Checkbox>
|
||||
|
||||
<LayoutFormRow header={t("owners.forms.name")} grow>
|
||||
<Form.Item
|
||||
label={t("owners.fields.ownr_ln")}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Input, Table } from "antd";
|
||||
import { Card, Input, Table } from "antd";
|
||||
import React, { useContext, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
|
||||
@@ -91,65 +91,63 @@ export default function JobsCreateOwnerInfoSearchComponent({
|
||||
};
|
||||
|
||||
return (
|
||||
<Table
|
||||
loading={loading}
|
||||
title={() => {
|
||||
return (
|
||||
<div className="imex-table-header">
|
||||
<Input.Search
|
||||
className="imex-table-header__search"
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
setState({
|
||||
...state,
|
||||
owner: { ...state.owner, search: value },
|
||||
});
|
||||
}}
|
||||
enterButton
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
scroll={{ x: true }}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={owners}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: (props) => {
|
||||
setState({
|
||||
...state,
|
||||
owner: { ...state.owner, new: false, selectedid: props.id },
|
||||
});
|
||||
},
|
||||
type: "radio",
|
||||
selectedRowKeys: [state.owner.selectedid],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
if (record) {
|
||||
if (record.id) {
|
||||
setState({
|
||||
...state,
|
||||
owner: {
|
||||
...state.owner,
|
||||
new: false,
|
||||
selectedid: record.id,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
<Card
|
||||
extra={
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
setState({
|
||||
...state,
|
||||
owner: { ...state.owner, selectedid: null },
|
||||
owner: { ...state.owner, search: value },
|
||||
});
|
||||
}}
|
||||
enterButton
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
scroll={{ x: true }}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={owners}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: (props) => {
|
||||
setState({
|
||||
...state,
|
||||
owner: { ...state.owner, new: false, selectedid: props.id },
|
||||
});
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
type: "radio",
|
||||
selectedRowKeys: [state.owner.selectedid],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
if (record) {
|
||||
if (record.id) {
|
||||
setState({
|
||||
...state,
|
||||
owner: {
|
||||
...state.owner,
|
||||
new: false,
|
||||
selectedid: record.id,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
setState({
|
||||
...state,
|
||||
owner: { ...state.owner, selectedid: null },
|
||||
});
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,56 @@
|
||||
import { Col, Row, Typography } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Checkbox, Col, Row } from "antd";
|
||||
import React, { useContext } from "react";
|
||||
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
|
||||
import JobsCreateVehicleInfoNewComponent from "./jobs-create-vehicle-info.new.component";
|
||||
import JobsCreateVehicleInfoSearchComponent from "./jobs-create-vehicle-info.search.component";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
const colSpan = {
|
||||
sm: { span: 24 },
|
||||
lg: { span: 12 },
|
||||
};
|
||||
|
||||
export default function JobsCreateVehicleInfoComponent({ loading, vehicles }) {
|
||||
const [state, setState] = useContext(JobCreateContext);
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div>
|
||||
<Typography.Title>{t("jobs.labels.create.vehicleinfo")}</Typography.Title>
|
||||
<Row gutter={[32, 32]}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={24}>
|
||||
<Checkbox
|
||||
defaultChecked={state.vehicle.new}
|
||||
checked={state.vehicle.new}
|
||||
onChange={() => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
none: false,
|
||||
new: !state.vehicle.new,
|
||||
selectedid: null,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.labels.create.newvehicle")}
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
defaultChecked={state.vehicle.none}
|
||||
checked={state.vehicle.none}
|
||||
onChange={() => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
new: false,
|
||||
none: !state.vehicle.none,
|
||||
selectedid: null,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.labels.create.novehicle")}
|
||||
</Checkbox>
|
||||
</Col>
|
||||
<Col {...colSpan}>
|
||||
<JobsCreateVehicleInfoSearchComponent
|
||||
loading={loading}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Checkbox, Form, Input } from "antd";
|
||||
import { Form, Input } from "antd";
|
||||
import React, { useContext } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
|
||||
@@ -6,46 +6,11 @@ import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
|
||||
export default function JobsCreateVehicleInfoNewComponent() {
|
||||
const [state, setState] = useContext(JobCreateContext);
|
||||
const [state] = useContext(JobCreateContext);
|
||||
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div>
|
||||
<Checkbox
|
||||
defaultChecked={state.vehicle.new}
|
||||
checked={state.vehicle.new}
|
||||
onChange={() => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
none: false,
|
||||
new: !state.vehicle.new,
|
||||
selectedid: null,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.labels.create.newvehicle")}
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
defaultChecked={state.vehicle.none}
|
||||
checked={state.vehicle.none}
|
||||
onChange={() => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
new: false,
|
||||
none: !state.vehicle.none,
|
||||
selectedid: null,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.labels.create.novehicle")}
|
||||
</Checkbox>
|
||||
|
||||
<LayoutFormRow header={t("vehicles.forms.detail")} grow>
|
||||
<Form.Item
|
||||
label={t("vehicles.fields.v_vin")}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Table, Input } from "antd";
|
||||
import { Table, Input, Card, Space } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
|
||||
@@ -55,73 +55,77 @@ export default function JobsCreateVehicleInfoSearchComponent({
|
||||
};
|
||||
|
||||
return (
|
||||
<Table
|
||||
loading={loading}
|
||||
title={() => {
|
||||
return (
|
||||
<div className="imex-table-header">
|
||||
<Input.Search
|
||||
className="imex-table-header__search"
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: { ...state.vehicle, search: value },
|
||||
});
|
||||
}}
|
||||
enterButton
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
scroll={{ x: true }}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={vehicles}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: (props) => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
none: false,
|
||||
new: false,
|
||||
selectedid: props.id,
|
||||
vehicleObj: props,
|
||||
},
|
||||
});
|
||||
},
|
||||
type: "radio",
|
||||
selectedRowKeys: [state.vehicle.selectedid],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
if (record) {
|
||||
if (record.id) {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
none: false,
|
||||
new: false,
|
||||
selectedid: record.id,
|
||||
vehicleObj: record,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
<Card
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: { ...state.vehicle, search: value },
|
||||
});
|
||||
}}
|
||||
enterButton
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
scroll={{ x: true }}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={vehicles}
|
||||
onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: (props) => {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: { ...state.vehicle, selectedid: null, vehicleObj: null },
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
none: false,
|
||||
new: false,
|
||||
selectedid: props.id,
|
||||
vehicleObj: props,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
type: "radio",
|
||||
selectedRowKeys: [state.vehicle.selectedid],
|
||||
}}
|
||||
onRow={(record, rowIndex) => {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
if (record) {
|
||||
if (record.id) {
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
none: false,
|
||||
new: false,
|
||||
selectedid: record.id,
|
||||
vehicleObj: record,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
setState({
|
||||
...state,
|
||||
vehicle: {
|
||||
...state.vehicle,
|
||||
selectedid: null,
|
||||
vehicleObj: null,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -142,46 +142,6 @@ export function JobsDetailHeader({ job, bodyshop }) {
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
||||
// return (
|
||||
// <PageHeader
|
||||
// title={job.ro_number || t("general.labels.na")}
|
||||
// subTitle={job.status}
|
||||
// tags={[
|
||||
// <OwnerTagPopoverComponent key="owner" job={job} />,
|
||||
// <VehicleTagPopoverComponent key="vehicle" job={job} />,
|
||||
// <Tag
|
||||
// color="#f50"
|
||||
// key="production"
|
||||
// style={{ display: job.inproduction ? "" : "none" }}
|
||||
// >
|
||||
// {t("jobs.labels.inproduction")}
|
||||
// </Tag>,
|
||||
// <Tag title={t("jobs.fields.repairtotal")} key="total" color="green">
|
||||
// <CurrencyFormatter>{job.clm_total}</CurrencyFormatter>
|
||||
// <span style={{ margin: "0rem .5rem" }}>/</span>
|
||||
// <CurrencyFormatter>{job.owner_owing}</CurrencyFormatter>
|
||||
// </Tag>,
|
||||
// ]}
|
||||
// extra={menuExtra}
|
||||
// >
|
||||
// <div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
// {(job.inproduction || jobInPostProduction) && (
|
||||
// <>
|
||||
// <div style={{ display: "flex", flex: 1 }}>
|
||||
// <div style={{ marginRight: "2rem" }}>
|
||||
// {t("jobs.fields.production_vars.note")}
|
||||
// </div>
|
||||
// <ProductionListColumnProductionNote record={job} />
|
||||
// </div>
|
||||
// <Divider type="vertical" />
|
||||
// </>
|
||||
// )}
|
||||
|
||||
//
|
||||
// </div>
|
||||
// </PageHeader>
|
||||
// );
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailHeader);
|
||||
|
||||
@@ -156,7 +156,7 @@ export default function JobsFindModalComponent({
|
||||
</div>
|
||||
)}
|
||||
pagination={{ position: "bottom" }}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
loading={jobsListLoading}
|
||||
dataSource={jobsList}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { Button, Input, Table } from "antd";
|
||||
import { Button, Card, Input, Space, Table } from "antd";
|
||||
import queryString from "query-string";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -191,7 +191,23 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
search.search = value;
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
enterButton
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
scroll={{ x: true }}
|
||||
@@ -205,26 +221,8 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
rowKey="id"
|
||||
dataSource={jobs}
|
||||
onChange={handleTableChange}
|
||||
title={() => {
|
||||
return (
|
||||
<div className="imex-table-header">
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<Input.Search
|
||||
className="imex-table-header__search"
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
search.search = value;
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
enterButton
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsList);
|
||||
|
||||
@@ -68,7 +68,7 @@ export default function OwnerFindModalComponent({
|
||||
<Table
|
||||
title={() => t("owners.labels.existing_owners")}
|
||||
pagination={{ position: "bottom" }}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
loading={ownersListLoading}
|
||||
dataSource={ownersList}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Input } from "antd";
|
||||
import { Input, PageHeader, Space, Spin } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
@@ -17,25 +17,35 @@ export default connect(
|
||||
mapDispatchToProps
|
||||
)(ProductionBoardFilters);
|
||||
|
||||
export function ProductionBoardFilters({ bodyshop, filter, setFilter }) {
|
||||
export function ProductionBoardFilters({
|
||||
bodyshop,
|
||||
filter,
|
||||
setFilter,
|
||||
loading,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex" }}>
|
||||
<Input.Search
|
||||
//value={filter.search}
|
||||
placeholder={t("general.labels.search")}
|
||||
onChange={(e) => {
|
||||
setFilter({ ...filter, search: e.target.value });
|
||||
}}
|
||||
/>
|
||||
<EmployeeSearchSelectComponent
|
||||
options={bodyshop.employees.filter((e) => e.active)}
|
||||
value={filter.employeeId}
|
||||
placeholder={t("production.labels.employeesearch")}
|
||||
onChange={(emp) => setFilter({ ...filter, employeeId: emp })}
|
||||
allowClear
|
||||
/>
|
||||
</div>
|
||||
<PageHeader
|
||||
extra={
|
||||
<Space wrap>
|
||||
{loading && <Spin />}
|
||||
<Input.Search
|
||||
//value={filter.search}
|
||||
placeholder={t("general.labels.search")}
|
||||
onChange={(e) => {
|
||||
setFilter({ ...filter, search: e.target.value });
|
||||
}}
|
||||
/>
|
||||
<EmployeeSearchSelectComponent
|
||||
options={bodyshop.employees.filter((e) => e.active)}
|
||||
value={filter.employeeId}
|
||||
placeholder={t("production.labels.employeesearch")}
|
||||
onChange={(emp) => setFilter({ ...filter, employeeId: emp })}
|
||||
allowClear
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
></PageHeader>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
.imex-kanban-card {
|
||||
padding: 0px !important;
|
||||
.ant-card-body {
|
||||
padding: 0.8rem;
|
||||
}
|
||||
.ant-card-head {
|
||||
padding: 0rem 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export default function ProductionBoardCard(technician, card) {
|
||||
<Dropdown overlay={menu} trigger={["contextMenu"]}>
|
||||
<Card
|
||||
className="react-kanban-card imex-kanban-card tight-antd-rows"
|
||||
style={{ margin: ".2rem 0rem" }}
|
||||
//style={{ margin: ".2rem 0rem" }}
|
||||
title={`${card.ro_number || t("general.labels.na")} - ${
|
||||
card.v_model_yr
|
||||
} ${card.v_make_desc || ""} ${card.v_model_desc || ""}`}
|
||||
|
||||
@@ -116,7 +116,11 @@ export function ProductionBoardKanbanComponent({ data, bodyshop, technician }) {
|
||||
return (
|
||||
<div>
|
||||
<IndefiniteLoading loading={isMoving} />
|
||||
<ProductionBoardFilters filter={filter} setFilter={setFilter} />
|
||||
<ProductionBoardFilters
|
||||
filter={filter}
|
||||
setFilter={setFilter}
|
||||
loading={isMoving}
|
||||
/>
|
||||
<Board
|
||||
children={boardLanes}
|
||||
disableCardDrag={isMoving}
|
||||
|
||||
@@ -11,11 +11,10 @@ const mapStateToProps = createStructuredSelector({
|
||||
});
|
||||
|
||||
export function ProductionBoardKanbanContainer({ bodyshop }) {
|
||||
const { loading, data } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION, {
|
||||
// variables: {
|
||||
// statusList: bodyshop.md_ro_statuses.production_statuses || [],
|
||||
// },
|
||||
});
|
||||
const { loading, data } = useSubscription(
|
||||
SUBSCRIPTION_JOBS_IN_PRODUCTION,
|
||||
{}
|
||||
);
|
||||
|
||||
return (
|
||||
<ProductionBoardKanbanComponent
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { Button, Dropdown, Input, Menu, Table } from "antd";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Dropdown,
|
||||
Input,
|
||||
Menu,
|
||||
PageHeader,
|
||||
Space,
|
||||
Table,
|
||||
} from "antd";
|
||||
import React, { useState } from "react";
|
||||
import ReactDragListView from "react-drag-listview";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -108,24 +117,7 @@ export function ProductionListTable({
|
||||
.includes(searchText.toLowerCase())
|
||||
);
|
||||
|
||||
const tableTitle = () => (
|
||||
<div style={{ display: "flex" }}>
|
||||
<ProductionListColumnsAdd columnState={columnState} />
|
||||
<ProductionListSaveConfigButton columns={columns} tableState={state} />
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (refetch) refetch();
|
||||
}}
|
||||
>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<Input
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
placeholder={t("general.labels.search")}
|
||||
value={searchText}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
const tableTitle = () => <div style={{ display: "flex" }}></div>;
|
||||
|
||||
// const handleSelectRecord = (record) => {
|
||||
// if (selected !== record.id) {
|
||||
@@ -139,6 +131,29 @@ export function ProductionListTable({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageHeader
|
||||
extra={
|
||||
<Space wrap>
|
||||
<ProductionListColumnsAdd columnState={columnState} />
|
||||
<ProductionListSaveConfigButton
|
||||
columns={columns}
|
||||
tableState={state}
|
||||
/>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (refetch) refetch();
|
||||
}}
|
||||
>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<Input
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
placeholder={t("general.labels.search")}
|
||||
value={searchText}
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
/>
|
||||
<ProductionListDetail jobs={dataSource} />
|
||||
<ReactDragListView.DragColumn
|
||||
onDragEnd={onDragEnd}
|
||||
@@ -147,6 +162,7 @@ export function ProductionListTable({
|
||||
>
|
||||
<Table
|
||||
pagination={false}
|
||||
size="small"
|
||||
components={{
|
||||
header: {
|
||||
cell: ResizeableTitle,
|
||||
@@ -168,15 +184,8 @@ export function ProductionListTable({
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
dataSource={dataSource}
|
||||
scrol={{ x: true }}
|
||||
onChange={handleTableChange}
|
||||
// rowClassName={(record, index) => {
|
||||
// // const classes = [];
|
||||
// // if (!!record.scheduled_completion) {
|
||||
// // if (new Date(record.scheduled_completion) - Now < OneCalendarDay)
|
||||
// // classes.push("production-completion-1");
|
||||
// // }
|
||||
// // return classes.join(" ");
|
||||
// }}
|
||||
/>
|
||||
</ReactDragListView.DragColumn>
|
||||
</div>
|
||||
|
||||
@@ -16,11 +16,10 @@ const mapStateToProps = createStructuredSelector({
|
||||
export default connect(mapStateToProps, null)(ProductionListTableContainer);
|
||||
|
||||
export function ProductionListTableContainer({ bodyshop, technician }) {
|
||||
const { loading, data } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION, {
|
||||
// variables: {
|
||||
// statusList: bodyshop.md_ro_statuses.production_statuses || [],
|
||||
// },
|
||||
});
|
||||
const { loading, data } = useSubscription(
|
||||
SUBSCRIPTION_JOBS_IN_PRODUCTION,
|
||||
{}
|
||||
);
|
||||
|
||||
const columnState = useState(
|
||||
(bodyshop.production_config &&
|
||||
|
||||
@@ -48,7 +48,7 @@ export default function ProfileShopsComponent({
|
||||
</Typography.Title>
|
||||
)}
|
||||
loading={loading}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={data}
|
||||
/>
|
||||
|
||||
@@ -63,7 +63,7 @@ export function ScheduleJobModalComponent({
|
||||
};
|
||||
|
||||
return (
|
||||
<Row gutter={[32, 32]}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={12}>
|
||||
<LayoutFormRow grow>
|
||||
<Form.Item
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function ShopEmployeesListComponent({
|
||||
}}
|
||||
loading={loading}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={employees}
|
||||
rowSelection={{
|
||||
|
||||
@@ -49,7 +49,7 @@ export default function ShopInfoUsersComponent() {
|
||||
<Table
|
||||
loading={loading}
|
||||
pagination={{ position: "top" }}
|
||||
columns={columns.map((item) => ({ ...item }))}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={data && data.associations}
|
||||
/>
|
||||
|
||||
@@ -33,15 +33,13 @@ export default function TimeTicketsDatesSelector() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DatePicker.RangePicker
|
||||
defaultValue={[
|
||||
start ? moment(start) : moment().startOf("week").subtract(7, "days"),
|
||||
end ? moment(end) : moment().endOf("week"),
|
||||
]}
|
||||
ranges={DatePickerRanges}
|
||||
onCalendarChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
<DatePicker.RangePicker
|
||||
defaultValue={[
|
||||
start ? moment(start) : moment().startOf("week").subtract(7, "days"),
|
||||
end ? moment(end) : moment().endOf("week"),
|
||||
]}
|
||||
ranges={DatePickerRanges}
|
||||
onCalendarChange={handleChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { Button, Checkbox, Input, Space, Table, Typography } from "antd";
|
||||
import { Button, Card, Checkbox, Input, Space, Table } from "antd";
|
||||
import queryString from "query-string";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -201,37 +201,39 @@ export function BillsListPage({
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card
|
||||
title={t("bills.labels.bills")}
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setBillEnterContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.actions.postbills")}
|
||||
</Button>
|
||||
<div className="imex-table-header__search">
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
search.search = value;
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<PartsOrderModalContainer />
|
||||
<Typography.Title level={4}>{t("bills.labels.bills")}</Typography.Title>
|
||||
|
||||
<Table
|
||||
loading={loading}
|
||||
title={() => (
|
||||
<div className="imex-table-header">
|
||||
<Button onClick={() => refetch()}>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setBillEnterContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("jobs.actions.postbills")}
|
||||
</Button>
|
||||
<div className="imex-table-header__search">
|
||||
<Input.Search
|
||||
placeholder={t("general.labels.search")}
|
||||
onSearch={(value) => {
|
||||
search.search = value;
|
||||
history.push({ search: queryString.stringify(search) });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
scroll={{ x: "50%", y: "40rem" }}
|
||||
pagination={{
|
||||
position: "top",
|
||||
@@ -244,7 +246,7 @@ export function BillsListPage({
|
||||
dataSource={data}
|
||||
onChange={handleTableChange}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
export default connect(null, mapDispatchToProps)(BillsListPage);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button } from "antd";
|
||||
import { Button, Col, PageHeader, Row } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ContractCarsContainer from "../../components/contract-cars/contract-cars.container";
|
||||
@@ -25,22 +25,31 @@ export default function ContractCreatePageComponent({
|
||||
|
||||
return (
|
||||
<div>
|
||||
{CreateButton}
|
||||
<ContractJobsContainer selectedJobState={selectedJobState} />
|
||||
<ContractCarsContainer selectedCarState={selectedCarState} form={form} />
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: selectedJobState[0] && selectedCarState[0] ? "" : "none",
|
||||
}}
|
||||
>
|
||||
<ContractFormComponent
|
||||
create
|
||||
form={form}
|
||||
selectedJobState={selectedJobState}
|
||||
/>
|
||||
</div>
|
||||
{CreateButton}
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={24}>
|
||||
<ContractJobsContainer selectedJobState={selectedJobState} />
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<ContractCarsContainer
|
||||
selectedCarState={selectedCarState}
|
||||
form={form}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<div
|
||||
style={{
|
||||
display: selectedJobState[0] && selectedCarState[0] ? "" : "none",
|
||||
}}
|
||||
>
|
||||
<ContractFormComponent
|
||||
create
|
||||
form={form}
|
||||
selectedJobState={selectedJobState}
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<PageHeader extra={CreateButton} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Col, Row, Space, Typography, Form } from "antd";
|
||||
import { Button, Col, Row, Space, Typography, Form, PageHeader } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
@@ -28,17 +28,14 @@ export function ContractDetailPage({
|
||||
return (
|
||||
<div>
|
||||
<Row align="middle">
|
||||
<Typography.Title>{`Agreement ${
|
||||
(contract && contract.agreementnumber) || ""
|
||||
} - ${t((contract && contract.status) || "")}`}</Typography.Title>
|
||||
<Typography.Title></Typography.Title>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col span={4} offset={1}>
|
||||
<ContractJobBlock job={job} />
|
||||
<ContractCourtesyCarBlock courtesyCar={courtesyCar} />
|
||||
</Col>
|
||||
<Col span={18} offset={1}>
|
||||
<PageHeader
|
||||
title={t("contracts.labels.agreement", {
|
||||
agreement_num: contract && contract.agreementnumber,
|
||||
status: t(contract && contract.status),
|
||||
})}
|
||||
extra={
|
||||
<Form.Item shouldUpdate>
|
||||
{() => {
|
||||
return (
|
||||
@@ -94,6 +91,16 @@ export function ContractDetailPage({
|
||||
);
|
||||
}}
|
||||
</Form.Item>
|
||||
}
|
||||
/>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col sm={24} md={12}>
|
||||
<ContractJobBlock job={job} />
|
||||
</Col>
|
||||
<Col sm={24} md={12}>
|
||||
<ContractCourtesyCarBlock courtesyCar={courtesyCar} />
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<ContractFormComponent form={form} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -8,13 +8,11 @@ export default function ContractsPageComponent({
|
||||
total,
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<ContractsList
|
||||
loading={loading}
|
||||
contracts={data}
|
||||
refetch={refetch}
|
||||
total={total}
|
||||
/>
|
||||
</div>
|
||||
<ContractsList
|
||||
loading={loading}
|
||||
contracts={data}
|
||||
refetch={refetch}
|
||||
total={total}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export function JobsChecklistViewContainer({
|
||||
|
||||
return (
|
||||
<RbacWrapper action="jobs:checklist-view">
|
||||
<Row gutter={[32, 32]}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={12}>
|
||||
<Typography.Title level={4}>
|
||||
{t("jobs.labels.intakechecklist")}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Result, Steps } from "antd";
|
||||
import { Button, PageHeader, Result, Space, Steps } from "antd";
|
||||
import React, { useContext, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
@@ -44,36 +44,68 @@ export default function JobsCreateComponent({ form }) {
|
||||
};
|
||||
const { Step } = Steps;
|
||||
|
||||
const ProgressButtons = () => {
|
||||
const ProgressButtons = ({ top }) => {
|
||||
return (
|
||||
<div style={{ margin: "1rem" }}>
|
||||
{pageIndex > 0 && <Button onClick={() => prev()}>Previous</Button>}
|
||||
{pageIndex < steps.length - 1 && (
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
form
|
||||
.validateFields()
|
||||
.then((r) => {
|
||||
if (steps[pageIndex].validation) {
|
||||
setErrorMessage(null);
|
||||
next();
|
||||
} else {
|
||||
setErrorMessage(steps[pageIndex].error);
|
||||
}
|
||||
})
|
||||
.catch((error) => console.log("error", error));
|
||||
}}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<PageHeader
|
||||
extra={
|
||||
<Space wrap>
|
||||
{pageIndex > 0 && <Button onClick={() => prev()}>Previous</Button>}
|
||||
{pageIndex < steps.length - 1 && (
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
form
|
||||
.validateFields()
|
||||
.then((r) => {
|
||||
if (steps[pageIndex].validation) {
|
||||
setErrorMessage(null);
|
||||
next();
|
||||
} else {
|
||||
setErrorMessage(steps[pageIndex].error);
|
||||
}
|
||||
})
|
||||
.catch((error) => console.log("error", error));
|
||||
}}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
)}
|
||||
{pageIndex === steps.length - 1 && (
|
||||
<Button type="primary" htmlType="submit">
|
||||
Done
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
{top && (
|
||||
<Steps current={pageIndex}>
|
||||
{steps.map((item, idx) => (
|
||||
<Step
|
||||
key={item.title}
|
||||
title={item.title}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
fontWeight: idx === pageIndex && "bolder",
|
||||
}}
|
||||
onClick={() => {
|
||||
form
|
||||
.validateFields()
|
||||
.then((r) => {
|
||||
if (steps[pageIndex].validation) {
|
||||
setErrorMessage(null);
|
||||
setPageIndex(idx);
|
||||
} else {
|
||||
setErrorMessage(steps[pageIndex].error);
|
||||
}
|
||||
})
|
||||
.catch((error) => console.log("error", error));
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Steps>
|
||||
)}
|
||||
{pageIndex === steps.length - 1 && (
|
||||
<Button type="primary" htmlType="submit">
|
||||
Done
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</PageHeader>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -96,29 +128,7 @@ export default function JobsCreateComponent({ form }) {
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<Steps current={pageIndex}>
|
||||
{steps.map((item, idx) => (
|
||||
<Step
|
||||
key={item.title}
|
||||
title={item.title}
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => {
|
||||
form
|
||||
.validateFields()
|
||||
.then((r) => {
|
||||
if (steps[pageIndex].validation) {
|
||||
setErrorMessage(null);
|
||||
setPageIndex(idx);
|
||||
} else {
|
||||
setErrorMessage(steps[pageIndex].error);
|
||||
}
|
||||
})
|
||||
.catch((error) => console.log("error", error));
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Steps>
|
||||
<ProgressButtons />
|
||||
<ProgressButtons top />
|
||||
|
||||
{errorMessage ? (
|
||||
<div>
|
||||
|
||||
@@ -149,6 +149,7 @@ function JobsCreateContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
|
||||
<JobCreateContext.Provider value={contextState}>
|
||||
<RbacWrapper action="jobs:create">
|
||||
<Form
|
||||
scrollToFirstError
|
||||
form={form}
|
||||
onFinish={handleFinish}
|
||||
layout="vertical"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import ProductionListTable from "../../components/production-list-table/production-list-table.container";
|
||||
|
||||
export default function ProductionListComponent({ columnState }) {
|
||||
export default function ProductionListComponent() {
|
||||
return <ProductionListTable />;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
|
||||
import {
|
||||
setBreadcrumbs,
|
||||
setSelectedHeader,
|
||||
} from "../../redux/application/application.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import ProductionListComponent from "./production-list.component";
|
||||
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
|
||||
@@ -21,7 +15,7 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
export function ProductionListContainer({
|
||||
setBreadcrumbs,
|
||||
bodyshop,
|
||||
|
||||
setSelectedHeader,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
@@ -40,7 +34,4 @@ export function ProductionListContainer({
|
||||
</RbacWrapper>
|
||||
);
|
||||
}
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ProductionListContainer);
|
||||
export default connect(null, mapDispatchToProps)(ProductionListContainer);
|
||||
|
||||
@@ -520,13 +520,17 @@
|
||||
"status": "Status"
|
||||
},
|
||||
"labels": {
|
||||
"agreement": "Agreement {{agreement_num}} - {{status}}",
|
||||
"availablecars": "Available Cars",
|
||||
"convertform": {
|
||||
"applycleanupcharge": "Apply cleanup charge?",
|
||||
"refuelqty": "Refuel qty.?"
|
||||
},
|
||||
"correctdataonform": "Please review the information above. If any of it is not correct, you can fix it later.",
|
||||
"driverinformation": "Driver's Information",
|
||||
"noteconvertedfrom": "R.O. created from converted Courtesy Car Contract {{agreementnumber}}.",
|
||||
"populatefromjob": "Populate from Job",
|
||||
"rates": "Contract Rates",
|
||||
"vehicle": "Vehicle",
|
||||
"waitingforscan": "Please scan driver's license barcode..."
|
||||
},
|
||||
|
||||
@@ -520,13 +520,17 @@
|
||||
"status": ""
|
||||
},
|
||||
"labels": {
|
||||
"agreement": "",
|
||||
"availablecars": "",
|
||||
"convertform": {
|
||||
"applycleanupcharge": "",
|
||||
"refuelqty": ""
|
||||
},
|
||||
"correctdataonform": "",
|
||||
"driverinformation": "",
|
||||
"noteconvertedfrom": "",
|
||||
"populatefromjob": "",
|
||||
"rates": "",
|
||||
"vehicle": "",
|
||||
"waitingforscan": ""
|
||||
},
|
||||
|
||||
@@ -520,13 +520,17 @@
|
||||
"status": ""
|
||||
},
|
||||
"labels": {
|
||||
"agreement": "",
|
||||
"availablecars": "",
|
||||
"convertform": {
|
||||
"applycleanupcharge": "",
|
||||
"refuelqty": ""
|
||||
},
|
||||
"correctdataonform": "",
|
||||
"driverinformation": "",
|
||||
"noteconvertedfrom": "",
|
||||
"populatefromjob": "",
|
||||
"rates": "",
|
||||
"vehicle": "",
|
||||
"waitingforscan": ""
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user