Compare commits
18 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2be0f3de09 | ||
|
|
b791f9846f | ||
|
|
0669282432 | ||
|
|
bf4dc7e158 | ||
|
|
5de2036fdb | ||
|
|
1629663e15 | ||
|
|
e25f2db2b1 | ||
|
|
cbf5d268ea | ||
|
|
a92a95a9fa | ||
|
|
0be7bf2c8e | ||
|
|
56b810dd40 | ||
|
|
000ded6649 | ||
|
|
72181e1ff7 | ||
|
|
d73b1d2220 | ||
|
|
8645b434c8 | ||
|
|
38a13bd082 | ||
|
|
3bc5f5d626 | ||
|
|
86a2351316 |
@@ -156,3 +156,11 @@
|
|||||||
td.ant-table-column-sort {
|
td.ant-table-column-sort {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-table-tbody > tr.ant-table-row:nth-child(2n) > td {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rowWithColor > td {
|
||||||
|
background-color: var(--bgColor) !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import AddToProduction from "./jobs-detail-header-actions.addtoproduction.util";
|
|||||||
import JobsDetaiLheaderCsi from "./jobs-detail-header-actions.csi.component";
|
import JobsDetaiLheaderCsi from "./jobs-detail-header-actions.csi.component";
|
||||||
import DuplicateJob from "./jobs-detail-header-actions.duplicate.util";
|
import DuplicateJob from "./jobs-detail-header-actions.duplicate.util";
|
||||||
import JobsDetailHeaderActionsExportcustdataComponent from "./jobs-detail-header-actions.exportcustdata.component";
|
import JobsDetailHeaderActionsExportcustdataComponent from "./jobs-detail-header-actions.exportcustdata.component";
|
||||||
|
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -461,54 +462,56 @@ export function JobsDetailHeaderActions({
|
|||||||
)}
|
)}
|
||||||
<JobsDetailHeaderActionsAddevent jobid={job.id} />
|
<JobsDetailHeaderActionsAddevent jobid={job.id} />
|
||||||
{!jobRO && job.converted && (
|
{!jobRO && job.converted && (
|
||||||
<Menu.Item>
|
<RbacWrapper action="jobs:void" noauth>
|
||||||
<Popconfirm
|
<Menu.Item>
|
||||||
title={t("jobs.labels.voidjob")}
|
<Popconfirm
|
||||||
okText="Yes"
|
title={t("jobs.labels.voidjob")}
|
||||||
cancelText="No"
|
okText="Yes"
|
||||||
onClick={(e) => e.stopPropagation()}
|
cancelText="No"
|
||||||
onConfirm={async () => {
|
onClick={(e) => e.stopPropagation()}
|
||||||
//delete the job.
|
onConfirm={async () => {
|
||||||
const result = await voidJob({
|
//delete the job.
|
||||||
variables: {
|
const result = await voidJob({
|
||||||
jobId: job.id,
|
variables: {
|
||||||
job: {
|
jobId: job.id,
|
||||||
status: bodyshop.md_ro_statuses.default_void,
|
job: {
|
||||||
voided: true,
|
status: bodyshop.md_ro_statuses.default_void,
|
||||||
scheduled_in: null,
|
voided: true,
|
||||||
scheduled_completion: null,
|
scheduled_in: null,
|
||||||
inproduction: false,
|
scheduled_completion: null,
|
||||||
},
|
inproduction: false,
|
||||||
note: [
|
|
||||||
{
|
|
||||||
jobid: job.id,
|
|
||||||
created_by: currentUser.email,
|
|
||||||
audit: true,
|
|
||||||
text: t("jobs.labels.voidnote"),
|
|
||||||
},
|
},
|
||||||
],
|
note: [
|
||||||
},
|
{
|
||||||
});
|
jobid: job.id,
|
||||||
|
created_by: currentUser.email,
|
||||||
|
audit: true,
|
||||||
|
text: t("jobs.labels.voidnote"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (!!!result.errors) {
|
if (!!!result.errors) {
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("jobs.successes.voided"),
|
message: t("jobs.successes.voided"),
|
||||||
});
|
});
|
||||||
//go back to jobs list.
|
//go back to jobs list.
|
||||||
history.push(`/manage/`);
|
history.push(`/manage/`);
|
||||||
} else {
|
} else {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("jobs.errors.voiding", {
|
message: t("jobs.errors.voiding", {
|
||||||
error: JSON.stringify(result.errors),
|
error: JSON.stringify(result.errors),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
getPopupContainer={(trigger) => trigger.parentNode}
|
getPopupContainer={(trigger) => trigger.parentNode}
|
||||||
>
|
>
|
||||||
{t("menus.jobsactions.void")}
|
{t("menus.jobsactions.void")}
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
</RbacWrapper>
|
||||||
)}
|
)}
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -112,7 +112,9 @@ export function JobsList({ bodyshop }) {
|
|||||||
title: t("jobs.fields.ro_number"),
|
title: t("jobs.fields.ro_number"),
|
||||||
dataIndex: "ro_number",
|
dataIndex: "ro_number",
|
||||||
key: "ro_number",
|
key: "ro_number",
|
||||||
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
|
sorter: (a, b) =>
|
||||||
|
parseInt((a.ro_number || "0").replace(/\D/g, "")) -
|
||||||
|
parseInt((b.ro_number || "0").replace(/\D/g, "")),
|
||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
|
||||||
|
|
||||||
|
|||||||
@@ -23,17 +23,34 @@ export function PrintCenterJobsComponent({ printCenterModal, bodyshop }) {
|
|||||||
const { id: jobId, job } = printCenterModal.context;
|
const { id: jobId, job } = printCenterModal.context;
|
||||||
const tempList = TemplateList("job", {});
|
const tempList = TemplateList("job", {});
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const JobsReportsList = Object.keys(tempList)
|
|
||||||
.map((key) => {
|
const JobsReportsList =
|
||||||
return tempList[key];
|
bodyshop.cdk_dealerid === null && bodyshop.pbs_serialnumber === null
|
||||||
})
|
? Object.keys(tempList)
|
||||||
.filter(
|
.map((key) => {
|
||||||
(temp) =>
|
return tempList[key];
|
||||||
!temp.regions ||
|
})
|
||||||
(temp.regions && temp.regions[bodyshop.region_config]) ||
|
.filter(
|
||||||
(temp.regions &&
|
(temp) =>
|
||||||
bodyshop.region_config.includes(Object.keys(temp.regions)) === true)
|
(!temp.regions ||
|
||||||
);
|
(temp.regions && temp.regions[bodyshop.region_config]) ||
|
||||||
|
(temp.regions &&
|
||||||
|
bodyshop.region_config.includes(Object.keys(temp.regions)) ===
|
||||||
|
true)) &&
|
||||||
|
(!temp.dms || temp.dms === false)
|
||||||
|
)
|
||||||
|
: Object.keys(tempList)
|
||||||
|
.map((key) => {
|
||||||
|
return tempList[key];
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
(temp) =>
|
||||||
|
!temp.regions ||
|
||||||
|
(temp.regions && temp.regions[bodyshop.region_config]) ||
|
||||||
|
(temp.regions &&
|
||||||
|
bodyshop.region_config.includes(Object.keys(temp.regions)) ===
|
||||||
|
true)
|
||||||
|
);
|
||||||
|
|
||||||
const filteredJobsReportsList =
|
const filteredJobsReportsList =
|
||||||
search !== ""
|
search !== ""
|
||||||
|
|||||||
@@ -246,11 +246,21 @@ export function ProductionListTable({
|
|||||||
(x) => x.status === record.status
|
(x) => x.status === record.status
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!color) return null;
|
if (!color) {
|
||||||
|
if (index % 2 === 0)
|
||||||
|
return {
|
||||||
|
style: {
|
||||||
|
backgroundColor: `rgb(236, 236, 236)`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
className: "rowWithColor",
|
||||||
style: {
|
style: {
|
||||||
backgroundColor: `rgb(${color.color.r},${color.color.g},${color.color.b},${color.color.a})`,
|
"--bgColor": `rgb(${color.color.r},${color.color.g},${color.color.b},${color.color.a})`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ const ret = {
|
|||||||
"jobs:partsqueue": 4,
|
"jobs:partsqueue": 4,
|
||||||
"jobs:checklist-view": 2,
|
"jobs:checklist-view": 2,
|
||||||
"jobs:list-ready": 1,
|
"jobs:list-ready": 1,
|
||||||
|
"jobs:void": 5,
|
||||||
|
|
||||||
"bills:enter": 2,
|
"bills:enter": 2,
|
||||||
"bills:view": 2,
|
"bills:view": 2,
|
||||||
"bills:list": 2,
|
"bills:list": 2,
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import "./schedule-calendar.styles.scss";
|
|||||||
import JobDetailCards from "../job-detail-cards/job-detail-cards.component";
|
import JobDetailCards from "../job-detail-cards/job-detail-cards.component";
|
||||||
import { selectProblemJobs } from "../../redux/application/application.selectors";
|
import { selectProblemJobs } from "../../redux/application/application.selectors";
|
||||||
import { Alert, Collapse } from "antd";
|
import { Alert, Collapse } from "antd";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation, Trans } from "react-i18next";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -66,10 +67,21 @@ export function ScheduleCalendarWrapperComponent({
|
|||||||
<Alert
|
<Alert
|
||||||
key={problem.id}
|
key={problem.id}
|
||||||
type="error"
|
type="error"
|
||||||
message={t("appointments.labels.dataconsistency", {
|
message={
|
||||||
ro_number: problem.ro_number,
|
<Trans
|
||||||
code: problem.code,
|
i18nKey="appointments.labels.dataconsistency"
|
||||||
})}
|
components={[
|
||||||
|
<Link
|
||||||
|
to={`/manage/jobs/${problem.id}`}
|
||||||
|
target="_blank"
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
values={{
|
||||||
|
ro_number: problem.ro_number,
|
||||||
|
code: problem.code,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Collapse.Panel>
|
</Collapse.Panel>
|
||||||
@@ -79,10 +91,18 @@ export function ScheduleCalendarWrapperComponent({
|
|||||||
<Alert
|
<Alert
|
||||||
key={problem.id}
|
key={problem.id}
|
||||||
type="error"
|
type="error"
|
||||||
message={t("appointments.labels.dataconsistency", {
|
message={
|
||||||
ro_number: problem.ro_number,
|
<Trans
|
||||||
code: problem.code,
|
i18nKey="appointments.labels.dataconsistency"
|
||||||
})}
|
components={[
|
||||||
|
<Link to={`/manage/jobs/${problem.id}`} target="_blank" />,
|
||||||
|
]}
|
||||||
|
values={{
|
||||||
|
ro_number: problem.ro_number,
|
||||||
|
code: problem.code,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Form, InputNumber } from "antd";
|
import { Form, InputNumber } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
|
||||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
|
||||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
});
|
});
|
||||||
@@ -316,6 +316,18 @@ export function ShopInfoRbacComponent({ form, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<InputNumber />
|
<InputNumber />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.rbac.jobs.void")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={["md_rbac", "jobs:void"]}
|
||||||
|
>
|
||||||
|
<InputNumber />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.rbac.bills.enter")}
|
label={t("bodyshop.fields.rbac.bills.enter")}
|
||||||
rules={[
|
rules={[
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export function TechClockInComponent({ form, bodyshop, technician }) {
|
|||||||
<JobSearchSelect
|
<JobSearchSelect
|
||||||
convertedOnly={!bodyshop.tt_allow_post_to_invoiced}
|
convertedOnly={!bodyshop.tt_allow_post_to_invoiced}
|
||||||
notExported={!bodyshop.tt_allow_post_to_invoiced}
|
notExported={!bodyshop.tt_allow_post_to_invoiced}
|
||||||
|
notInvoiced={!bodyshop.tt_allow_post_to_invoiced}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import { Alert, Button, Space } from "antd";
|
||||||
|
import i18n from "i18next";
|
||||||
|
import React from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectUpdateAvailable } from "../../redux/application/application.selectors";
|
||||||
|
import { AlertOutlined } from "@ant-design/icons";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { setUpdateAvailable } from "../../redux/application/application.actions";
|
||||||
|
import { store } from "../../redux/store";
|
||||||
|
import * as serviceWorkerRegistration from "../../serviceWorkerRegistration";
|
||||||
|
|
||||||
|
let globalRegistration;
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
updateAvailable: selectUpdateAvailable,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(UpdateAlert);
|
||||||
|
|
||||||
|
export function UpdateAlert({ updateAvailable }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
if (!updateAvailable) return null;
|
||||||
|
return (
|
||||||
|
<Alert
|
||||||
|
message={t("general.messages.newversiontitle")}
|
||||||
|
showIcon
|
||||||
|
icon={<AlertOutlined />}
|
||||||
|
description={t("general.messages.newversionmessage")}
|
||||||
|
closable={false}
|
||||||
|
type="warning"
|
||||||
|
action={
|
||||||
|
<Space flex>
|
||||||
|
<Button
|
||||||
|
onClick={async () => {
|
||||||
|
window.open("https://imex-online.noticeable.news/", "_blank");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18n.t("general.actions.viewreleasenotes")}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={async () => {
|
||||||
|
if (globalRegistration && globalRegistration.waiting) {
|
||||||
|
await globalRegistration.unregister();
|
||||||
|
// Makes Workbox call skipWaiting()
|
||||||
|
globalRegistration.waiting.postMessage({
|
||||||
|
type: "SKIP_WAITING",
|
||||||
|
});
|
||||||
|
// Once the service worker is unregistered, we can reload the page to let
|
||||||
|
// the browser download a fresh copy of our app (invalidating the cache)
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18n.t("general.actions.refresh")}
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const onServiceWorkerUpdate = (registration) => {
|
||||||
|
console.log("onServiceWorkerUpdate", registration);
|
||||||
|
globalRegistration = registration;
|
||||||
|
store.dispatch(setUpdateAvailable(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
serviceWorkerRegistration.register({ onUpdate: onServiceWorkerUpdate });
|
||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
import * as Sentry from "@sentry/react";
|
import * as Sentry from "@sentry/react";
|
||||||
|
|
||||||
import "./manage.page.styles.scss";
|
import "./manage.page.styles.scss";
|
||||||
|
import UpdateAlert from "../../components/update-alert/update-alert.component";
|
||||||
|
|
||||||
const ManageRootPage = lazy(() =>
|
const ManageRootPage = lazy(() =>
|
||||||
import("../manage-root/manage-root.page.container")
|
import("../manage-root/manage-root.page.container")
|
||||||
@@ -394,6 +395,7 @@ export function Manage({ match, conflict, bodyshop }) {
|
|||||||
<>
|
<>
|
||||||
<ChatAffixContainer />
|
<ChatAffixContainer />
|
||||||
<Layout className="layout-container">
|
<Layout className="layout-container">
|
||||||
|
<UpdateAlert />
|
||||||
<HeaderContainer />
|
<HeaderContainer />
|
||||||
|
|
||||||
<Content className="content-container">
|
<Content className="content-container">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import AlertComponent from "../../components/alert/alert.component";
|
|||||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||||
import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
|
import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
|
||||||
import { setBodyshop } from "../../redux/user/user.actions";
|
import { setBodyshop } from "../../redux/user/user.actions";
|
||||||
import "../../utils/RegisterSw";
|
//import "../../utils/RegisterSw";
|
||||||
import ManagePage from "./manage.page.component";
|
import ManagePage from "./manage.page.component";
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import TechSider from "../../components/tech-sider/tech-sider.component";
|
|||||||
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
import FeatureWrapper from "../../components/feature-wrapper/feature-wrapper.component";
|
import FeatureWrapper from "../../components/feature-wrapper/feature-wrapper.component";
|
||||||
import "./tech.page.styles.scss";
|
import "./tech.page.styles.scss";
|
||||||
|
import UpdateAlert from "../../components/update-alert/update-alert.component";
|
||||||
const TimeTicketModalContainer = lazy(() =>
|
const TimeTicketModalContainer = lazy(() =>
|
||||||
import("../../components/time-ticket-modal/time-ticket-modal.container")
|
import("../../components/time-ticket-modal/time-ticket-modal.container")
|
||||||
);
|
);
|
||||||
@@ -56,7 +57,9 @@ export function TechPage({ technician, match }) {
|
|||||||
<TechSider />
|
<TechSider />
|
||||||
<Layout>
|
<Layout>
|
||||||
{technician ? null : <Redirect to={`${match.path}/login`} />}
|
{technician ? null : <Redirect to={`${match.path}/login`} />}
|
||||||
|
<UpdateAlert />
|
||||||
<TechHeader />
|
<TechHeader />
|
||||||
|
|
||||||
<Content className="tech-content-container">
|
<Content className="tech-content-container">
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<Suspense
|
<Suspense
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import LoadingSpinner from "../../components/loading-spinner/loading-spinner.com
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import "../../utils/RegisterSw";
|
//import "../../utils/RegisterSw";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
|
|||||||
@@ -62,3 +62,8 @@ export const setProblemJobs = (problemJobs) => ({
|
|||||||
type: ApplicationActionTypes.SET_PROBLEM_JOBS,
|
type: ApplicationActionTypes.SET_PROBLEM_JOBS,
|
||||||
payload: problemJobs,
|
payload: problemJobs,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const setUpdateAvailable = (isUpdateAvailable) => ({
|
||||||
|
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
|
||||||
|
payload: isUpdateAvailable,
|
||||||
|
});
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import ApplicationActionTypes from "./application.types";
|
|||||||
const INITIAL_STATE = {
|
const INITIAL_STATE = {
|
||||||
loading: false,
|
loading: false,
|
||||||
online: true,
|
online: true,
|
||||||
|
updateAvailable: false,
|
||||||
breadcrumbs: [],
|
breadcrumbs: [],
|
||||||
recentItems: [],
|
recentItems: [],
|
||||||
selectedHeader: "home",
|
selectedHeader: "home",
|
||||||
@@ -18,6 +19,11 @@ const INITIAL_STATE = {
|
|||||||
|
|
||||||
const applicationReducer = (state = INITIAL_STATE, action) => {
|
const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
case ApplicationActionTypes.SET_UPDATE_AVAILABLE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
updateAvailable: action.payload,
|
||||||
|
};
|
||||||
case ApplicationActionTypes.SET_SELECTED_HEADER:
|
case ApplicationActionTypes.SET_SELECTED_HEADER:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|||||||
@@ -48,3 +48,7 @@ export const selectProblemJobs = createSelector(
|
|||||||
[selectApplication],
|
[selectApplication],
|
||||||
(application) => application.problemJobs
|
(application) => application.problemJobs
|
||||||
);
|
);
|
||||||
|
export const selectUpdateAvailable = createSelector(
|
||||||
|
[selectApplication],
|
||||||
|
(application) => application.updateAvailable
|
||||||
|
);
|
||||||
|
|||||||
@@ -12,5 +12,6 @@ const ApplicationActionTypes = {
|
|||||||
SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
|
SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
|
||||||
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
|
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
|
||||||
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
|
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
|
||||||
|
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE"
|
||||||
};
|
};
|
||||||
export default ApplicationActionTypes;
|
export default ApplicationActionTypes;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
"blocked": "Blocked",
|
"blocked": "Blocked",
|
||||||
"cancelledappointment": "Canceled appointment for: ",
|
"cancelledappointment": "Canceled appointment for: ",
|
||||||
"completingjobs": "Completing Jobs",
|
"completingjobs": "Completing Jobs",
|
||||||
"dataconsistency": "{{ro_number}} has a data consistency issue. It may have been excluded for scheduling purposes. CODE: {{code}}.",
|
"dataconsistency": "<0>{{ro_number}}</0> has a data consistency issue. It may have been excluded for scheduling purposes. CODE: {{code}}.",
|
||||||
"expectedjobs": "Expected Jobs in Production: ",
|
"expectedjobs": "Expected Jobs in Production: ",
|
||||||
"expectedprodhrs": "Expected Production Hours:",
|
"expectedprodhrs": "Expected Production Hours:",
|
||||||
"history": "History",
|
"history": "History",
|
||||||
@@ -405,7 +405,8 @@
|
|||||||
"list-active": "Jobs -> List Active",
|
"list-active": "Jobs -> List Active",
|
||||||
"list-all": "Jobs -> List All",
|
"list-all": "Jobs -> List All",
|
||||||
"list-ready": "Jobs -> List Ready",
|
"list-ready": "Jobs -> List Ready",
|
||||||
"partsqueue": "Jobs -> Parts Queue"
|
"partsqueue": "Jobs -> Parts Queue",
|
||||||
|
"void": "Jobs -> Void"
|
||||||
},
|
},
|
||||||
"owners": {
|
"owners": {
|
||||||
"detail": "Owners -> Detail",
|
"detail": "Owners -> Detail",
|
||||||
@@ -1117,7 +1118,7 @@
|
|||||||
},
|
},
|
||||||
"messages": {
|
"messages": {
|
||||||
"exception": "$t(titles.app) has encountered an error. Please try again. If the problem persists, please submit a support ticket or contact us.",
|
"exception": "$t(titles.app) has encountered an error. Please try again. If the problem persists, please submit a support ticket or contact us.",
|
||||||
"newversionmessage": "Click refresh below to update to the latest available version of ImEX Online. Please make sure all other tabs and windows are closed.",
|
"newversionmessage": "Click refresh to update to the latest available version of ImEX Online. Please make sure all other tabs and windows are closed.",
|
||||||
"newversiontitle": "New version of ImEX Online Available",
|
"newversiontitle": "New version of ImEX Online Available",
|
||||||
"noacctfilepath": "There is no accounting file path set. You will not be able to export any items.",
|
"noacctfilepath": "There is no accounting file path set. You will not be able to export any items.",
|
||||||
"nofeatureaccess": "You do not have access to this feature of ImEX Online. Please contact support to request a license for this feature.",
|
"nofeatureaccess": "You do not have access to this feature of ImEX Online. Please contact support to request a license for this feature.",
|
||||||
|
|||||||
@@ -405,7 +405,8 @@
|
|||||||
"list-active": "",
|
"list-active": "",
|
||||||
"list-all": "",
|
"list-all": "",
|
||||||
"list-ready": "",
|
"list-ready": "",
|
||||||
"partsqueue": ""
|
"partsqueue": "",
|
||||||
|
"void": ""
|
||||||
},
|
},
|
||||||
"owners": {
|
"owners": {
|
||||||
"detail": "",
|
"detail": "",
|
||||||
|
|||||||
@@ -405,7 +405,8 @@
|
|||||||
"list-active": "",
|
"list-active": "",
|
||||||
"list-all": "",
|
"list-all": "",
|
||||||
"list-ready": "",
|
"list-ready": "",
|
||||||
"partsqueue": ""
|
"partsqueue": "",
|
||||||
|
"void": ""
|
||||||
},
|
},
|
||||||
"owners": {
|
"owners": {
|
||||||
"detail": "",
|
"detail": "",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Button, notification, Space } from "antd";
|
|||||||
import i18n from "i18next";
|
import i18n from "i18next";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import * as serviceWorkerRegistration from "../serviceWorkerRegistration";
|
import * as serviceWorkerRegistration from "../serviceWorkerRegistration";
|
||||||
|
import { store } from "../redux/store";
|
||||||
|
|
||||||
const onServiceWorkerUpdate = (registration) => {
|
const onServiceWorkerUpdate = (registration) => {
|
||||||
console.log("onServiceWorkerUpdate", registration);
|
console.log("onServiceWorkerUpdate", registration);
|
||||||
@@ -33,6 +34,9 @@ const onServiceWorkerUpdate = (registration) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
store.dispatch()
|
||||||
|
|
||||||
notification.open({
|
notification.open({
|
||||||
icon: <AlertOutlined />,
|
icon: <AlertOutlined />,
|
||||||
message: i18n.t("general.messages.newversiontitle"),
|
message: i18n.t("general.messages.newversiontitle"),
|
||||||
|
|||||||
@@ -512,6 +512,7 @@ export const TemplateList = (type, context) => {
|
|||||||
key: "dms_posting_sheet",
|
key: "dms_posting_sheet",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "financial",
|
group: "financial",
|
||||||
|
dms: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
|
|||||||
@@ -729,9 +729,15 @@ async function InsertDmsVehicle(socket) {
|
|||||||
deliveryDate: moment()
|
deliveryDate: moment()
|
||||||
// .tz(socket.JobData.bodyshop.timezone)
|
// .tz(socket.JobData.bodyshop.timezone)
|
||||||
.format("YYYYMMDD"),
|
.format("YYYYMMDD"),
|
||||||
licensePlateNo: String(socket.JobData.plate_no)
|
licensePlateNo:
|
||||||
.replace(/([^\w]|_)/g, "")
|
socket.JobData.plate_no === null
|
||||||
.toUpperCase(),
|
? null
|
||||||
|
: String(socket.JobData.plate_no).replace(/([^\w]|_)/g, "")
|
||||||
|
.length === 0
|
||||||
|
? null
|
||||||
|
: String(socket.JobData.plate_no)
|
||||||
|
.replace(/([^\w]|_)/g, "")
|
||||||
|
.toUpperCase(),
|
||||||
make: socket.txEnvelope.dms_make,
|
make: socket.txEnvelope.dms_make,
|
||||||
modelAbrev: socket.txEnvelope.dms_model,
|
modelAbrev: socket.txEnvelope.dms_model,
|
||||||
modelYear: socket.JobData.v_model_yr,
|
modelYear: socket.JobData.v_model_yr,
|
||||||
|
|||||||
Reference in New Issue
Block a user