Release/2025 01 10 IO-3069 IO-3067 IO-3070

This commit is contained in:
Patrick Fic
2025-01-08 14:16:41 -08:00
8 changed files with 321 additions and 199 deletions

View File

@@ -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 : [];

View File

@@ -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>
), ),

View File

@@ -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}>

View File

@@ -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,6 +23,7 @@ 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`}
> >
{!hasMediaAccess && (
<UpsellComponent disableMask upsell={upsellEnum().media.general}> <UpsellComponent disableMask upsell={upsellEnum().media.general}>
{data.documents.length > 0 ? ( {data.documents.length > 0 ? (
<Carousel autoplay> <Carousel autoplay>
@@ -32,6 +35,7 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
<div>{t("documents.errors.nodocuments")}</div> <div>{t("documents.errors.nodocuments")}</div>
)} )}
</UpsellComponent> </UpsellComponent>
)}
</CardTemplate> </CardTemplate>
); );
} }

View File

@@ -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%" }}
> >
{!hasLifeCycleAccess && (
<Card type="inner" style={{ marginTop: "10px" }}> <Card type="inner" style={{ marginTop: "10px" }}>
<UpsellComponent upsell={upsellEnum().lifecycle.general} /> <UpsellComponent upsell={upsellEnum().lifecycle.general} />
</Card> </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;

View File

@@ -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,

View File

@@ -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,21 +67,41 @@ 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 = () => {
const { currentUser, bodyshop } = store.getState().user;
const [first_name, ...last_name] = currentUser?.displayName ? currentUser.displayName.split(" ") : [];
const LearnMoreLink = encodeURI(
InstanceRenderManager({
imex: `https://imexsystems.ca/schedule-a-demo/`,
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: { bills: {
autoreconcile: { autoreconcile: {
//icon: null, //icon: null,
title: i18n.t("upsell.messages.bills.autoreconcile.title"), title: i18n.t("upsell.messages.bills.autoreconcile.title"),
subTitle: i18n.t("upsell.messages.bills.autoreconcile.subtitle"), subTitle: i18n.t("upsell.messages.bills.autoreconcile.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null //status: null
}, },
general: { general: {
//icon: null, //icon: null,
title: i18n.t("upsell.messages.bills.general.title"), title: i18n.t("upsell.messages.bills.general.title"),
subTitle: i18n.t("upsell.messages.bills.general.subtitle"), subTitle: i18n.t("upsell.messages.bills.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null //status: null
} }
}, },
@@ -87,7 +110,11 @@ export const upsellEnum = () => ({
//icon: null, //icon: null,
title: i18n.t("upsell.messages.checklist.general.title"), title: i18n.t("upsell.messages.checklist.general.title"),
subTitle: i18n.t("upsell.messages.checklist.general.subtitle"), subTitle: i18n.t("upsell.messages.checklist.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null //status: null
} }
}, },
@@ -96,7 +123,11 @@ export const upsellEnum = () => ({
//icon: null, //icon: null,
title: i18n.t("upsell.messages.payments.general.title"), title: i18n.t("upsell.messages.payments.general.title"),
subTitle: i18n.t("upsell.messages.payments.general.subtitle"), subTitle: i18n.t("upsell.messages.payments.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null //status: null
} }
}, },
@@ -105,7 +136,11 @@ export const upsellEnum = () => ({
//icon: null, //icon: null,
title: i18n.t("upsell.messages.audit.general.title"), title: i18n.t("upsell.messages.audit.general.title"),
subTitle: i18n.t("upsell.messages.audit.general.subtitle"), subTitle: i18n.t("upsell.messages.audit.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null //status: null
} }
}, },
@@ -114,7 +149,11 @@ export const upsellEnum = () => ({
//icon: null, //icon: null,
title: i18n.t("upsell.messages.lifecycle.general.title"), title: i18n.t("upsell.messages.lifecycle.general.title"),
subTitle: i18n.t("upsell.messages.lifecycle.general.subtitle"), subTitle: i18n.t("upsell.messages.lifecycle.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null } //status: null }
} }
}, },
@@ -123,14 +162,22 @@ export const upsellEnum = () => ({
//icon: null, //icon: null,
title: i18n.t("upsell.messages.media.general.title"), title: i18n.t("upsell.messages.media.general.title"),
subTitle: i18n.t("upsell.messages.media.general.subtitle"), subTitle: i18n.t("upsell.messages.media.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null } //status: null }
}, },
mobile: { mobile: {
icon: <MobileOutlined />, icon: <MobileOutlined />,
title: i18n.t("upsell.messages.media.mobile.title"), title: i18n.t("upsell.messages.media.mobile.title"),
subTitle: i18n.t("upsell.messages.media.mobile.subtitle"), subTitle: i18n.t("upsell.messages.media.mobile.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
//status: null } //status: null }
} }
}, },
@@ -138,12 +185,20 @@ export const upsellEnum = () => ({
allocations: { allocations: {
title: i18n.t("upsell.messages.timetickets.allocations.title"), title: i18n.t("upsell.messages.timetickets.allocations.title"),
subTitle: i18n.t("upsell.messages.timetickets.allocations.subtitle"), subTitle: i18n.t("upsell.messages.timetickets.allocations.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
}, },
general: { general: {
title: i18n.t("upsell.messages.timetickets.general.title"), title: i18n.t("upsell.messages.timetickets.general.title"),
subTitle: i18n.t("upsell.messages.timetickets.general.subtitle"), subTitle: i18n.t("upsell.messages.timetickets.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
smartscheduling: { smartscheduling: {
@@ -151,19 +206,31 @@ export const upsellEnum = () => ({
icon: <CalendarOutlined />, icon: <CalendarOutlined />,
title: i18n.t("upsell.messages.smartscheduling.general.title"), title: i18n.t("upsell.messages.smartscheduling.general.title"),
subTitle: i18n.t("upsell.messages.smartscheduling.general.subtitle"), subTitle: i18n.t("upsell.messages.smartscheduling.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
}, },
hrsdelta: { hrsdelta: {
icon: <CarOutlined />, icon: <CarOutlined />,
title: i18n.t("upsell.messages.smartscheduling.hrsdelta.title"), title: i18n.t("upsell.messages.smartscheduling.hrsdelta.title"),
subTitle: i18n.t("upsell.messages.smartscheduling.hrsdelta.subtitle"), subTitle: i18n.t("upsell.messages.smartscheduling.hrsdelta.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
}, },
datepicker: { datepicker: {
icon: <CarOutlined />, icon: <CarOutlined />,
title: i18n.t("upsell.messages.smartscheduling.datepicker.title"), title: i18n.t("upsell.messages.smartscheduling.datepicker.title"),
subTitle: i18n.t("upsell.messages.smartscheduling.datepicker.subtitle"), subTitle: i18n.t("upsell.messages.smartscheduling.datepicker.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
accounting: { accounting: {
@@ -171,19 +238,31 @@ export const upsellEnum = () => ({
icon: <DollarOutlined />, icon: <DollarOutlined />,
title: i18n.t("upsell.messages.accounting.payables.title"), title: i18n.t("upsell.messages.accounting.payables.title"),
subTitle: i18n.t("upsell.messages.accounting.payables.subtitle"), subTitle: i18n.t("upsell.messages.accounting.payables.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
}, },
receivables: { receivables: {
icon: <DollarOutlined />, icon: <DollarOutlined />,
title: i18n.t("upsell.messages.accounting.receivables.title"), title: i18n.t("upsell.messages.accounting.receivables.title"),
subTitle: i18n.t("upsell.messages.accounting.receivables.subtitle"), subTitle: i18n.t("upsell.messages.accounting.receivables.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
}, },
payments: { payments: {
icon: <DollarOutlined />, icon: <DollarOutlined />,
title: i18n.t("upsell.messages.accounting.payments.title"), title: i18n.t("upsell.messages.accounting.payments.title"),
subTitle: i18n.t("upsell.messages.accounting.payments.subtitle"), subTitle: i18n.t("upsell.messages.accounting.payments.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
courtesycars: { courtesycars: {
@@ -191,7 +270,11 @@ export const upsellEnum = () => ({
icon: <CarOutlined />, icon: <CarOutlined />,
title: i18n.t("upsell.messages.courtesycars.general.title"), title: i18n.t("upsell.messages.courtesycars.general.title"),
subTitle: i18n.t("upsell.messages.courtesycars.general.subtitle"), subTitle: i18n.t("upsell.messages.courtesycars.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
dashboard: { dashboard: {
@@ -199,7 +282,11 @@ export const upsellEnum = () => ({
icon: <DashboardOutlined />, icon: <DashboardOutlined />,
title: i18n.t("upsell.messages.dashboard.general.title"), title: i18n.t("upsell.messages.dashboard.general.title"),
subTitle: i18n.t("upsell.messages.dashboard.general.subtitle"), subTitle: i18n.t("upsell.messages.dashboard.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
visualboard: { visualboard: {
@@ -207,7 +294,11 @@ export const upsellEnum = () => ({
icon: <BuildOutlined />, icon: <BuildOutlined />,
title: i18n.t("upsell.messages.visualboard.general.title"), title: i18n.t("upsell.messages.visualboard.general.title"),
subTitle: i18n.t("upsell.messages.visualboard.general.subtitle"), subTitle: i18n.t("upsell.messages.visualboard.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
scoreboard: { scoreboard: {
@@ -215,7 +306,11 @@ export const upsellEnum = () => ({
icon: <LineChartOutlined />, icon: <LineChartOutlined />,
title: i18n.t("upsell.messages.scoreboard.general.title"), title: i18n.t("upsell.messages.scoreboard.general.title"),
subTitle: i18n.t("upsell.messages.scoreboard.general.subtitle"), subTitle: i18n.t("upsell.messages.scoreboard.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
techconsole: { techconsole: {
@@ -223,7 +318,11 @@ export const upsellEnum = () => ({
icon: <LineChartOutlined />, icon: <LineChartOutlined />,
title: i18n.t("upsell.messages.techconsole.general.title"), title: i18n.t("upsell.messages.techconsole.general.title"),
subTitle: i18n.t("upsell.messages.techconsole.general.subtitle"), subTitle: i18n.t("upsell.messages.techconsole.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
}, },
csi: { csi: {
@@ -231,7 +330,12 @@ export const upsellEnum = () => ({
icon: <StarOutlined />, icon: <StarOutlined />,
title: i18n.t("upsell.messages.csi.general.title"), title: i18n.t("upsell.messages.csi.general.title"),
subTitle: i18n.t("upsell.messages.csi.general.subtitle"), subTitle: i18n.t("upsell.messages.csi.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button> extra: (
<Link to={LearnMoreLink} target="_blank">
<Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
</Link>
)
} }
} }
}); };
};

View File

@@ -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} />
}, },
{ {