Release/2025 01 10 IO-3069 IO-3067 IO-3070
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { EditFilled, SyncOutlined } from "@ant-design/icons";
|
import { EditFilled, SyncOutlined } from "@ant-design/icons";
|
||||||
import { Button, Card, Checkbox, Input, Space, Table } from "antd";
|
import { Button, Card, Checkbox, Input, Space, Table } from "antd";
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FaTasks } from "react-icons/fa";
|
import { FaTasks } from "react-icons/fa";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -17,8 +17,7 @@ import BillDetailEditReturnComponent from "../bill-detail-edit/bill-detail-edit-
|
|||||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||||
import LockerWrapperComponent from "../lock-wrapper/lock-wrapper.component";
|
import LockerWrapperComponent from "../lock-wrapper/lock-wrapper.component";
|
||||||
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
|
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
|
||||||
import UpsellComponent from "../upsell/upsell.component";
|
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
||||||
import { upsellEnum } from "../upsell/upsell.component";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
jobRO: selectJobReadOnly,
|
jobRO: selectJobReadOnly,
|
||||||
@@ -61,7 +60,6 @@ export function BillsListTableComponent({
|
|||||||
// const search = queryString.parse(useLocation().search);
|
// const search = queryString.parse(useLocation().search);
|
||||||
// const selectedBill = search.billid;
|
// const selectedBill = search.billid;
|
||||||
const [searchText, setSearchText] = useState("");
|
const [searchText, setSearchText] = useState("");
|
||||||
const containerRef = useRef(null);
|
|
||||||
|
|
||||||
const Templates = TemplateList("bill");
|
const Templates = TemplateList("bill");
|
||||||
const bills = billsQuery.data ? billsQuery.data.bills : [];
|
const bills = billsQuery.data ? billsQuery.data.bills : [];
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ function Header({
|
|||||||
label: (
|
label: (
|
||||||
<Space>
|
<Space>
|
||||||
<LockWrapper featureName="bills" bodyshop={bodyshop}>
|
<LockWrapper featureName="bills" bodyshop={bodyshop}>
|
||||||
{t(t("menus.header.enterbills"))}
|
{t("menus.header.enterbills")}
|
||||||
</LockWrapper>
|
</LockWrapper>
|
||||||
</Space>
|
</Space>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ export function JobDetailCards({ bodyshop, setPrintCenterContext }) {
|
|||||||
</Col>
|
</Col>
|
||||||
{!bodyshop.uselocalmediaserver && (
|
{!bodyshop.uselocalmediaserver && (
|
||||||
<Col {...span}>
|
<Col {...span}>
|
||||||
<JobDetailCardsDocumentsComponent loading={loading} data={data ? data.jobs_by_pk : null} />
|
<JobDetailCardsDocumentsComponent loading={loading} data={data ? data.jobs_by_pk : null} bodyshop={bodyshop} />
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
<Col {...span}>
|
<Col {...span}>
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { Carousel } from "antd";
|
import { Carousel } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||||
import { GenerateThumbUrl } from "../jobs-documents-gallery/job-documents.utility";
|
import { GenerateThumbUrl } from "../jobs-documents-gallery/job-documents.utility";
|
||||||
import CardTemplate from "./job-detail-cards.template.component";
|
|
||||||
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
||||||
|
import CardTemplate from "./job-detail-cards.template.component";
|
||||||
|
|
||||||
export default function JobDetailCardsDocumentsComponent({ loading, data }) {
|
export default function JobDetailCardsDocumentsComponent({ loading, data, bodyshop }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const hasMediaAccess = HasFeatureAccess({ bodyshop, featureName: "media" });
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return (
|
return (
|
||||||
@@ -21,17 +23,19 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
|
|||||||
title={t("jobs.labels.cards.documents")}
|
title={t("jobs.labels.cards.documents")}
|
||||||
extraLink={`/manage/jobs/${data.id}?tab=documents`}
|
extraLink={`/manage/jobs/${data.id}?tab=documents`}
|
||||||
>
|
>
|
||||||
<UpsellComponent disableMask upsell={upsellEnum().media.general}>
|
{!hasMediaAccess && (
|
||||||
{data.documents.length > 0 ? (
|
<UpsellComponent disableMask upsell={upsellEnum().media.general}>
|
||||||
<Carousel autoplay>
|
{data.documents.length > 0 ? (
|
||||||
{data.documents.map((item) => (
|
<Carousel autoplay>
|
||||||
<img key={item.id} src={GenerateThumbUrl(item)} alt={item.name} />
|
{data.documents.map((item) => (
|
||||||
))}
|
<img key={item.id} src={GenerateThumbUrl(item)} alt={item.name} />
|
||||||
</Carousel>
|
))}
|
||||||
) : (
|
</Carousel>
|
||||||
<div>{t("documents.errors.nodocuments")}</div>
|
) : (
|
||||||
)}
|
<div>{t("documents.errors.nodocuments")}</div>
|
||||||
</UpsellComponent>
|
)}
|
||||||
|
</UpsellComponent>
|
||||||
|
)}
|
||||||
</CardTemplate>
|
</CardTemplate>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,25 @@ import { useTranslation } from "react-i18next";
|
|||||||
|
|
||||||
import "./job-lifecycle.styles.scss";
|
import "./job-lifecycle.styles.scss";
|
||||||
import BlurWrapperComponent from "../feature-wrapper/blur-wrapper.component";
|
import BlurWrapperComponent from "../feature-wrapper/blur-wrapper.component";
|
||||||
|
|
||||||
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
||||||
|
|
||||||
|
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
// show text on bar if text can fit
|
// show text on bar if text can fit
|
||||||
export function JobLifecycleComponent({ job, statuses, ...rest }) {
|
export function JobLifecycleComponent({ bodyshop, job, statuses, ...rest }) {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [lifecycleData, setLifecycleData] = useState(null);
|
const [lifecycleData, setLifecycleData] = useState(null);
|
||||||
const { t } = useTranslation(); // Used for tracking external state changes.
|
const { t } = useTranslation(); // Used for tracking external state changes.
|
||||||
|
const hasLifeCycleAccess = HasFeatureAccess({ bodyshop, featureName: "lifecycle" });
|
||||||
const { data } = useQuery(
|
const { data } = useQuery(
|
||||||
gql`
|
gql`
|
||||||
query get_job_test($id: uuid!) {
|
query get_job_test($id: uuid!) {
|
||||||
@@ -143,9 +154,11 @@ export function JobLifecycleComponent({ job, statuses, ...rest }) {
|
|||||||
}
|
}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
>
|
>
|
||||||
<Card type="inner" style={{ marginTop: "10px" }}>
|
{!hasLifeCycleAccess && (
|
||||||
<UpsellComponent upsell={upsellEnum().lifecycle.general} />
|
<Card type="inner" style={{ marginTop: "10px" }}>
|
||||||
</Card>
|
<UpsellComponent upsell={upsellEnum().lifecycle.general} />
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
<BlurWrapperComponent featureName="lifecycle" bypass>
|
<BlurWrapperComponent featureName="lifecycle" bypass>
|
||||||
<div
|
<div
|
||||||
id="bar-container"
|
id="bar-container"
|
||||||
@@ -302,5 +315,4 @@ export function JobLifecycleComponent({ job, statuses, ...rest }) {
|
|||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(JobLifecycleComponent);
|
||||||
export default JobLifecycleComponent;
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ import { selectScheduleLoad, selectScheduleLoadCalculating } from "../../redux/a
|
|||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||||
import { default as BlurWrapper, default as BlurWrapperComponent } from "../feature-wrapper/blur-wrapper.component";
|
import { default as BlurWrapper, default as BlurWrapperComponent } from "../feature-wrapper/blur-wrapper.component";
|
||||||
|
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||||
import ScheduleBlockDay from "../schedule-block-day/schedule-block-day.component";
|
import ScheduleBlockDay from "../schedule-block-day/schedule-block-day.component";
|
||||||
|
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
|
||||||
import ScheduleCalendarHeaderGraph from "./schedule-calendar-header-graph.component";
|
import ScheduleCalendarHeaderGraph from "./schedule-calendar-header-graph.component";
|
||||||
import UpsellComponent, { upsellEnum, UpsellMaskWrapper } from "../upsell/upsell.component";
|
|
||||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import { Button, Card, Result } from "antd";
|
|||||||
import i18n from "i18next";
|
import i18n from "i18next";
|
||||||
import React, { useEffect, useRef } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { store } from "../../redux/store.js";
|
||||||
|
import InstanceRenderManager from "../../utils/instanceRenderMgr.js";
|
||||||
import "./upsell.styles.scss";
|
import "./upsell.styles.scss";
|
||||||
|
|
||||||
export default function UpsellComponent({ featureName, subFeatureName, upsell, disableMask }) {
|
export default function UpsellComponent({ featureName, subFeatureName, upsell, disableMask }) {
|
||||||
@@ -64,174 +67,275 @@ export function UpsellMaskWrapper({ children, upsell, featureName, subFeatureNam
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is kept in this function as pulling it out into it's own util/enum prevents passing JSX as an `extra` prop
|
//This is kept in this function as pulling it out into it's own util/enum prevents passing JSX as an `extra` prop
|
||||||
export const upsellEnum = () => ({
|
export const upsellEnum = () => {
|
||||||
bills: {
|
const { currentUser, bodyshop } = store.getState().user;
|
||||||
autoreconcile: {
|
|
||||||
//icon: null,
|
const [first_name, ...last_name] = currentUser?.displayName ? currentUser.displayName.split(" ") : [];
|
||||||
title: i18n.t("upsell.messages.bills.autoreconcile.title"),
|
const LearnMoreLink = encodeURI(
|
||||||
subTitle: i18n.t("upsell.messages.bills.autoreconcile.subtitle"),
|
InstanceRenderManager({
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
imex: `https://imexsystems.ca/schedule-a-demo/`,
|
||||||
//status: null
|
rome: `https://forms.zohopublic.com/rometech/form/ROLearnMore/formperma/0G29z8LgLlvKK8nno-b7s-GHgNXwIFlrMeE0mC394L4?first_name=${first_name || ""}&last_name=${last_name.join(" ") || ""}&shop_name=${bodyshop?.shopname || ""}&email=${currentUser?.email || ""}&shop_phone=${bodyshop?.phone || ""}`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
bills: {
|
||||||
|
autoreconcile: {
|
||||||
|
//icon: null,
|
||||||
|
title: i18n.t("upsell.messages.bills.autoreconcile.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.bills.autoreconcile.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
//status: null
|
||||||
|
},
|
||||||
|
general: {
|
||||||
|
//icon: null,
|
||||||
|
title: i18n.t("upsell.messages.bills.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.bills.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
//status: null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
general: {
|
checklist: {
|
||||||
//icon: null,
|
general: {
|
||||||
title: i18n.t("upsell.messages.bills.general.title"),
|
//icon: null,
|
||||||
subTitle: i18n.t("upsell.messages.bills.general.subtitle"),
|
title: i18n.t("upsell.messages.checklist.general.title"),
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
subTitle: i18n.t("upsell.messages.checklist.general.subtitle"),
|
||||||
//status: null
|
extra: (
|
||||||
}
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
},
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
checklist: {
|
</Link>
|
||||||
general: {
|
)
|
||||||
//icon: null,
|
//status: null
|
||||||
title: i18n.t("upsell.messages.checklist.general.title"),
|
}
|
||||||
subTitle: i18n.t("upsell.messages.checklist.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
//status: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
payments: {
|
|
||||||
general: {
|
|
||||||
//icon: null,
|
|
||||||
title: i18n.t("upsell.messages.payments.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.payments.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
//status: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
audit: {
|
|
||||||
general: {
|
|
||||||
//icon: null,
|
|
||||||
title: i18n.t("upsell.messages.audit.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.audit.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
//status: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
lifecycle: {
|
|
||||||
general: {
|
|
||||||
//icon: null,
|
|
||||||
title: i18n.t("upsell.messages.lifecycle.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.lifecycle.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
//status: null }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
media: {
|
|
||||||
general: {
|
|
||||||
//icon: null,
|
|
||||||
title: i18n.t("upsell.messages.media.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.media.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
//status: null }
|
|
||||||
},
|
|
||||||
mobile: {
|
|
||||||
icon: <MobileOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.media.mobile.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.media.mobile.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
//status: null }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timetickets: {
|
|
||||||
allocations: {
|
|
||||||
title: i18n.t("upsell.messages.timetickets.allocations.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.timetickets.allocations.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
},
|
|
||||||
general: {
|
|
||||||
title: i18n.t("upsell.messages.timetickets.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.timetickets.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
smartscheduling: {
|
|
||||||
general: {
|
|
||||||
icon: <CalendarOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.smartscheduling.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.smartscheduling.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
},
|
|
||||||
hrsdelta: {
|
|
||||||
icon: <CarOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.smartscheduling.hrsdelta.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.smartscheduling.hrsdelta.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
},
|
|
||||||
datepicker: {
|
|
||||||
icon: <CarOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.smartscheduling.datepicker.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.smartscheduling.datepicker.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
accounting: {
|
|
||||||
payables: {
|
|
||||||
icon: <DollarOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.accounting.payables.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.accounting.payables.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
},
|
|
||||||
receivables: {
|
|
||||||
icon: <DollarOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.accounting.receivables.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.accounting.receivables.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
},
|
},
|
||||||
payments: {
|
payments: {
|
||||||
icon: <DollarOutlined />,
|
general: {
|
||||||
title: i18n.t("upsell.messages.accounting.payments.title"),
|
//icon: null,
|
||||||
subTitle: i18n.t("upsell.messages.accounting.payments.subtitle"),
|
title: i18n.t("upsell.messages.payments.general.title"),
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
subTitle: i18n.t("upsell.messages.payments.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
//status: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
audit: {
|
||||||
|
general: {
|
||||||
|
//icon: null,
|
||||||
|
title: i18n.t("upsell.messages.audit.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.audit.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
//status: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lifecycle: {
|
||||||
|
general: {
|
||||||
|
//icon: null,
|
||||||
|
title: i18n.t("upsell.messages.lifecycle.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.lifecycle.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
//status: null }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
media: {
|
||||||
|
general: {
|
||||||
|
//icon: null,
|
||||||
|
title: i18n.t("upsell.messages.media.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.media.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
//status: null }
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
icon: <MobileOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.media.mobile.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.media.mobile.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
//status: null }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timetickets: {
|
||||||
|
allocations: {
|
||||||
|
title: i18n.t("upsell.messages.timetickets.allocations.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.timetickets.allocations.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
general: {
|
||||||
|
title: i18n.t("upsell.messages.timetickets.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.timetickets.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
smartscheduling: {
|
||||||
|
general: {
|
||||||
|
icon: <CalendarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.smartscheduling.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.smartscheduling.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
hrsdelta: {
|
||||||
|
icon: <CarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.smartscheduling.hrsdelta.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.smartscheduling.hrsdelta.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
datepicker: {
|
||||||
|
icon: <CarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.smartscheduling.datepicker.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.smartscheduling.datepicker.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
accounting: {
|
||||||
|
payables: {
|
||||||
|
icon: <DollarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.accounting.payables.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.accounting.payables.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
receivables: {
|
||||||
|
icon: <DollarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.accounting.receivables.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.accounting.receivables.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
payments: {
|
||||||
|
icon: <DollarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.accounting.payments.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.accounting.payments.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
courtesycars: {
|
||||||
|
general: {
|
||||||
|
icon: <CarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.courtesycars.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.courtesycars.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dashboard: {
|
||||||
|
general: {
|
||||||
|
icon: <DashboardOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.dashboard.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.dashboard.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
visualboard: {
|
||||||
|
general: {
|
||||||
|
icon: <BuildOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.visualboard.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.visualboard.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scoreboard: {
|
||||||
|
general: {
|
||||||
|
icon: <LineChartOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.scoreboard.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.scoreboard.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
techconsole: {
|
||||||
|
general: {
|
||||||
|
icon: <LineChartOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.techconsole.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.techconsole.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
csi: {
|
||||||
|
general: {
|
||||||
|
icon: <StarOutlined />,
|
||||||
|
title: i18n.t("upsell.messages.csi.general.title"),
|
||||||
|
subTitle: i18n.t("upsell.messages.csi.general.subtitle"),
|
||||||
|
extra: (
|
||||||
|
<Link to={LearnMoreLink} target="_blank">
|
||||||
|
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
courtesycars: {
|
};
|
||||||
general: {
|
|
||||||
icon: <CarOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.courtesycars.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.courtesycars.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dashboard: {
|
|
||||||
general: {
|
|
||||||
icon: <DashboardOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.dashboard.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.dashboard.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
visualboard: {
|
|
||||||
general: {
|
|
||||||
icon: <BuildOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.visualboard.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.visualboard.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scoreboard: {
|
|
||||||
general: {
|
|
||||||
icon: <LineChartOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.scoreboard.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.scoreboard.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
techconsole: {
|
|
||||||
general: {
|
|
||||||
icon: <LineChartOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.techconsole.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.techconsole.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
csi: {
|
|
||||||
general: {
|
|
||||||
icon: <StarOutlined />,
|
|
||||||
title: i18n.t("upsell.messages.csi.general.title"),
|
|
||||||
subTitle: i18n.t("upsell.messages.csi.general.subtitle"),
|
|
||||||
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import { FaHardHat, FaRegStickyNote, FaShieldAlt, FaTasks } from "react-icons/fa
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { HasFeatureAccess } from "../../components/feature-wrapper/feature-wrapper.component";
|
|
||||||
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 JobAuditTrail from "../../components/job-audit-trail/job-audit-trail.component";
|
import JobAuditTrail from "../../components/job-audit-trail/job-audit-trail.component";
|
||||||
import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container";
|
import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container";
|
||||||
@@ -42,6 +41,7 @@ import JobsDetailTotals from "../../components/jobs-detail-totals/jobs-detail-to
|
|||||||
import JobsDocumentsGalleryContainer from "../../components/jobs-documents-gallery/jobs-documents-gallery.container";
|
import JobsDocumentsGalleryContainer from "../../components/jobs-documents-gallery/jobs-documents-gallery.container";
|
||||||
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
||||||
import JobNotesContainer from "../../components/jobs-notes/jobs-notes.container";
|
import JobNotesContainer from "../../components/jobs-notes/jobs-notes.container";
|
||||||
|
import LockWrapperComponent from "../../components/lock-wrapper/lock-wrapper.component.jsx";
|
||||||
import NoteUpsertModalComponent from "../../components/note-upsert-modal/note-upsert-modal.container";
|
import NoteUpsertModalComponent from "../../components/note-upsert-modal/note-upsert-modal.container";
|
||||||
import ScheduleJobModalContainer from "../../components/schedule-job-modal/schedule-job-modal.container";
|
import ScheduleJobModalContainer from "../../components/schedule-job-modal/schedule-job-modal.container";
|
||||||
import TaskListContainer from "../../components/task-list/task-list.container.jsx";
|
import TaskListContainer from "../../components/task-list/task-list.container.jsx";
|
||||||
@@ -54,9 +54,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
|||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
import { DateTimeFormat } from "../../utils/DateFormatter";
|
import { DateTimeFormat } from "../../utils/DateFormatter";
|
||||||
import dayjs from "../../utils/day";
|
import dayjs from "../../utils/day";
|
||||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
|
||||||
import UndefinedToNull from "../../utils/undefinedtonull";
|
import UndefinedToNull from "../../utils/undefinedtonull";
|
||||||
import LockWrapperComponent from "../../components/lock-wrapper/lock-wrapper.component.jsx";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -403,7 +401,9 @@ export function JobsDetailPage({
|
|||||||
icon: <BarsOutlined />,
|
icon: <BarsOutlined />,
|
||||||
id: "job-details-lifecycle",
|
id: "job-details-lifecycle",
|
||||||
label: (
|
label: (
|
||||||
<LockWrapperComponent featureName="lifecycle" bypass>{t("menus.jobsdetail.lifecycle")}</LockWrapperComponent>
|
<LockWrapperComponent featureName="lifecycle" bypass>
|
||||||
|
{t("menus.jobsdetail.lifecycle")}
|
||||||
|
</LockWrapperComponent>
|
||||||
),
|
),
|
||||||
children: <JobLifecycleComponent job={job} statuses={bodyshop.md_ro_statuses} />
|
children: <JobLifecycleComponent job={job} statuses={bodyshop.md_ro_statuses} />
|
||||||
},
|
},
|
||||||
@@ -438,7 +438,11 @@ export function JobsDetailPage({
|
|||||||
key: "audit",
|
key: "audit",
|
||||||
icon: <HistoryOutlined />,
|
icon: <HistoryOutlined />,
|
||||||
id: "job-details-audit",
|
id: "job-details-audit",
|
||||||
label: <LockWrapperComponent featureName="audit" bypass>{t("jobs.labels.audit")}</LockWrapperComponent>,
|
label: (
|
||||||
|
<LockWrapperComponent featureName="audit" bypass>
|
||||||
|
{t("jobs.labels.audit")}
|
||||||
|
</LockWrapperComponent>
|
||||||
|
),
|
||||||
children: <JobAuditTrail jobId={job.id} />
|
children: <JobAuditTrail jobId={job.id} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user