Finalized read only job. Logic to detmerine what is read only outstanding. BOD-409
This commit is contained in:
@@ -1,18 +1,17 @@
|
|||||||
import { SyncOutlined } from "@ant-design/icons";
|
import { SyncOutlined } from "@ant-design/icons";
|
||||||
import { Button, Checkbox, Descriptions, Table, Input, Typography } from "antd";
|
import { Button, Checkbox, Descriptions, Input, Table, Typography } from "antd";
|
||||||
|
import queryString from "query-string";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { Link } from "react-router-dom";
|
import { Link, useLocation } from "react-router-dom";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
import { DateFormatter } from "../../utils/DateFormatter";
|
import { DateFormatter } from "../../utils/DateFormatter";
|
||||||
import { alphaSort } from "../../utils/sorters";
|
import { alphaSort } from "../../utils/sorters";
|
||||||
import queryString from "query-string";
|
|
||||||
import { useLocation } from "react-router-dom";
|
|
||||||
|
|
||||||
import { createStructuredSelector } from "reselect";
|
|
||||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
jobRO: selectJobReadOnly,
|
jobRO: selectJobReadOnly,
|
||||||
});
|
});
|
||||||
@@ -376,4 +375,7 @@ export function BillsListTableComponent({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
export default connect(null, mapDispatchToProps)(BillsListTableComponent);
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(BillsListTableComponent);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { TimePicker } from "antd";
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
//To be used as a form element only.
|
//To be used as a form element only.
|
||||||
|
|
||||||
const DateTimePicker = ({ value, onChange, onBlur }, ref) => {
|
const DateTimePicker = ({ value, onChange, onBlur, ...restProps }, ref) => {
|
||||||
// const handleChange = (newDate) => {
|
// const handleChange = (newDate) => {
|
||||||
// if (value !== newDate && onChange) {
|
// if (value !== newDate && onChange) {
|
||||||
// onChange(newDate);
|
// onChange(newDate);
|
||||||
@@ -15,9 +15,15 @@ const DateTimePicker = ({ value, onChange, onBlur }, ref) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<FormDatePicker value={value} onBlur={onBlur} onChange={onChange} />
|
<FormDatePicker
|
||||||
|
{...restProps}
|
||||||
|
value={value}
|
||||||
|
onBlur={onBlur}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
|
||||||
<TimePicker
|
<TimePicker
|
||||||
|
{...restProps}
|
||||||
value={value ? moment(value) : null}
|
value={value ? moment(value) : null}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
showSecond={false}
|
showSecond={false}
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { Form } from "antd";
|
import { Form } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
|
import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
||||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
||||||
import FormRow from "../layout-form-row/layout-form-row.component";
|
import FormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
|
||||||
|
|
||||||
export default function JobsDetailDatesComponent({ job }) {
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
jobRO: selectJobReadOnly,
|
||||||
|
});
|
||||||
|
|
||||||
|
export function JobsDetailDatesComponent({ jobRO, job }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -15,10 +22,10 @@ export default function JobsDetailDatesComponent({ job }) {
|
|||||||
label={t("jobs.fields.date_estimated")}
|
label={t("jobs.fields.date_estimated")}
|
||||||
name="date_estimated"
|
name="date_estimated"
|
||||||
>
|
>
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.date_open")} name="date_open">
|
<Form.Item label={t("jobs.fields.date_open")} name="date_open">
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
|
|
||||||
@@ -27,13 +34,13 @@ export default function JobsDetailDatesComponent({ job }) {
|
|||||||
label={t("jobs.fields.date_scheduled")}
|
label={t("jobs.fields.date_scheduled")}
|
||||||
name="date_scheduled"
|
name="date_scheduled"
|
||||||
>
|
>
|
||||||
<FormDatePicker />
|
<FormDatePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.scheduled_in")} name="scheduled_in">
|
<Form.Item label={t("jobs.fields.scheduled_in")} name="scheduled_in">
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.actual_in")} name="actual_in">
|
<Form.Item label={t("jobs.fields.actual_in")} name="actual_in">
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow header={t("jobs.forms.repairdates")}>
|
<FormRow header={t("jobs.forms.repairdates")}>
|
||||||
@@ -41,38 +48,39 @@ export default function JobsDetailDatesComponent({ job }) {
|
|||||||
label={t("jobs.fields.scheduled_completion")}
|
label={t("jobs.fields.scheduled_completion")}
|
||||||
name="scheduled_completion"
|
name="scheduled_completion"
|
||||||
>
|
>
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("jobs.fields.actual_completion")}
|
label={t("jobs.fields.actual_completion")}
|
||||||
name="actual_completion"
|
name="actual_completion"
|
||||||
>
|
>
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("jobs.fields.scheduled_delivery")}
|
label={t("jobs.fields.scheduled_delivery")}
|
||||||
name="scheduled_delivery"
|
name="scheduled_delivery"
|
||||||
>
|
>
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("jobs.fields.actual_delivery")}
|
label={t("jobs.fields.actual_delivery")}
|
||||||
name="actual_delivery"
|
name="actual_delivery"
|
||||||
>
|
>
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow header={t("jobs.forms.admindates")}>
|
<FormRow header={t("jobs.forms.admindates")}>
|
||||||
<Form.Item label={t("jobs.fields.date_invoiced")} name="date_invoiced">
|
<Form.Item label={t("jobs.fields.date_invoiced")} name="date_invoiced">
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.date_closed")} name="date_closed">
|
<Form.Item label={t("jobs.fields.date_closed")} name="date_closed">
|
||||||
<DateTimePicker />
|
<DateTimePicker />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.date_exported")} name="date_exported">
|
<Form.Item label={t("jobs.fields.date_exported")} name="date_exported">
|
||||||
<DateTimePicker />
|
<DateTimePicker disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
export default connect(mapStateToProps, null)(JobsDetailDatesComponent);
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
import LaborAllocationsTableComponent from "../labor-allocations-table/labor-allocations-table.component";
|
import LaborAllocationsTableComponent from "../labor-allocations-table/labor-allocations-table.component";
|
||||||
import TimeTicketEnterButton from "../time-ticket-enter-button/time-ticket-enter-button.component";
|
import TimeTicketEnterButton from "../time-ticket-enter-button/time-ticket-enter-button.component";
|
||||||
import TimeTicketList from "../time-ticket-list/time-ticket-list.component";
|
import TimeTicketList from "../time-ticket-list/time-ticket-list.component";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
export default function JobsDetailLaborContainer({
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
jobRO: selectJobReadOnly,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, null)(JobsDetailLaborContainer);
|
||||||
|
|
||||||
|
export function JobsDetailLaborContainer({
|
||||||
|
jobRO,
|
||||||
jobId,
|
jobId,
|
||||||
joblines,
|
joblines,
|
||||||
timetickets,
|
timetickets,
|
||||||
@@ -16,7 +26,11 @@ export default function JobsDetailLaborContainer({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{techConsole ? null : (
|
{techConsole ? null : (
|
||||||
<TimeTicketEnterButton actions={{ refetch }} context={{ jobId: jobId }}>
|
<TimeTicketEnterButton
|
||||||
|
disabled={jobRO}
|
||||||
|
actions={{ refetch }}
|
||||||
|
context={{ jobId: jobId }}
|
||||||
|
>
|
||||||
{t("timetickets.actions.enter")}
|
{t("timetickets.actions.enter")}
|
||||||
</TimeTicketEnterButton>
|
</TimeTicketEnterButton>
|
||||||
)}
|
)}
|
||||||
@@ -29,6 +43,7 @@ export default function JobsDetailLaborContainer({
|
|||||||
timetickets={timetickets}
|
timetickets={timetickets}
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
techConsole={techConsole}
|
techConsole={techConsole}
|
||||||
|
disabled={jobRO}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import moment from "moment";
|
|||||||
import { onlyUnique } from "../../utils/arrayHelper";
|
import { onlyUnique } from "../../utils/arrayHelper";
|
||||||
|
|
||||||
export default function TimeTicketList({
|
export default function TimeTicketList({
|
||||||
|
disabled,
|
||||||
loading,
|
loading,
|
||||||
timetickets,
|
timetickets,
|
||||||
refetch,
|
refetch,
|
||||||
@@ -40,7 +41,8 @@ export default function TimeTicketList({
|
|||||||
sortOrder: state.sortedInfo.columnKey === "vin" && state.sortedInfo.order,
|
sortOrder: state.sortedInfo.columnKey === "vin" && state.sortedInfo.order,
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<Link
|
<Link
|
||||||
to={`/manage/employees/${record.employee.id}`}>{`${record.employee.first_name} ${record.employee.last_name}`}</Link>
|
to={`/manage/employees/${record.employee.id}`}
|
||||||
|
>{`${record.employee.first_name} ${record.employee.last_name}`}</Link>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -126,22 +128,22 @@ export default function TimeTicketList({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
!!techConsole
|
||||||
title: t("general.labels.actions"),
|
? {
|
||||||
dataIndex: "actions",
|
title: t("general.labels.actions"),
|
||||||
key: "actions",
|
dataIndex: "actions",
|
||||||
render: (text, record) => {
|
key: "actions",
|
||||||
if (techConsole) return null;
|
render: (text, record) => (
|
||||||
return (
|
<TimeTicketEnterButton
|
||||||
<TimeTicketEnterButton
|
actions={{ refetch }}
|
||||||
actions={{ refetch }}
|
context={{ id: record.id, timeticket: record }}
|
||||||
context={{ id: record.id, timeticket: record }}
|
disabled={!!!record.job || disabled}
|
||||||
disabled={!!!record.job}>
|
>
|
||||||
{t("general.actions.edit")}
|
{t("general.actions.edit")}
|
||||||
</TimeTicketEnterButton>
|
</TimeTicketEnterButton>
|
||||||
);
|
),
|
||||||
},
|
}
|
||||||
},
|
: null,
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleTableChange = (pagination, filters, sorter) => {
|
const handleTableChange = (pagination, filters, sorter) => {
|
||||||
@@ -151,10 +153,10 @@ export default function TimeTicketList({
|
|||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
loading={loading}
|
loading={loading}
|
||||||
size='small'
|
size="small"
|
||||||
pagination={{ position: "top" }}
|
pagination={{ position: "top" }}
|
||||||
columns={columns.map((item) => ({ ...item }))}
|
columns={columns.map((item) => ({ ...item }))}
|
||||||
rowKey='id'
|
rowKey="id"
|
||||||
dataSource={timetickets}
|
dataSource={timetickets}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import Icon, {
|
|||||||
DollarCircleOutlined,
|
DollarCircleOutlined,
|
||||||
FileImageFilled,
|
FileImageFilled,
|
||||||
ToolFilled,
|
ToolFilled,
|
||||||
CheckSquareFilled,
|
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import { Form, notification, Tabs } from "antd";
|
import { Form, notification, Tabs } from "antd";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
@@ -13,20 +12,15 @@ import moment from "moment";
|
|||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { lazy, Suspense, useState } from "react";
|
import React, { lazy, Suspense, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import { FaHardHat, FaRegStickyNote, FaShieldAlt } from "react-icons/fa";
|
||||||
FaHardHat,
|
|
||||||
FaHistory,
|
|
||||||
FaRegStickyNote,
|
|
||||||
FaShieldAlt,
|
|
||||||
} from "react-icons/fa";
|
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { useHistory, useLocation } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import FormFieldsChanged from "../../components/form-fields-changed-alert/form-fields-changed-alert.component";
|
import FormFieldsChanged from "../../components/form-fields-changed-alert/form-fields-changed-alert.component";
|
||||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
//import JobsDetailChecklists from "../../components/jobs-detail-checklists/jobs-detail-checklists.component";
|
||||||
import JobsDetailChecklists from "../../components/jobs-detail-checklists/jobs-detail-checklists.component";
|
|
||||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
|
||||||
const JobsLinesContainer = lazy(() =>
|
const JobsLinesContainer = lazy(() =>
|
||||||
import("../../components/job-detail-lines/job-lines.container")
|
import("../../components/job-detail-lines/job-lines.container")
|
||||||
@@ -66,9 +60,9 @@ const JobLineUpsertModalContainer = lazy(() =>
|
|||||||
const JobsDetailPliContainer = lazy(() =>
|
const JobsDetailPliContainer = lazy(() =>
|
||||||
import("../../components/jobs-detail-pli/jobs-detail-pli.container")
|
import("../../components/jobs-detail-pli/jobs-detail-pli.container")
|
||||||
);
|
);
|
||||||
const JobsDetailAuditContainer = lazy(() =>
|
// const JobsDetailAuditContainer = lazy(() =>
|
||||||
import("../../components/audit-trail-list/audit-trail-list.container")
|
// import("../../components/audit-trail-list/audit-trail-list.container")
|
||||||
);
|
// );
|
||||||
const JobsDetailLaborContainer = lazy(() =>
|
const JobsDetailLaborContainer = lazy(() =>
|
||||||
import("../../components/jobs-detail-labor/jobs-detail-labor.container")
|
import("../../components/jobs-detail-labor/jobs-detail-labor.container")
|
||||||
);
|
);
|
||||||
@@ -268,29 +262,30 @@ export function JobsDetailPage({
|
|||||||
>
|
>
|
||||||
<JobNotesContainer jobId={job.id} />
|
<JobNotesContainer jobId={job.id} />
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
|
{
|
||||||
<Tabs.TabPane
|
// <Tabs.TabPane
|
||||||
tab={
|
// tab={
|
||||||
<span>
|
// <span>
|
||||||
<Icon component={FaHistory} />
|
// <Icon component={FaHistory} />
|
||||||
{t("jobs.labels.audit")}
|
// {t("jobs.labels.audit")}
|
||||||
</span>
|
// </span>
|
||||||
}
|
// }
|
||||||
key="audit"
|
// key="audit"
|
||||||
>
|
// >
|
||||||
<JobsDetailAuditContainer recordId={job.id} />
|
// <JobsDetailAuditContainer recordId={job.id} />
|
||||||
</Tabs.TabPane>
|
// </Tabs.TabPane>
|
||||||
<Tabs.TabPane
|
// <Tabs.TabPane
|
||||||
tab={
|
// tab={
|
||||||
<span>
|
// <span>
|
||||||
<CheckSquareFilled />
|
// <CheckSquareFilled />
|
||||||
{t("jobs.labels.checklists")}
|
// {t("jobs.labels.checklists")}
|
||||||
</span>
|
// </span>
|
||||||
}
|
// }
|
||||||
key="checklists"
|
// key="checklists"
|
||||||
>
|
// >
|
||||||
<JobsDetailChecklists job={job} />
|
// <JobsDetailChecklists job={job} />
|
||||||
</Tabs.TabPane>
|
// </Tabs.TabPane>
|
||||||
|
}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Form>
|
</Form>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|||||||
Reference in New Issue
Block a user