Compare commits

..

8 Commits

Author SHA1 Message Date
Allan Carr
bc42d19dff IO-3069 Job Drawer Documents Upsell correction
Would constantly display the upsell component

Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-27 10:01:11 -08:00
Patrick Fic
c0bf829dc0 Merged in hotfix/IO-3056-intellipay-logging (pull request #2031)
IO-3056 resolve logging issue for intellipay.
2024-12-16 21:17:03 +00:00
Patrick Fic
51cd61c932 IO-3056 resolve logging issue for intellipay. 2024-12-16 13:16:13 -08:00
Allan Carr
4ab77de591 Merged in hotfix/IO-3020-smart-scheduling-upsell (pull request #2030)
IO-3020 Fix PrintCenter Upsell restrictions
2024-12-16 20:56:40 +00:00
Allan Carr
2336617077 IO-3020 Fix PrintCenter Upsell restrictions
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-12-16 12:42:21 -08:00
Patrick Fic
897efde14d Merged in hotfix/IO-3020-smart-scheduling-upsell (pull request #2027)
IO-3020 Resolve smart scheduling upsell displays when they shouldn't.
2024-12-16 18:26:55 +00:00
Patrick Fic
98f7147378 IO-3020 Resolve smart scheduling upsell displays when they shouldn't. 2024-12-16 10:26:03 -08:00
Patrick Fic
54b8f564e4 Merged in hotfix/IO-3001-null-cieca-scrubbing (pull request #2025)
IO-3001 Add CIECA data check for scrubbing.
2024-12-16 16:07:15 +00:00
8 changed files with 68 additions and 46 deletions

View File

@@ -122,7 +122,7 @@ export function JobDetailCards({ bodyshop, setPrintCenterContext }) {
</Col>
{!bodyshop.uselocalmediaserver && (
<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 {...span}>

View File

@@ -1,12 +1,14 @@
import { Carousel } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
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 CardTemplate from "./job-detail-cards.template.component";
export default function JobDetailCardsDocumentsComponent({ loading, data }) {
export default function JobDetailCardsDocumentsComponent({ loading, data, bodyshop }) {
const { t } = useTranslation();
const hasMediaAccess = HasFeatureAccess({ bodyshop, featureName: "media" });
if (!data)
return (
@@ -21,17 +23,19 @@ export default function JobDetailCardsDocumentsComponent({ loading, data }) {
title={t("jobs.labels.cards.documents")}
extraLink={`/manage/jobs/${data.id}?tab=documents`}
>
<UpsellComponent disableMask upsell={upsellEnum().media.general}>
{data.documents.length > 0 ? (
<Carousel autoplay>
{data.documents.map((item) => (
<img key={item.id} src={GenerateThumbUrl(item)} alt={item.name} />
))}
</Carousel>
) : (
<div>{t("documents.errors.nodocuments")}</div>
)}
</UpsellComponent>
{!hasMediaAccess && (
<UpsellComponent disableMask upsell={upsellEnum().media.general}>
{data.documents.length > 0 ? (
<Carousel autoplay>
{data.documents.map((item) => (
<img key={item.id} src={GenerateThumbUrl(item)} alt={item.name} />
))}
</Carousel>
) : (
<div>{t("documents.errors.nodocuments")}</div>
)}
</UpsellComponent>
)}
</CardTemplate>
);
}

View File

@@ -9,6 +9,7 @@ import { selectTechnician } from "../../redux/tech/tech.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { GenerateDocument } from "../../utils/RenderTemplate";
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import { HasFeatureAccess } from './../feature-wrapper/feature-wrapper.component';
const mapStateToProps = createStructuredSelector({
printCenterModal: selectPrintCenter,
@@ -43,10 +44,12 @@ export function PrintCenterItemComponent({
setLoading(false);
};
if (disabled || item.featureNameRestricted)
if (disabled || (item.featureNameRestricted && !HasFeatureAccess({"featureName": item.featureNameRestricted, bodyshop})))
return (
<li className="print-center-item">
<LockWrapperComponent featureName={item.featureNameRestricted}>{item.title}</LockWrapperComponent>
<LockWrapperComponent featureName={item.featureNameRestricted} bodyshop={bodyshop}>
{item.title}
</LockWrapperComponent>
</li>
);
return (

View File

@@ -8,6 +8,7 @@ import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import BlurWrapperComponent from "../feature-wrapper/blur-wrapper.component";
import { UpsellMaskWrapper, upsellEnum } from "../upsell/upsell.component";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -35,6 +36,28 @@ export function ScheduleCalendarHeaderGraph({ bodyshop, loadData }) {
[]
);
}, [loadData, ssbuckets]);
const hasSmartSchedulingAccess = HasFeatureAccess({ featureName: "smartscheduling", bodyshop });
const chartContents = (
<>
<RadarChart
// cx={300}
// cy={250}
// outerRadius={150}
width={800}
height={600}
data={data}
>
<PolarGrid />
<PolarAngleAxis dataKey="bucket" />
<PolarRadiusAxis angle={90} />
<Radar name="Ideal Load" dataKey="target" stroke="darkgreen" fill="white" fillOpacity={0} />
<Radar name="EOD Load" dataKey="current" stroke="dodgerblue" fill="dodgerblue" fillOpacity={0.6} />
<Tooltip />
<Legend />
</RadarChart>
</>
);
const popContent = (
<div>
@@ -48,26 +71,13 @@ export function ScheduleCalendarHeaderGraph({ bodyshop, loadData }) {
<strong>{loadData?.expectedJobCount}</strong>
</BlurWrapperComponent>
</Space>
<UpsellMaskWrapper upsell={upsellEnum().smartscheduling.general}>
<BlurWrapperComponent featureName="smartscheduling">
<RadarChart
// cx={300}
// cy={250}
// outerRadius={150}
width={800}
height={600}
data={data}
>
<PolarGrid />
<PolarAngleAxis dataKey="bucket" />
<PolarRadiusAxis angle={90} />
<Radar name="Ideal Load" dataKey="target" stroke="darkgreen" fill="white" fillOpacity={0} />
<Radar name="EOD Load" dataKey="current" stroke="dodgerblue" fill="dodgerblue" fillOpacity={0.6} />
<Tooltip />
<Legend />
</RadarChart>
</BlurWrapperComponent>
</UpsellMaskWrapper>
<BlurWrapperComponent featureName="smartscheduling">
{hasSmartSchedulingAccess ? (
chartContents
) : (
<UpsellMaskWrapper upsell={upsellEnum().smartscheduling.general}>{chartContents}</UpsellMaskWrapper>
)}
</BlurWrapperComponent>
</div>
);

View File

@@ -18,6 +18,7 @@ import OwnerNameDisplay from "../owner-name-display/owner-name-display.component
import ScheduleBlockDay from "../schedule-block-day/schedule-block-day.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({
bodyshop: selectBodyshop,
@@ -52,6 +53,7 @@ export function ScheduleCalendarHeaderComponent({
const { t } = useTranslation();
const loadData = load[date.toISOString().substr(0, 10)];
const hasSmartSchedulingAccess = HasFeatureAccess({ featureName: "smartscheduling", bodyshop });
const jobsOutPopup = () => (
<div onClick={(e) => e.stopPropagation()}>
@@ -89,9 +91,11 @@ export function ScheduleCalendarHeaderComponent({
)}
</tbody>
</table>
<Card style={{ maxWidth: "30rem" }}>
<UpsellComponent size="small" upsell={upsellEnum().smartscheduling.hrsdelta} />
</Card>
{!hasSmartSchedulingAccess && (
<Card style={{ maxWidth: "30rem" }}>
<UpsellComponent size="small" upsell={upsellEnum().smartscheduling.hrsdelta} />
</Card>
)}
</div>
);
@@ -129,9 +133,11 @@ export function ScheduleCalendarHeaderComponent({
</BlurWrapperComponent>
</tr>
)}
<Card style={{ maxWidth: "30rem" }}>
<UpsellComponent size="small" upsell={upsellEnum().smartscheduling.hrsdelta} />
</Card>
{!hasSmartSchedulingAccess && (
<Card style={{ maxWidth: "30rem" }}>
<UpsellComponent size="small" upsell={upsellEnum().smartscheduling.hrsdelta} />
</Card>
)}
</tbody>
</table>
</div>

View File

@@ -16,7 +16,7 @@ import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.con
import ScheduleExistingAppointmentsList from "../schedule-existing-appointments-list/schedule-existing-appointments-list.component";
import "./schedule-job-modal.scss";
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import { BlurWrapper } from "../feature-wrapper/blur-wrapper.component";
import BlurWrapper from "../feature-wrapper/blur-wrapper.component";
import UpsellComponent, { upsellEnum } from "../upsell/upsell.component";
const mapStateToProps = createStructuredSelector({
@@ -138,7 +138,7 @@ export function ScheduleJobModalComponent({
</BlurWrapper>
</Button>
))}
{smartOptions.length > 1 && hasSmartSchedulingAccess && (
{!smartOptions.length > 1 && hasSmartSchedulingAccess && (
<UpsellComponent upsell={upsellEnum().smartscheduling.general} />
)}
</Space>

View File

@@ -19,7 +19,6 @@ export default function UpsellComponent({ featureName, subFeatureName, upsell, d
const { t } = useTranslation();
const resultProps = upsell || upsellEnum[featureName][subFeatureName];
console.trace("***LOG ~ file: upsell.component.jsx:22 ~ UpsellComponent ~ resultProps:", resultProps);
const componentRef = useRef(null);
useEffect(() => {

View File

@@ -389,7 +389,7 @@ exports.postback = async (req, res) => {
if (decodedComment) {
//Shifted the order to have this first to retain backwards compatibility for the old style of short link.
//This has been triggered by IO and may have multiple jobs.
const parsedComment = JSON.parse(decodedComment);
const parsedComment = decodedComment;
logger.log("intellipay-postback-parsed-comment", "DEBUG", req.user?.email, null, {
parsedComment,