IO-3020 IO-3036 Add basic upsell component and blur out reports.

This commit is contained in:
Patrick Fic
2024-12-06 10:58:07 -08:00
parent 43b1ad78a3
commit b052e97b73
4 changed files with 113 additions and 23 deletions

View File

@@ -1,7 +1,8 @@
import { EditFilled, SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Input, Space, Table } from "antd";
import React, { useState } from "react";
import React, { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { FaTasks } from "react-icons/fa";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
@@ -13,10 +14,11 @@ import { alphaSort, dateSort } from "../../utils/sorters";
import { TemplateList } from "../../utils/TemplateConstants";
import BillDeleteButton from "../bill-delete-button/bill-delete-button.component";
import BillDetailEditReturnComponent from "../bill-detail-edit/bill-detail-edit-return.component";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
import { FaTasks } from "react-icons/fa";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import LockerWrapperComponent from "../lock-wrapper/lock-wrapper.component";
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
import UpsellComponent from "../upsell/upsell.component";
import upsellEnum from "../upsell/upsell.enum";
const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
@@ -59,6 +61,7 @@ export function BillsListTableComponent({
// const search = queryString.parse(useLocation().search);
// const selectedBill = search.billid;
const [searchText, setSearchText] = useState("");
const containerRef = useRef(null);
const Templates = TemplateList("bill");
const bills = billsQuery.data ? billsQuery.data.bills : [];
@@ -237,14 +240,7 @@ export function BillsListTableComponent({
onChange={handleTableChange}
locale={{
...(!hasBillsAccess && {
emptyText: (
<div>
Upsell
{
//TODO:Upsell
}
</div>
)
emptyText: <UpsellComponent upsell={upsellEnum.bills.table} />
})
}}
/>

View File

@@ -16,6 +16,7 @@ import { TemplateList } from "../../utils/TemplateConstants";
import dayjs from "../../utils/day";
import EmployeeSearchSelectEmail from "../employee-search-select/employee-search-select-email.component";
import EmployeeSearchSelect from "../employee-search-select/employee-search-select.component";
import BlurWrapperComponent from "../feature-wrapper/blur-wrapper.component";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
import ReportCenterModalFiltersSortersComponent from "./report-center-modal-filters-sorters-component";
@@ -130,9 +131,12 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
const grouped = _.groupBy(FilteredReportsList, "group");
const groupExcludeKeyFilter = [
...(!HasFeatureAccess({ featureName: "bills", bodyshop }) ? ["purchases"] : []),
...(!HasFeatureAccess({ featureName: "timetickets", bodyshop }) ? ["payroll"] : [])
...(!HasFeatureAccess({ featureName: "bills", bodyshop }) ? [{ key: "purchases", featureName: "bills" }] : []),
...(!HasFeatureAccess({ featureName: "timetickets", bodyshop })
? [{ key: "payroll", featureName: "timetickets" }]
: [])
];
//TODO: Find a way to filter out / blur on demand.
return (
<div>
@@ -165,15 +169,31 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
}}
>
<Typography.Title level={4}>{t(`reportcenter.labels.groups.${key}`)}</Typography.Title>
<ul style={{ listStyleType: "none", columns: "2 auto" }}>
{grouped[key].map((item) => (
<li key={item.key}>
<Radio key={item.key} value={item.key}>
{item.title}
</Radio>
</li>
))}
</ul>
{groupExcludeKeyFilter.find((g) => g.key === key) ? (
<BlurWrapperComponent
featureName={groupExcludeKeyFilter.find((g) => g.key === key).featureName}
>
<ul style={{ listStyleType: "none", columns: "2 auto" }}>
{grouped[key].map((item) => (
<li key={item.key}>
<Radio key={item.key} value={item.key}>
{item.title}
</Radio>
</li>
))}
</ul>
</BlurWrapperComponent>
) : (
<ul style={{ listStyleType: "none", columns: "2 auto" }}>
{grouped[key].map((item) => (
<li key={item.key}>
<Radio key={item.key} value={item.key}>
{item.title}
</Radio>
</li>
))}
</ul>
)}
</Card.Grid>
</Col>
))}
@@ -278,7 +298,8 @@ export function ReportCenterModalComponent({ reportCenterModal, bodyshop }) {
{
validator: (_, value) => {
if (
(!import.meta.env.VITE_APP_IS_TEST && import.meta.env.PROD) &&
!import.meta.env.VITE_APP_IS_TEST &&
import.meta.env.PROD &&
value &&
value[0] &&
value[1]

View File

@@ -0,0 +1,39 @@
import { AppstoreAddOutlined } from "@ant-design/icons";
import { Result } from "antd";
import React, { useEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import upsellEnum from "./upsell.enum";
export default function UpsellComponent({ featureName, subFeatureName, upsell, disableMask = false }) {
const { t } = useTranslation();
const resultProps = upsell || upsellEnum[featureName][subFeatureName];
const componentRef = useRef(null);
useEffect(() => {
if (disableMask) return;
const parentElement = componentRef.current?.parentElement;
if (parentElement) {
const mask = document.createElement("div");
mask.style.position = "absolute";
mask.style.top = 0;
mask.style.left = 0;
mask.style.width = "100%";
mask.style.height = "100%";
mask.style.backgroundColor = "rgba(0, 0, 0, 0.25)";
mask.style.zIndex = 9999;
parentElement.style.position = "relative";
parentElement.appendChild(mask);
return () => {
parentElement.removeChild(mask);
};
}
}, []);
if (!resultProps) return <Result status="info" title={t("upsell.messages.generic")} />;
return (
<div ref={componentRef}>
<Result status="info" icon={<AppstoreAddOutlined />} {...resultProps} />
</div>
);
}

View File

@@ -0,0 +1,34 @@
import i18n from "i18next";
const upsellEnum = {
bills: {
postbills: {
icon: null,
title: i18n.t("upsell.messages.bills.postbills.title"),
subTitle: i18n.t("upsell.messages.bills.postbills.subtitle"),
status: null //Nullable
},
reconcile: {
icon: null,
title: i18n.t("upsell.messages.bills.reconcile.title"),
subTitle: i18n.t("upsell.messages.bills.reconcile.subtitle"),
status: null //Nullable
},
table: {
//icon: null,
title: i18n.t("upsell.messages.bills.table.title"),
subTitle: i18n.t("upsell.messages.bills.table.subtitle"),
//status: null //Nullable
}
},
timetickets: {
table: {
icon: null,
title: i18n.t("upsell.messages.timetickets.table.title"),
subTitle: i18n.t("upsell.messages.timetickets.table.subtitle"),
status: null //Nullable
}
}
};
export default upsellEnum;