Compare commits

..

72 Commits
master ... test

Author SHA1 Message Date
Allan Carr
b667524a04 Merged in release/2024-08-23-LEGACY (pull request #1639)
IO-2887 Null out BillData if returnfrombill is not available
2024-08-20 23:17:11 +00:00
Allan Carr
5a4c0e4f65 Merged in release/2024-08-23-LEGACY (pull request #1637)
IO-2887 Returnfrombill Parts Drawer Legacy
2024-08-20 22:47:06 +00:00
Dave Richer
5f9c756172 Merged in release/2024-08-16-LEGACY (pull request #1624)
IO-2884 Production List Filter LEGACY
2024-08-16 16:17:42 +00:00
Dave Richer
6528509288 Merged in release/2024-08-16-LEGACY (pull request #1609)
- Improve handle beta code (AIO Version)
2024-08-15 15:21:48 +00:00
Allan Carr
a18e40a63c Merged in release/2024-08-16-LEGACY (pull request #1605)
IO-2876 OpenSearch Sorters LEGACY
2024-08-14 19:40:24 +00:00
Dave Richer
c171847555 Merged in release/2024-08-16-LEGACY (pull request #1602)
- Improve handle beta code (AIO Version)
2024-08-14 18:42:09 +00:00
Allan Carr
7e60e2c699 Merged in release/2024-08-16-LEGACY (pull request #1591)
Release/2024 08 16 LEGACY
2024-08-12 22:23:44 +00:00
Dave Richer
e685ca5ad8 Merged in release/2024-05-31 (pull request #1454)
IO-2792 Resolve bill receive of credit memo and noline
2024-06-01 17:20:41 +00:00
Dave Richer
0fa110cc51 Merged in release/2024-05-24 (pull request #1446)
Release/2024 05 24
2024-05-24 17:22:07 +00:00
Patrick Fic
76441e49e1 Merge branch 'test' of bitbucket.org:snaptsoft/bodyshop into test 2024-05-03 14:39:26 -07:00
Patrick Fic
524385af7d Merge branch 'release/2024-04-26' into test 2024-05-03 14:39:06 -07:00
Patrick Fic
ded7393aec Merged in release/2024-04-26 (pull request #1437)
Release/2024 04 26
2024-04-26 16:06:44 +00:00
Patrick Fic
b269d54f2c Merge branch 'release/2024-04-19' into test 2024-04-16 16:11:10 -07:00
Patrick Fic
069d508528 Update cron trigger timing. 2024-04-16 16:09:54 -07:00
Patrick Fic
d213c382c9 Merge branch 'release/2024-04-19' into test 2024-04-16 16:03:42 -07:00
Patrick Fic
878e81dc8f Hasura schema changes for tasks. 2024-04-16 16:02:25 -07:00
Dave Richer
deab90b326 Merged in release/2024-04-19 (pull request #1417)
Release/2024 04 19
2024-04-16 19:55:26 +00:00
Dave Richer
a1f7e7b755 Merged in feature/IO-2667-Migrations-For-Remind-At-Sent (pull request #1416)
- Migrations for remind_at_sent
2024-04-16 19:52:13 +00:00
Dave Richer
c8f8a86a98 - Migrations for remind_at_sent
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-04-16 15:45:56 -04:00
Allan Carr
8c74276b98 Merged in release/2024-04-12 (pull request #1410)
IO-2609 Fix Spelling Mistake in object name
2024-04-11 21:39:59 +00:00
Allan Carr
ac1ad12ac4 Merged in release/2024-04-12 (pull request #1407)
Release/2024 04 12
2024-04-11 21:23:28 +00:00
Allan Carr
dedc594b58 Merged in release/2024-04-05 (pull request #1400)
Release/2024 04 05
2024-04-08 19:58:02 +00:00
Allan Carr
02747f4144 Merged in release/2024-04-05 (pull request #1397)
IO-2568 Button Padding in Print Center Label Modal
2024-04-05 19:03:48 +00:00
Allan Carr
05b1078e27 Merged in release/2024-04-05 (pull request #1394)
IO-2750 Missing Mutation return fields
2024-04-05 15:55:38 +00:00
Allan Carr
cc57eb40cf Merged in release/2024-04-05 (pull request #1391)
Release/2024 04 05
2024-04-04 19:27:21 +00:00
Allan Carr
33518e5c25 Merged in release/2024-03-28 (pull request #1381)
Release/2024 03 28
2024-03-28 20:26:17 +00:00
Dave Richer
b34909b7f3 Merged in release/2024-03-28 (pull request #1378)
Release/2024 03 28
2024-03-28 17:00:21 +00:00
Dave Richer
bd599cfea4 Merged in release/2024-03-22 (pull request #1371)
IO-2721 Owners Note in Owners Card
2024-03-22 16:19:15 +00:00
Patrick Fic
e8917f5736 Merged in release/2024-03-22 (pull request #1368)
Release/2024 03 22
2024-03-21 21:43:06 +00:00
Patrick Fic
b7ee95059d Merged in release/2024-03-15 (pull request #1360)
Release/2024 03 15
2024-03-15 17:28:36 +00:00
Dave Richer
f59d369529 Merged in release/2024-03-15 (pull request #1352)
- Implement
2024-03-15 14:49:47 +00:00
Dave Richer
eefac38d9c Merged in release/2024-03-15 (pull request #1349)
- Fix bug
2024-03-14 19:00:06 +00:00
Dave Richer
249b74a597 Merged in release/2024-03-15 (pull request #1347)
Release/2024 03 15
2024-03-14 16:39:05 +00:00
Allan Carr
4fb491697c Merged in release/2024-03-08 (pull request #1329)
Release/2024 03 08
2024-03-08 19:39:07 +00:00
Dave Richer
09da3f349b Merged in release/2024-03-08 (pull request #1326)
- Add new special filters
2024-03-08 17:48:15 +00:00
Dave Richer
e8f4f30cc4 Merged in release/2024-03-08 (pull request #1324)
Release/2024 03 08
2024-03-08 17:39:02 +00:00
Patrick Fic
8c4f395ff9 Merged in release/2024-03-01 (pull request #1316)
Resolve refund payment logging.
2024-03-01 19:59:42 +00:00
Allan Carr
acbf75ff4d Merged in release/2024-03-01 (pull request #1313)
Release/2024 03 01

Approved-by: Dave Richer
2024-03-01 17:18:20 +00:00
Allan Carr
36e3828e2d Merged in release/2024-02-23 (pull request #1309)
IO-2640 Adjust Filters and Sorters for Table
2024-02-23 21:26:20 +00:00
Allan Carr
281c9bbc2a Merged in release/2024-02-23 (pull request #1304)
Release/2024 02 23
2024-02-22 21:53:33 +00:00
Allan Carr
455e79a6f7 Merged in release/2024-02-16 (pull request #1295)
IO-2631 Correct Import Statement for moment
2024-02-16 20:34:07 +00:00
Allan Carr
bc73e75217 Merged in release/2024-02-16 (pull request #1293)
IO-2631 Correct for Business Days
2024-02-16 19:25:01 +00:00
Allan Carr
7b3f71701e Merged in release/2024-02-16 (pull request #1288)
IO-2637 Correct for Timezone offset
2024-02-16 17:24:44 +00:00
Dave Richer
383a383a9f Merged in release/2024-02-16 (pull request #1286)
- Fix issues with labels on sorters
2024-02-16 02:05:56 +00:00
Dave Richer
7ee853ae15 Merged in release/2024-02-16 (pull request #1285)
Release/2024 02 16
2024-02-15 17:45:53 +00:00
Allan Carr
3510d081cd Merged in release/2024-02-02 (pull request #1273)
IO-2630 Adjust Query to match Tags
2024-02-09 17:55:09 +00:00
Allan Carr
471105828c Merged in release/2024-02-02 (pull request #1271)
Release/2024 02 02
2024-02-09 16:20:01 +00:00
Allan Carr
1ec1f5d3a8 Merged in release/2024-02-02 (pull request #1268)
IO-2626 Adjust Image Prop on customer page
2024-02-08 17:58:46 +00:00
Patrick Fic
355de9efd0 Merge branch 'release/2024-02-02' into test 2024-02-06 10:05:44 -08:00
Patrick Fic
2c14731ebd Merge branch 'release/2024-02-02' into test 2024-02-06 09:30:29 -08:00
Allan Carr
065d2d5688 Merged in release/2024-02-02 (pull request #1264)
IO-2626 CICD Resource Size Change
2024-02-06 16:56:32 +00:00
Allan Carr
879dea9fa7 Merged in release/2024-02-02 (pull request #1260)
Release/2024 02 02
2024-02-06 16:18:33 +00:00
Allan Carr
3ceada30a3 Merged in release/2024-02-02 (pull request #1252)
IO-2624 federal_tax_exempt destructure
2024-02-02 17:47:36 +00:00
Patrick Fic
d26eb81339 Merge branch 'feature/Sentry-Improvements' into test 2024-01-30 16:58:35 -08:00
Patrick Fic
fcdcdbbf7f Merge branch 'feature/Sentry-Improvements' into test 2024-01-30 13:33:13 -08:00
Patrick Fic
d482447dc9 Merge branch 'feature/Sentry-Improvements' into test 2024-01-30 13:26:32 -08:00
Patrick Fic
647dfbfa06 Merge branch 'feature/Sentry-Improvements' into test 2024-01-30 13:14:43 -08:00
Patrick Fic
f17899285f Merge branch 'feature/Sentry-Improvements' into test 2024-01-30 12:53:20 -08:00
Patrick Fic
47f5641518 Merge branch 'test' of bitbucket.org:snaptsoft/bodyshop into test 2024-01-30 12:48:00 -08:00
Patrick Fic
6e41a282ca Merge branch 'feature/Sentry-Improvements' into test 2024-01-30 12:47:38 -08:00
Patrick Fic
abbd2263ee Merged in release/2024-01-29 (pull request #1229)
IO-1532 resolve update logic issue for status timings.
2024-01-29 17:06:19 +00:00
Dave Richer
4b70c89e54 Merged in release/2024-01-26 (pull request #1224)
- updates from lifecyle component.
2024-01-26 23:07:40 +00:00
Dave Richer
5e2c1aae4f Merged in release/2024-01-26 (pull request #1222)
- Fix use hook
2024-01-26 21:34:47 +00:00
Dave Richer
fda06bb298 Merged in release/2024-01-26 (pull request #1220)
Release/2024 01 26
2024-01-26 21:21:52 +00:00
Allan Carr
3dfd45ca0f Merged in release/2024-01-26 (pull request #1217)
Release/2024 01 26
2024-01-26 16:53:56 +00:00
Allan Carr
86e748502c Merged in release/2024-01-26 (pull request #1212)
Release/2024 01 26

Approved-by: Dave Richer
2024-01-25 20:27:32 +00:00
Patrick Fic
0f85250d40 Merged in release/2024-01-19 (pull request #1205)
Release/2024 01 19
2024-01-19 21:19:03 +00:00
Allan Carr
f04bc59966 Merged in release/2024-01-19 (pull request #1184)
Release/2024 01 19

Approved-by: Dave Richer
2024-01-19 16:59:22 +00:00
Dave Richer
e6e24dae4b Merged in feature/IO-1828-Beta-Updates-To-Test (pull request #1192)
- update handleBeta
2024-01-18 21:36:14 +00:00
Dave Richer
4ad32117c3 Merged in feature/IO-1828-Beta-Updates-To-Test (pull request #1191)
- update handleBeta
2024-01-18 21:23:38 +00:00
Dave Richer
befb8009e0 Merged in feature/IO-1828-Beta-Updates-To-Test (pull request #1190)
- update handleBeta
2024-01-18 21:16:22 +00:00
Dave Richer
41bec72390 Merged in feature/IO-1828-Beta-Updates-To-Test (pull request #1189)
- update handleBeta
2024-01-18 21:07:45 +00:00
8 changed files with 321 additions and 80 deletions

View File

@@ -16,28 +16,42 @@ import TechPageContainer from "../pages/tech/tech.page.container";
import { setOnline } from "../redux/application/application.actions";
import { selectOnline } from "../redux/application/application.selectors";
import { checkUserSession } from "../redux/user/user.actions";
import { selectBodyshop, selectCurrentUser } from "../redux/user/user.selectors";
import {
selectBodyshop,
selectCurrentUser,
} from "../redux/user/user.selectors";
import PrivateRoute from "../utils/private-route";
import "./App.styles.scss";
import handleBeta from "../utils/handleBeta";
const ResetPassword = lazy(() => import("../pages/reset-password/reset-password.component"));
const ResetPassword = lazy(() =>
import("../pages/reset-password/reset-password.component")
);
const ManagePage = lazy(() => import("../pages/manage/manage.page.container"));
const SignInPage = lazy(() => import("../pages/sign-in/sign-in.page"));
const CsiPage = lazy(() => import("../pages/csi/csi.container.page"));
const MobilePaymentContainer = lazy(() => import("../pages/mobile-payment/mobile-payment.container"));
const MobilePaymentContainer = lazy(() =>
import("../pages/mobile-payment/mobile-payment.container")
);
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
online: selectOnline,
bodyshop: selectBodyshop
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
checkUserSession: () => dispatch(checkUserSession()),
setOnline: (isOnline) => dispatch(setOnline(isOnline))
setOnline: (isOnline) => dispatch(setOnline(isOnline)),
});
export function App({ bodyshop, checkUserSession, currentUser, online, setOnline }) {
export function App({
bodyshop,
checkUserSession,
currentUser,
online,
setOnline,
}) {
const client = useClient();
useEffect(() => {
@@ -94,6 +108,8 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
/>
);
handleBeta();
return (
<Switch>
<Suspense fallback={<LoadingSpinner message="ImEX Online" />}>
@@ -113,16 +129,32 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
<Route exact path="/disclaimer" component={DisclaimerPage} />
</ErrorBoundary>
<ErrorBoundary>
<Route exact path="/mp/:paymentIs" component={MobilePaymentContainer} />
<Route
exact
path="/mp/:paymentIs"
component={MobilePaymentContainer}
/>
</ErrorBoundary>
<ErrorBoundary>
<PrivateRoute isAuthorized={currentUser.authorized} path="/manage" component={ManagePage} />
<PrivateRoute
isAuthorized={currentUser.authorized}
path="/manage"
component={ManagePage}
/>
</ErrorBoundary>
<ErrorBoundary>
<PrivateRoute isAuthorized={currentUser.authorized} path="/tech" component={TechPageContainer} />
<PrivateRoute
isAuthorized={currentUser.authorized}
path="/tech"
component={TechPageContainer}
/>
</ErrorBoundary>
<ErrorBoundary>
<PrivateRoute isAuthorized={currentUser.authorized} path="/edit" component={DocumentEditorContainer} />
<PrivateRoute
isAuthorized={currentUser.authorized}
path="/edit"
component={DocumentEditorContainer}
/>
</ErrorBoundary>
</Suspense>
</Switch>

View File

@@ -11,8 +11,9 @@ import Icon, {
FileAddFilled,
FileAddOutlined,
FileFilled,
//GlobalOutlined,
HomeFilled,
ImportOutlined,
ImportOutlined, InfoCircleOutlined,
LineChartOutlined,
PaperClipOutlined,
PhoneOutlined,
@@ -22,39 +23,56 @@ import Icon, {
TeamOutlined,
ToolFilled,
UnorderedListOutlined,
UserOutlined
UserOutlined,
} from "@ant-design/icons";
import { useTreatments } from "@splitsoftware/splitio-react";
import { Layout, Menu } from "antd";
import React from "react";
import {Layout, Menu, Switch, Tooltip} from "antd";
import React, {useEffect, useState} from "react";
import { useTranslation } from "react-i18next";
import { BsKanban } from "react-icons/bs";
import { FaCalendarAlt, FaCarCrash, FaCreditCard, FaFileInvoiceDollar } from "react-icons/fa";
import {
FaCalendarAlt,
FaCarCrash,
FaCreditCard,
FaFileInvoiceDollar,
} from "react-icons/fa";
import { GiPayMoney, GiPlayerTime, GiSettingsKnobs } from "react-icons/gi";
import { IoBusinessOutline } from "react-icons/io5";
import { RiSurveyLine } from "react-icons/ri";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { selectRecentItems, selectSelectedHeader } from "../../redux/application/application.selectors";
import {
selectRecentItems,
selectSelectedHeader,
} from "../../redux/application/application.selectors";
import { setModalContext } from "../../redux/modals/modals.actions";
import { signOutStart } from "../../redux/user/user.actions";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import {handleBeta, setBeta, checkBeta} from "../../utils/handleBeta";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
recentItems: selectRecentItems,
selectedHeader: selectSelectedHeader,
bodyshop: selectBodyshop
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
setBillEnterContext: (context) => dispatch(setModalContext({ context: context, modal: "billEnter" })),
setTimeTicketContext: (context) => dispatch(setModalContext({ context: context, modal: "timeTicket" })),
setPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "payment" })),
setReportCenterContext: (context) => dispatch(setModalContext({ context: context, modal: "reportCenter" })),
setBillEnterContext: (context) =>
dispatch(setModalContext({ context: context, modal: "billEnter" })),
setTimeTicketContext: (context) =>
dispatch(setModalContext({ context: context, modal: "timeTicket" })),
setPaymentContext: (context) =>
dispatch(setModalContext({ context: context, modal: "payment" })),
setReportCenterContext: (context) =>
dispatch(setModalContext({ context: context, modal: "reportCenter" })),
signOutStart: () => dispatch(signOutStart()),
setCardPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "cardPayment" }))
setCardPaymentContext: (context) =>
dispatch(setModalContext({ context: context, modal: "cardPayment" })),
});
function Header({
@@ -68,26 +86,37 @@ function Header({
setPaymentContext,
setReportCenterContext,
recentItems,
setCardPaymentContext
setCardPaymentContext,
}) {
const { Simple_Inventory } = useTreatments(["Simple_Inventory"], {}, bodyshop && bodyshop.imexshopid);
const { DmsAp } = useTreatments(["DmsAp"], {}, bodyshop && bodyshop.imexshopid);
const { ImEXPay } = useTreatments(["ImEXPay"], {}, bodyshop && bodyshop.imexshopid);
const { Simple_Inventory } = useTreatments(
["Simple_Inventory"],
{},
bodyshop && bodyshop.imexshopid
);
const { DmsAp } = useTreatments(
["DmsAp"],
{},
bodyshop && bodyshop.imexshopid
);
const { ImEXPay } = useTreatments(
["ImEXPay"],
{},
bodyshop && bodyshop.imexshopid
);
const [betaSwitch, setBetaSwitch] = useState(false);
const { t } = useTranslation();
const deleteBetaCookie = () => {
const cookieExists = document.cookie.split("; ").some((row) => row.startsWith(`betaSwitchImex=`));
if (cookieExists) {
const domain = window.location.hostname.split(".").slice(-2).join(".");
document.cookie = `betaSwitchImex=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${domain}`;
console.log(`betaSwitchImex cookie deleted`);
} else {
console.log(`betaSwitchImex cookie does not exist`);
}
};
useEffect(() => {
const isBeta = checkBeta();
setBetaSwitch(isBeta);
}, []);
deleteBetaCookie();
const betaSwitchChange = (checked) => {
setBeta(checked);
setBetaSwitch(checked);
handleBeta();
}
return (
<Layout.Header>
@@ -105,7 +134,11 @@ function Header({
<Menu.Item key="schedule" icon={<Icon component={FaCalendarAlt} />}>
<Link to="/manage/schedule">{t("menus.header.schedule")}</Link>
</Menu.Item>
<Menu.SubMenu key="jobssubmenu" icon={<Icon component={FaCarCrash} />} title={t("menus.header.jobs")}>
<Menu.SubMenu
key="jobssubmenu"
icon={<Icon component={FaCarCrash} />}
title={t("menus.header.jobs")}
>
<Menu.Item key="activejobs" icon={<FileFilled />}>
<Link to="/manage/jobs">{t("menus.header.activejobs")}</Link>
</Menu.Item>
@@ -116,7 +149,9 @@ function Header({
<Link to="/manage/partsqueue">{t("menus.header.parts-queue")}</Link>
</Menu.Item>
<Menu.Item key="availablejobs" icon={<ImportOutlined />}>
<Link to="/manage/available">{t("menus.header.availablejobs")}</Link>
<Link to="/manage/available">
{t("menus.header.availablejobs")}
</Link>
</Menu.Item>
<Menu.Item key="newjob" icon={<FileAddOutlined />}>
<Link to="/manage/jobs/new">{t("menus.header.newjob")}</Link>
@@ -127,17 +162,25 @@ function Header({
</Menu.Item>
<Menu.Divider key="div2" />
<Menu.Item key="productionlist" icon={<ScheduleOutlined />}>
<Link to="/manage/production/list">{t("menus.header.productionlist")}</Link>
<Link to="/manage/production/list">
{t("menus.header.productionlist")}
</Link>
</Menu.Item>
<Menu.Item key="productionboard" icon={<Icon component={BsKanban} />}>
<Link to="/manage/production/board">{t("menus.header.productionboard")}</Link>
<Link to="/manage/production/board">
{t("menus.header.productionboard")}
</Link>
</Menu.Item>
<Menu.Divider key="div3" />
<Menu.Item key="scoreboard" icon={<LineChartOutlined />}>
<Link to="/manage/scoreboard">{t("menus.header.scoreboard")}</Link>
</Menu.Item>
</Menu.SubMenu>
<Menu.SubMenu key="customers" icon={<UserOutlined />} title={t("menus.header.customers")}>
<Menu.SubMenu
key="customers"
icon={<UserOutlined />}
title={t("menus.header.customers")}
>
<Menu.Item key="owners" icon={<TeamOutlined />}>
<Link to="/manage/owners">{t("menus.header.owners")}</Link>
</Menu.Item>
@@ -145,19 +188,36 @@ function Header({
<Link to="/manage/vehicles">{t("menus.header.vehicles")}</Link>
</Menu.Item>
</Menu.SubMenu>
<Menu.SubMenu key="ccs" icon={<CarFilled />} title={t("menus.header.courtesycars")}>
<Menu.SubMenu
key="ccs"
icon={<CarFilled />}
title={t("menus.header.courtesycars")}
>
<Menu.Item key="courtesycarsall" icon={<CarFilled />}>
<Link to="/manage/courtesycars">{t("menus.header.courtesycars-all")}</Link>
<Link to="/manage/courtesycars">
{t("menus.header.courtesycars-all")}
</Link>
</Menu.Item>
<Menu.Item key="contracts" icon={<FileFilled />}>
<Link to="/manage/courtesycars/contracts">{t("menus.header.courtesycars-contracts")}</Link>
<Link to="/manage/courtesycars/contracts">
{t("menus.header.courtesycars-contracts")}
</Link>
</Menu.Item>
<Menu.Item key="newcontract" icon={<FileAddFilled />}>
<Link to="/manage/courtesycars/contracts/new">{t("menus.header.courtesycars-newcontract")}</Link>
<Link to="/manage/courtesycars/contracts/new">
{t("menus.header.courtesycars-newcontract")}
</Link>
</Menu.Item>
</Menu.SubMenu>
<Menu.SubMenu key="accounting" icon={<DollarCircleFilled />} title={t("menus.header.accounting")}>
<Menu.Item key="bills" icon={<Icon component={FaFileInvoiceDollar} />}>
<Menu.SubMenu
key="accounting"
icon={<DollarCircleFilled />}
title={t("menus.header.accounting")}
>
<Menu.Item
key="bills"
icon={<Icon component={FaFileInvoiceDollar} />}
>
<Link to="/manage/bills">{t("menus.header.bills")}</Link>
</Menu.Item>
<Menu.Item
@@ -166,7 +226,7 @@ function Header({
onClick={() => {
setBillEnterContext({
actions: {},
context: {}
context: {},
});
}}
>
@@ -175,8 +235,13 @@ function Header({
{Simple_Inventory.treatment === "on" && (
<>
<Menu.Divider key="div4" />
<Menu.Item key="inventory" icon={<Icon component={FaFileInvoiceDollar} />}>
<Link to="/manage/inventory">{t("menus.header.inventory")}</Link>
<Menu.Item
key="inventory"
icon={<Icon component={FaFileInvoiceDollar} />}
>
<Link to="/manage/inventory">
{t("menus.header.inventory")}
</Link>
</Menu.Item>
</>
)}
@@ -189,7 +254,7 @@ function Header({
onClick={() => {
setPaymentContext({
actions: {},
context: null
context: null,
});
}}
icon={<Icon component={FaCreditCard} />}
@@ -202,7 +267,7 @@ function Header({
onClick={() => {
setCardPaymentContext({
actions: {},
context: {}
context: {},
});
}}
icon={<Icon component={FaCreditCard} />}
@@ -212,7 +277,9 @@ function Header({
)}
<Menu.Divider key="div5" />
<Menu.Item key="timetickets" icon={<FieldTimeOutlined />}>
<Link to="/manage/timetickets">{t("menus.header.timetickets")}</Link>
<Link to="/manage/timetickets">
{t("menus.header.timetickets")}
</Link>
</Menu.Item>
<Menu.Item
key="entertimetickets"
@@ -223,31 +290,49 @@ function Header({
context: {
created_by: currentUser.displayName
? currentUser.email.concat(" | ", currentUser.displayName)
: currentUser.email
}
: currentUser.email,
},
});
}}
>
{t("menus.header.entertimeticket")}
</Menu.Item>
<Menu.Divider key="div6" />
<Menu.SubMenu key="accountingexport" title={t("menus.header.export")} icon={<ExportOutlined />}>
<Menu.SubMenu
key="accountingexport"
title={t("menus.header.export")}
icon={<ExportOutlined />}
>
<Menu.Item key="receivables">
<Link to="/manage/accounting/receivables">{t("menus.header.accounting-receivables")}</Link>
<Link to="/manage/accounting/receivables">
{t("menus.header.accounting-receivables")}
</Link>
</Menu.Item>
{(!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber)) ||
{(!(
(bodyshop && bodyshop.cdk_dealerid) ||
(bodyshop && bodyshop.pbs_serialnumber)
) ||
DmsAp.treatment === "on") && (
<Menu.Item key="payables">
<Link to="/manage/accounting/payables">{t("menus.header.accounting-payables")}</Link>
<Link to="/manage/accounting/payables">
{t("menus.header.accounting-payables")}
</Link>
</Menu.Item>
)}
{!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber)) && (
{!(
(bodyshop && bodyshop.cdk_dealerid) ||
(bodyshop && bodyshop.pbs_serialnumber)
) && (
<Menu.Item key="payments">
<Link to="/manage/accounting/payments">{t("menus.header.accounting-payments")}</Link>
<Link to="/manage/accounting/payments">
{t("menus.header.accounting-payments")}
</Link>
</Menu.Item>
)}
<Menu.Item key="export-logs">
<Link to="/manage/accounting/exportlogs">{t("menus.header.export-logs")}</Link>
<Link to="/manage/accounting/exportlogs">
{t("menus.header.export-logs")}
</Link>
</Menu.Item>
</Menu.SubMenu>
</Menu.SubMenu>
@@ -255,11 +340,19 @@ function Header({
<Link to="/manage/phonebook">{t("menus.header.phonebook")}</Link>
</Menu.Item>
<Menu.Item key="temporarydocs" icon={<PaperClipOutlined />}>
<Link to="/manage/temporarydocs">{t("menus.header.temporarydocs")}</Link>
<Link to="/manage/temporarydocs">
{t("menus.header.temporarydocs")}
</Link>
</Menu.Item>
<Menu.SubMenu key="shopsubmenu" title={t("menus.header.shop")} icon={<SettingOutlined />}>
<Menu.SubMenu
key="shopsubmenu"
title={t("menus.header.shop")}
icon={<SettingOutlined />}
>
<Menu.Item key="shop" icon={<Icon component={GiSettingsKnobs} />}>
<Link to="/manage/shop?tab=info">{t("menus.header.shop_config")}</Link>
<Link to="/manage/shop?tab=info">
{t("menus.header.shop_config")}
</Link>
</Menu.Item>
<Menu.Item key="dashboard" icon={<DashboardFilled />}>
<Link to="/manage/dashboard">{t("menus.header.dashboard")}</Link>
@@ -270,20 +363,32 @@ function Header({
onClick={() => {
setReportCenterContext({
actions: {},
context: {}
context: {},
});
}}
>
{t("menus.header.reportcenter")}
</Menu.Item>
<Menu.Item key="shop-vendors" icon={<Icon component={IoBusinessOutline} />}>
<Link to="/manage/shop/vendors">{t("menus.header.shop_vendors")}</Link>
<Menu.Item
key="shop-vendors"
icon={<Icon component={IoBusinessOutline} />}
>
<Link to="/manage/shop/vendors">
{t("menus.header.shop_vendors")}
</Link>
</Menu.Item>
<Menu.Item key="shop-csi" icon={<Icon component={RiSurveyLine} />}>
<Link to="/manage/shop/csi">{t("menus.header.shop_csi")}</Link>
</Menu.Item>
</Menu.SubMenu>
<Menu.SubMenu key="user" title={currentUser.displayName || currentUser.email || t("general.labels.unknown")}>
<Menu.SubMenu
key="user"
title={
currentUser.displayName ||
currentUser.email ||
t("general.labels.unknown")
}
>
<Menu.Item key="signout" danger onClick={() => signOutStart()}>
{t("user.actions.signout")}
</Menu.Item>
@@ -339,6 +444,17 @@ function Header({
</Menu.Item>
))}
</Menu.SubMenu>
<Menu.Item style={{marginLeft: 'auto'}} key="profile">
<Tooltip title="A more modern ImEX Online is ready for you to try! You can switch back at any time.">
<InfoCircleOutlined/>
<span style={{marginRight: 8}}>Try the new ImEX Online</span>
<Switch
checked={betaSwitch}
onChange={betaSwitchChange}
/>
</Tooltip>
</Menu.Item>
</Menu>
</Layout.Header>
);

View File

@@ -5,6 +5,7 @@ import { getFirestore } from "firebase/firestore";
import { getMessaging, getToken, onMessage } from "firebase/messaging";
import { store } from "../redux/store";
import axios from "axios";
import { checkBeta } from "../utils/handleBeta";
const config = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG);
initializeApp(config);
@@ -50,7 +51,7 @@ export { messaging };
export const requestForToken = () => {
return getToken(messaging, {
vapidKey: process.env.REACT_APP_FIREBASE_PUBLIC_VAPID_KEY
vapidKey: process.env.REACT_APP_FIREBASE_PUBLIC_VAPID_KEY,
})
.then((currentToken) => {
if (currentToken) {
@@ -58,7 +59,9 @@ export const requestForToken = () => {
// Perform any other necessary action with the token
} else {
// Show permission request UI
console.log("No registration token available. Request permission to generate one.");
console.log(
"No registration token available. Request permission to generate one."
);
}
})
.catch((err) => {
@@ -77,17 +80,24 @@ export const onMessageListener = () =>
export const logImEXEvent = (eventName, additionalParams, stateProp = null) => {
const state = stateProp || store.getState();
const eventParams = {
shop: (state.user && state.user.bodyshop && state.user.bodyshop.shopname) || null,
user: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
...additionalParams
shop:
(state.user && state.user.bodyshop && state.user.bodyshop.shopname) ||
null,
user:
(state.user && state.user.currentUser && state.user.currentUser.email) ||
null,
...additionalParams,
};
axios.post("/ioevent", {
useremail: (state.user && state.user.currentUser && state.user.currentUser.email) || null,
bodyshopid: (state.user && state.user.bodyshop && state.user.bodyshop.id) || null,
useremail:
(state.user && state.user.currentUser && state.user.currentUser.email) ||
null,
bodyshopid:
(state.user && state.user.bodyshop && state.user.bodyshop.id) || null,
operationName: eventName,
variables: additionalParams,
dbevent: false,
env: "master"
env: checkBeta() ? "beta" : "master",
});
// console.log(

View File

@@ -0,0 +1,47 @@
export const BETA_KEY = "betaSwitchImex";
export const checkBeta = () => {
const cookie = document.cookie.split("; ").find((row) => row.startsWith(BETA_KEY));
return cookie ? cookie.split("=")[1] === "true" : false;
};
export const setBeta = (value) => {
const domain = window.location.hostname.split(".").slice(-2).join(".");
document.cookie = `${BETA_KEY}=${value}; path=/; domain=.${domain}`;
};
export const handleBeta = () => {
if (window.location.hostname.startsWith("localhost")) {
console.log("Not on beta or test, so no need to handle beta.");
return;
}
const isBeta = checkBeta();
const currentHostName = window.location.hostname;
// Determine if the host name starts with "beta" or "www.beta"
const isBetaHost = currentHostName.startsWith("beta.");
const isBetaHostWithWWW = currentHostName.startsWith("www.beta.");
if (isBeta) {
// If beta is on and we are not on a beta domain, redirect to the beta version
if (!isBetaHost && !isBetaHostWithWWW) {
const newHostName = currentHostName.startsWith("www.")
? `www.beta.${currentHostName.replace(/^www\./, "")}`
: `beta.${currentHostName}`;
const href = `${window.location.protocol}//${newHostName}${window.location.pathname}${window.location.search}${window.location.hash}`;
window.location.replace(href);
}
// Otherwise, if beta is on and we're already on a beta domain, stay there
} else {
// If beta is off and we are on a beta domain, redirect to the non-beta version
if (isBetaHost || isBetaHostWithWWW) {
const newHostName = currentHostName.replace(/^www\.beta\./, "www.").replace(/^beta\./, "");
const href = `${window.location.protocol}//${newHostName}${window.location.pathname}${window.location.search}${window.location.hash}`;
window.location.replace(href);
}
// Otherwise, if beta is off and we're not on a beta domain, stay there
}
};
export default handleBeta;

View File

@@ -1 +1,8 @@
[]
- name: Task Reminders
webhook: '{{HASURA_API_URL}}/tasks-remind-handler'
schedule: '*/15 * * * *'
include_in_metadata: true
payload: {}
headers:
- name: event-secret
value_from_env: EVENT_SECRET

View File

@@ -5797,6 +5797,29 @@
- active:
_eq: true
check: null
event_triggers:
- name: tasks_assigned_changed
definition:
enable_manual: false
insert:
columns: '*'
update:
columns:
- assigned_to
retry_conf:
interval_sec: 10
num_retries: 3
timeout_sec: 60
webhook_from_env: HASURA_API_URL
headers:
- name: event-secret
value_from_env: EVENT_SECRET
request_transform:
method: POST
query_params: {}
template_engine: Kriti
url: '{{$base_url}}/tasks-assigned-handler'
version: 2
- table:
name: timetickets
schema: public

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."tasks" add column "remind_at_sent" timestamptz
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."tasks" add column "remind_at_sent" timestamptz
null;