diff --git a/client/src/components/update-alert/update-alert.component.jsx b/client/src/components/update-alert/update-alert.component.jsx
new file mode 100644
index 000000000..59febd90c
--- /dev/null
+++ b/client/src/components/update-alert/update-alert.component.jsx
@@ -0,0 +1,73 @@
+import { Alert, Button, Space } from "antd";
+import i18n from "i18next";
+import React from "react";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { selectUpdateAvailable } from "../../redux/application/application.selectors";
+import { AlertOutlined } from "@ant-design/icons";
+import { useTranslation } from "react-i18next";
+import { setUpdateAvailable } from "../../redux/application/application.actions";
+import { store } from "../../redux/store";
+import * as serviceWorkerRegistration from "../../serviceWorkerRegistration";
+
+let globalRegistration;
+
+const mapStateToProps = createStructuredSelector({
+ updateAvailable: selectUpdateAvailable,
+});
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+});
+export default connect(mapStateToProps, mapDispatchToProps)(UpdateAlert);
+
+export function UpdateAlert({ updateAvailable }) {
+ const { t } = useTranslation();
+ if (!updateAvailable) return null;
+ return (
+ }
+ description={t("general.messages.newversionmessage")}
+ closable={false}
+ type="warning"
+ action={
+
+
+
+
+ }
+ />
+ );
+}
+
+const onServiceWorkerUpdate = (registration) => {
+ console.log("onServiceWorkerUpdate", registration);
+ globalRegistration = registration;
+ store.dispatch(setUpdateAvailable(true));
+};
+store.dispatch(setUpdateAvailable(true));
+
+serviceWorkerRegistration.register({ onUpdate: onServiceWorkerUpdate });
diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx
index f8ed14fcd..bd63cd011 100644
--- a/client/src/pages/manage/manage.page.component.jsx
+++ b/client/src/pages/manage/manage.page.component.jsx
@@ -25,6 +25,7 @@ import {
import * as Sentry from "@sentry/react";
import "./manage.page.styles.scss";
+import UpdateAlert from "../../components/update-alert/update-alert.component";
const ManageRootPage = lazy(() =>
import("../manage-root/manage-root.page.container")
@@ -394,6 +395,7 @@ export function Manage({ match, conflict, bodyshop }) {
<>
+
diff --git a/client/src/pages/manage/manage.page.container.jsx b/client/src/pages/manage/manage.page.container.jsx
index 75f4da328..04505ce2a 100644
--- a/client/src/pages/manage/manage.page.container.jsx
+++ b/client/src/pages/manage/manage.page.container.jsx
@@ -6,7 +6,7 @@ import AlertComponent from "../../components/alert/alert.component";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
import { setBodyshop } from "../../redux/user/user.actions";
-import "../../utils/RegisterSw";
+//import "../../utils/RegisterSw";
import ManagePage from "./manage.page.component";
const mapDispatchToProps = (dispatch) => ({
diff --git a/client/src/pages/tech/tech.page.component.jsx b/client/src/pages/tech/tech.page.component.jsx
index f7639a473..50219f72d 100644
--- a/client/src/pages/tech/tech.page.component.jsx
+++ b/client/src/pages/tech/tech.page.component.jsx
@@ -12,6 +12,7 @@ import TechSider from "../../components/tech-sider/tech-sider.component";
import { selectTechnician } from "../../redux/tech/tech.selectors";
import FeatureWrapper from "../../components/feature-wrapper/feature-wrapper.component";
import "./tech.page.styles.scss";
+import UpdateAlert from "../../components/update-alert/update-alert.component";
const TimeTicketModalContainer = lazy(() =>
import("../../components/time-ticket-modal/time-ticket-modal.container")
);
@@ -56,7 +57,9 @@ export function TechPage({ technician, match }) {
{technician ? null : }
+
+
({
type: ApplicationActionTypes.SET_PROBLEM_JOBS,
payload: problemJobs,
});
+
+export const setUpdateAvailable = (isUpdateAvailable) => ({
+ type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
+ payload: isUpdateAvailable,
+});
diff --git a/client/src/redux/application/application.reducer.js b/client/src/redux/application/application.reducer.js
index 95579574a..0b428209b 100644
--- a/client/src/redux/application/application.reducer.js
+++ b/client/src/redux/application/application.reducer.js
@@ -3,6 +3,7 @@ import ApplicationActionTypes from "./application.types";
const INITIAL_STATE = {
loading: false,
online: true,
+ updateAvailable: false,
breadcrumbs: [],
recentItems: [],
selectedHeader: "home",
@@ -18,6 +19,11 @@ const INITIAL_STATE = {
const applicationReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
+ case ApplicationActionTypes.SET_UPDATE_AVAILABLE:
+ return {
+ ...state,
+ updateAvailable: action.payload,
+ };
case ApplicationActionTypes.SET_SELECTED_HEADER:
return {
...state,
diff --git a/client/src/redux/application/application.selectors.js b/client/src/redux/application/application.selectors.js
index cb5e2c679..e9b293d62 100644
--- a/client/src/redux/application/application.selectors.js
+++ b/client/src/redux/application/application.selectors.js
@@ -48,3 +48,7 @@ export const selectProblemJobs = createSelector(
[selectApplication],
(application) => application.problemJobs
);
+export const selectUpdateAvailable = createSelector(
+ [selectApplication],
+ (application) => application.updateAvailable
+);
diff --git a/client/src/redux/application/application.types.js b/client/src/redux/application/application.types.js
index 1e047bb82..9b95dd6ee 100644
--- a/client/src/redux/application/application.types.js
+++ b/client/src/redux/application/application.types.js
@@ -12,5 +12,6 @@ const ApplicationActionTypes = {
SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
+ SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE"
};
export default ApplicationActionTypes;
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index b93d0c0a4..b857ca7c8 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -1118,7 +1118,7 @@
},
"messages": {
"exception": "$t(titles.app) has encountered an error. Please try again. If the problem persists, please submit a support ticket or contact us.",
- "newversionmessage": "Click refresh below to update to the latest available version of ImEX Online. Please make sure all other tabs and windows are closed.",
+ "newversionmessage": "Click refresh to update to the latest available version of ImEX Online. Please make sure all other tabs and windows are closed.",
"newversiontitle": "New version of ImEX Online Available",
"noacctfilepath": "There is no accounting file path set. You will not be able to export any items.",
"nofeatureaccess": "You do not have access to this feature of ImEX Online. Please contact support to request a license for this feature.",
diff --git a/client/src/utils/RegisterSw.js b/client/src/utils/RegisterSw.js
index 8b2477b8e..0b3bce09c 100644
--- a/client/src/utils/RegisterSw.js
+++ b/client/src/utils/RegisterSw.js
@@ -3,6 +3,7 @@ import { Button, notification, Space } from "antd";
import i18n from "i18next";
import React from "react";
import * as serviceWorkerRegistration from "../serviceWorkerRegistration";
+import { store } from "../redux/store";
const onServiceWorkerUpdate = (registration) => {
console.log("onServiceWorkerUpdate", registration);
@@ -33,6 +34,9 @@ const onServiceWorkerUpdate = (registration) => {
);
+
+ store.dispatch()
+
notification.open({
icon: ,
message: i18n.t("general.messages.newversiontitle"),