diff --git a/deployment.md b/deployment.md
new file mode 100644
index 0000000..43f5fd3
--- /dev/null
+++ b/deployment.md
@@ -0,0 +1,5 @@
+Deployment:
+
+Change version to 2.11.2
+Update VARS to HASURA_GRAPHQL_V1_BOOLEAN_NULL_COLLAPSE = true
+
diff --git a/electron/analytics.js b/electron/analytics.js
index 2a45eb7..e011d99 100644
--- a/electron/analytics.js
+++ b/electron/analytics.js
@@ -1,34 +1,34 @@
const { ipcMain } = require("electron");
-const { app } = require("electron");
+//const { app } = require("electron");
const log = require("electron-log");
-const Nucleus = require("nucleus-nodejs");
+//const Nucleus = require("nucleus-nodejs");
const { default: ipcTypes } = require("../src/ipc.types");
-Nucleus.init("5f91b569b95bac34eefdb63a", {
- disableInDev: true,
- debug: false,
- version: app.getVersion(),
-});
+// Nucleus.init("5f91b569b95bac34eefdb63a", {
+// disableInDev: true,
+// debug: false,
+// version: app.getVersion(),
+// });
-Nucleus.setProps({
- version: app.getVersion(),
-});
+// Nucleus.setProps({
+// version: app.getVersion(),
+// });
-Nucleus.onError = (type, err) => {
- log.error(err);
- // type will either be uncaughtException, unhandledRejection or windowError
-};
+// Nucleus.onError = (type, err) => {
+// log.error(err);
+// // type will either be uncaughtException, unhandledRejection or windowError
+// };
ipcMain.on(ipcTypes.app.toMain.setUserName, (event, userName) => {
- Nucleus.setUserId(userName);
- Nucleus.appStarted();
+// Nucleus.setUserId(userName);
+// Nucleus.appStarted();
});
ipcMain.on(ipcTypes.app.toMain.track, (e, args) => {
log.log("NUCLEUS Event", args);
- const { event, ...eventDetails } = args;
+ // const { event, ...eventDetails } = args;
try {
- Nucleus.track(event, eventDetails);
+ //// Nucleus.track(event, eventDetails);
} catch (error) {
log.error(error);
}
diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js
index b7fa4b9..86404ca 100644
--- a/electron/decoder/decoder.js
+++ b/electron/decoder/decoder.js
@@ -8,7 +8,7 @@ const ipcTypes = require("../../src/ipc.types");
const {
NewNotification,
} = require("../notification-wrapper/notification-wrapper");
-const Nucleus = require("nucleus-nodejs");
+//const Nucleus = require("nucleus-nodejs");
async function ImportJob(path) {
const b = BrowserWindow.getAllWindows()[0];
@@ -27,7 +27,7 @@ async function ImportJob(path) {
});
} else {
log.info(`Ignored job. ${newJob.ERROR}`);
- Nucleus.track("IGNORE_JOB", { reason: newJob.ERROR });
+ // Nucleus.track("IGNORE_JOB", { reason: newJob.ERROR });
NewNotification({
title: "Job Ignored",
body: newJob.ERROR,
diff --git a/electron/file-scan/file-scan-ipc.js b/electron/file-scan/file-scan-ipc.js
index f388001..f584988 100644
--- a/electron/file-scan/file-scan-ipc.js
+++ b/electron/file-scan/file-scan-ipc.js
@@ -1,5 +1,5 @@
const { ipcMain } = require("electron");
-const Nucleus = require("nucleus-nodejs");
+//const Nucleus = require("nucleus-nodejs");
const ipcTypes = require("../../src/ipc.types");
const { ImportJob } = require("../decoder/decoder");
const { GetListOfEstimates, DeleteAllEms } = require("./file-scan");
@@ -18,7 +18,7 @@ ipcMain.on(
ipcMain.on(
ipcTypes.default.fileScan.toMain.importJob,
async (event, filePath) => {
- Nucleus.track("IMPORT_JOB_FROM_SCAN");
+ // Nucleus.track("IMPORT_JOB_FROM_SCAN");
await ImportJob(filePath);
}
);
@@ -26,7 +26,7 @@ ipcMain.on(
ipcMain.on(
ipcTypes.default.fileScan.toMain.deleteAllEms,
async (event, filePath) => {
- Nucleus.track("DELETE_ALLEMS");
+ // Nucleus.track("DELETE_ALLEMS");
await DeleteAllEms();
const ret = await GetListOfEstimates();
event.reply(
diff --git a/electron/file-scan/file-scan.js b/electron/file-scan/file-scan.js
index c7328e5..b021eb8 100644
--- a/electron/file-scan/file-scan.js
+++ b/electron/file-scan/file-scan.js
@@ -3,13 +3,11 @@ const fs = require("fs");
const { store } = require("../electron-store");
const log = require("electron-log");
const fsPromises = fs.promises;
-const _ = require("lodash");
const { DecodeEstimate } = require("../decoder/decoder");
-const Nucleus = require("nucleus-nodejs");
-const { format } = require("path");
+//const Nucleus = require("nucleus-nodejs");
async function GetListOfEstimates() {
- Nucleus.track("SCAN_ALL_ESTIMATES");
+ // Nucleus.track("SCAN_ALL_ESTIMATES");
log.info("Scanning all local estimates..");
const ListOfEnvFiles = await GetEnvFiles();
const ListOfSummarizedEstimates = await ReadAllEstimates(ListOfEnvFiles);
diff --git a/electron/file-watcher/file-watcher.js b/electron/file-watcher/file-watcher.js
index 6964e04..2780299 100644
--- a/electron/file-watcher/file-watcher.js
+++ b/electron/file-watcher/file-watcher.js
@@ -8,7 +8,7 @@ const {
NewNotification,
} = require("../notification-wrapper/notification-wrapper");
const log = require("electron-log");
-const Nucleus = require("nucleus-nodejs");
+//const Nucleus = require("nucleus-nodejs");
var watcher;
async function StartWatcher() {
@@ -71,7 +71,7 @@ async function StartWatcher() {
log.error("Error in Watcher", error);
const b = BrowserWindow.getFocusedWindow();
b.webContents.send(ipcTypes.default.fileWatcher.toRenderer.error, error);
- Nucleus.track("WATCHER_ERROR", error);
+ // Nucleus.track("WATCHER_ERROR", error);
})
.on("ready", onWatcherReady)
.on("raw", function (event, path, details) {
diff --git a/electron/main.js b/electron/main.js
index 6dffe9f..7c45c60 100644
--- a/electron/main.js
+++ b/electron/main.js
@@ -15,7 +15,7 @@ const { store } = require("./electron-store");
const { autoUpdater } = require("electron-updater");
const log = require("electron-log");
-const Nucleus = require("nucleus-nodejs");
+//const Nucleus = require("nucleus-nodejs");
require("./ipc-main-handler");
require("./analytics");
@@ -299,12 +299,12 @@ ipcMain.on(ipcTypes.app.toMain.checkForUpdates, (event, args) => {
});
ipcMain.on(ipcTypes.app.toMain.downloadUpdates, (event, args) => {
- Nucleus.track("DOWNLOAD_UPDATE_FROM_RENDERER");
+ //Nucleus.track("DOWNLOAD_UPDATE_FROM_RENDERER");
autoUpdater.downloadUpdate();
});
ipcMain.on(ipcTypes.app.toMain.installUpdates, (event, args) => {
- Nucleus.track("INSTALL_UPDATE_FROM_RENDERER");
+ //Nucleus.track("INSTALL_UPDATE_FROM_RENDERER");
const isSilent = true;
const isForceRunAfter = true;
autoUpdater.quitAndInstall(isSilent, isForceRunAfter);
@@ -316,7 +316,7 @@ autoUpdater.on("download-progress", (ev) => {
});
autoUpdater.on("update-downloaded", (ev, info) => {
- Nucleus.track("UPDATE_DOWNLOADED", ev);
+ //Nucleus.track("UPDATE_DOWNLOADED", ev);
// if (process.env.NODE_ENV === "production") {
mainWindow.webContents.send(ipcTypes.app.toRenderer.downloadProgress, {
...ev,
diff --git a/hasura/metadata/databases/default/tables/public_bodyshops.yaml b/hasura/metadata/databases/default/tables/public_bodyshops.yaml
index 412f510..4296d9d 100644
--- a/hasura/metadata/databases/default/tables/public_bodyshops.yaml
+++ b/hasura/metadata/databases/default/tables/public_bodyshops.yaml
@@ -16,6 +16,13 @@ array_relationships:
table:
name: jobs
schema: public
+ - name: notifications
+ using:
+ foreign_key_constraint_on:
+ column: bodyshopid
+ table:
+ name: notifications
+ schema: public
select_permissions:
- role: user
permission:
diff --git a/hasura/metadata/databases/default/tables/public_notifications.yaml b/hasura/metadata/databases/default/tables/public_notifications.yaml
new file mode 100644
index 0000000..b1bb0d9
--- /dev/null
+++ b/hasura/metadata/databases/default/tables/public_notifications.yaml
@@ -0,0 +1,43 @@
+table:
+ name: notifications
+ schema: public
+object_relationships:
+ - name: bodyshop
+ using:
+ foreign_key_constraint_on: bodyshopid
+select_permissions:
+ - role: user
+ permission:
+ columns:
+ - acceptedat
+ - acceptedby
+ - bodyshopid
+ - created_at
+ - effectivedate
+ - html
+ - id
+ - requiresconfirmation
+ - requiresconfirmationby
+ - updated_at
+ filter:
+ bodyshop:
+ associations:
+ user:
+ authid:
+ _eq: X-Hasura-User-Id
+update_permissions:
+ - role: user
+ permission:
+ columns:
+ - acceptedat
+ - acceptedby
+ filter:
+ _and:
+ - bodyshop:
+ associations:
+ user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - acceptedat:
+ _is_null: true
+ check: null
diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml
index 42b6c18..154b182 100644
--- a/hasura/metadata/databases/default/tables/tables.yaml
+++ b/hasura/metadata/databases/default/tables/tables.yaml
@@ -3,5 +3,6 @@
- "!include public_groupings.yaml"
- "!include public_joblines.yaml"
- "!include public_jobs.yaml"
+- "!include public_notifications.yaml"
- "!include public_users.yaml"
- "!include public_veh_groups.yaml"
diff --git a/hasura/migrations/1602633863978_create_table_public_users/up.sql b/hasura/migrations/1602633863978_create_table_public_users/up.sql
new file mode 100644
index 0000000..c73e743
--- /dev/null
+++ b/hasura/migrations/1602633863978_create_table_public_users/up.sql
@@ -0,0 +1,35 @@
+
+CREATE TABLE "public"."users"("email" text NOT NULL, "authid" text NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("email") );
+CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
+RETURNS TRIGGER AS $$
+DECLARE
+ _new record;
+BEGIN
+ _new := NEW;
+ _new."updated_at" = NOW();
+ RETURN _new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER "set_public_users_updated_at"
+BEFORE UPDATE ON "public"."users"
+FOR EACH ROW
+EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
+COMMENT ON TRIGGER "set_public_users_updated_at" ON "public"."users"
+IS 'trigger to set value of column "updated_at" to current timestamp on row update';
+CREATE TABLE "public"."users"("email" text NOT NULL, "authid" text NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("email") );
+CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
+RETURNS TRIGGER AS $$
+DECLARE
+ _new record;
+BEGIN
+ _new := NEW;
+ _new."updated_at" = NOW();
+ RETURN _new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER "set_public_users_updated_at"
+BEFORE UPDATE ON "public"."users"
+FOR EACH ROW
+EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
+COMMENT ON TRIGGER "set_public_users_updated_at" ON "public"."users"
+IS 'trigger to set value of column "updated_at" to current timestamp on row update';
\ No newline at end of file
diff --git a/hasura/migrations/default/1663277904884_create_table_public_notifications/down.sql b/hasura/migrations/default/1663277904884_create_table_public_notifications/down.sql
new file mode 100644
index 0000000..6fc4e30
--- /dev/null
+++ b/hasura/migrations/default/1663277904884_create_table_public_notifications/down.sql
@@ -0,0 +1 @@
+DROP TABLE "public"."notifications";
diff --git a/hasura/migrations/default/1663277904884_create_table_public_notifications/up.sql b/hasura/migrations/default/1663277904884_create_table_public_notifications/up.sql
new file mode 100644
index 0000000..75423c3
--- /dev/null
+++ b/hasura/migrations/default/1663277904884_create_table_public_notifications/up.sql
@@ -0,0 +1,17 @@
+CREATE TABLE "public"."notifications" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "bodyshopid" uuid, "effectivedate" timestamptz NOT NULL, "html" text NOT NULL, "acceptedat" timestamptz, "acceptedby" text, "requiresaacceptance" text NOT NULL DEFAULT 'false', PRIMARY KEY ("id") , FOREIGN KEY ("bodyshopid") REFERENCES "public"."bodyshops"("id") ON UPDATE restrict ON DELETE restrict);
+CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
+RETURNS TRIGGER AS $$
+DECLARE
+ _new record;
+BEGIN
+ _new := NEW;
+ _new."updated_at" = NOW();
+ RETURN _new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER "set_public_notifications_updated_at"
+BEFORE UPDATE ON "public"."notifications"
+FOR EACH ROW
+EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
+COMMENT ON TRIGGER "set_public_notifications_updated_at" ON "public"."notifications"
+IS 'trigger to set value of column "updated_at" to current timestamp on row update';
diff --git a/hasura/migrations/default/1663278102853_alter_table_public_notifications_drop_column_requiresaacceptance/down.sql b/hasura/migrations/default/1663278102853_alter_table_public_notifications_drop_column_requiresaacceptance/down.sql
new file mode 100644
index 0000000..d6f67d7
--- /dev/null
+++ b/hasura/migrations/default/1663278102853_alter_table_public_notifications_drop_column_requiresaacceptance/down.sql
@@ -0,0 +1,3 @@
+alter table "public"."notifications" alter column "requiresaacceptance" set default ''false'::text';
+alter table "public"."notifications" alter column "requiresaacceptance" drop not null;
+alter table "public"."notifications" add column "requiresaacceptance" text;
diff --git a/hasura/migrations/default/1663278102853_alter_table_public_notifications_drop_column_requiresaacceptance/up.sql b/hasura/migrations/default/1663278102853_alter_table_public_notifications_drop_column_requiresaacceptance/up.sql
new file mode 100644
index 0000000..c1c5f36
--- /dev/null
+++ b/hasura/migrations/default/1663278102853_alter_table_public_notifications_drop_column_requiresaacceptance/up.sql
@@ -0,0 +1 @@
+alter table "public"."notifications" drop column "requiresaacceptance" cascade;
diff --git a/hasura/migrations/default/1663278122231_alter_table_public_notifications_add_column_requiresconfirmation/down.sql b/hasura/migrations/default/1663278122231_alter_table_public_notifications_add_column_requiresconfirmation/down.sql
new file mode 100644
index 0000000..e8faa06
--- /dev/null
+++ b/hasura/migrations/default/1663278122231_alter_table_public_notifications_add_column_requiresconfirmation/down.sql
@@ -0,0 +1,4 @@
+-- Could not auto-generate a down migration.
+-- Please write an appropriate down migration for the SQL below:
+-- alter table "public"."notifications" add column "requiresconfirmation" boolean
+-- not null default 'false';
diff --git a/hasura/migrations/default/1663278122231_alter_table_public_notifications_add_column_requiresconfirmation/up.sql b/hasura/migrations/default/1663278122231_alter_table_public_notifications_add_column_requiresconfirmation/up.sql
new file mode 100644
index 0000000..fb48de3
--- /dev/null
+++ b/hasura/migrations/default/1663278122231_alter_table_public_notifications_add_column_requiresconfirmation/up.sql
@@ -0,0 +1,2 @@
+alter table "public"."notifications" add column "requiresconfirmation" boolean
+ not null default 'false';
diff --git a/hasura/migrations/default/1663278170291_alter_table_public_notifications_add_column_requiresconfirmationby/down.sql b/hasura/migrations/default/1663278170291_alter_table_public_notifications_add_column_requiresconfirmationby/down.sql
new file mode 100644
index 0000000..5e46737
--- /dev/null
+++ b/hasura/migrations/default/1663278170291_alter_table_public_notifications_add_column_requiresconfirmationby/down.sql
@@ -0,0 +1,4 @@
+-- Could not auto-generate a down migration.
+-- Please write an appropriate down migration for the SQL below:
+-- alter table "public"."notifications" add column "requiresconfirmationby" timestamptz
+-- null;
diff --git a/hasura/migrations/default/1663278170291_alter_table_public_notifications_add_column_requiresconfirmationby/up.sql b/hasura/migrations/default/1663278170291_alter_table_public_notifications_add_column_requiresconfirmationby/up.sql
new file mode 100644
index 0000000..58fed55
--- /dev/null
+++ b/hasura/migrations/default/1663278170291_alter_table_public_notifications_add_column_requiresconfirmationby/up.sql
@@ -0,0 +1,2 @@
+alter table "public"."notifications" add column "requiresconfirmationby" timestamptz
+ null;
diff --git a/src/components/molecules/notification-display/notification-display.molecule.jsx b/src/components/molecules/notification-display/notification-display.molecule.jsx
new file mode 100644
index 0000000..dacd528
--- /dev/null
+++ b/src/components/molecules/notification-display/notification-display.molecule.jsx
@@ -0,0 +1,70 @@
+import { useMutation } from "@apollo/client";
+import { Button, Card, Form, Input, Space } from "antd";
+import React from "react";
+import { useState } from "react";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { ACCEPT_NOTIFICATION } from "../../../graphql/notification.queries";
+import { checkForNotification } from "../../../redux/user/user.actions";
+const mapStateToProps = createStructuredSelector({
+ //currentUser: selectCurrentUser
+});
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+ checkForNotification: () => dispatch(checkForNotification()),
+});
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(NotificationDisplayMolecule);
+
+export function NotificationDisplayMolecule({
+ notification,
+ checkForNotification,
+}) {
+ const [acceptNotification] = useMutation(ACCEPT_NOTIFICATION);
+ const [loading, setLoading] = useState(false);
+ const handleConfirm = async (values) => {
+ console.log("form submit", notification, values);
+ setLoading(true);
+ await acceptNotification({
+ variables: {
+ id: notification.id,
+ notification: { acceptedby: values.acceptedby, acceptedat: new Date() },
+ },
+ });
+ checkForNotification();
+ setLoading(false);
+ };
+ const handleDismiss = async () => {};
+ const [form] = Form.useForm();
+ return (
+
+
+ {notification.requiresconfirmation ? (
+
+ ) : (
+
+ )}
+
+ );
+}
diff --git a/src/components/organisms/notification-modal/notification-modal.organism.jsx b/src/components/organisms/notification-modal/notification-modal.organism.jsx
new file mode 100644
index 0000000..5676e0c
--- /dev/null
+++ b/src/components/organisms/notification-modal/notification-modal.organism.jsx
@@ -0,0 +1,30 @@
+import { Modal } from "antd";
+import React from "react";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { selectNotifications } from "../../../redux/user/user.selectors";
+import NotificationDisplayMolecule from "../../molecules/notification-display/notification-display.molecule";
+const mapStateToProps = createStructuredSelector({
+ //currentUser: selectCurrentUser
+ notifications: selectNotifications,
+});
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+});
+export default connect(mapStateToProps, mapDispatchToProps)(NotificationModal);
+
+export function NotificationModal({ notifications }) {
+ if (!notifications || notifications.length === 0) return null;
+ return (
+ 0}
+ closable={false}
+ footer={null}
+ >
+ {notifications &&
+ notifications.map((n) => (
+
+ ))}
+
+ );
+}
diff --git a/src/components/pages/routes/routes.page.jsx b/src/components/pages/routes/routes.page.jsx
index 9c9e24c..e6fb3f8 100644
--- a/src/components/pages/routes/routes.page.jsx
+++ b/src/components/pages/routes/routes.page.jsx
@@ -7,6 +7,7 @@ import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../../redux/user/user.selectors";
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
import ReleaseNotes from "../../molecules/release-notes/release-notes.molecule";
+import NotificationModalOrganism from "../../organisms/notification-modal/notification-modal.organism";
import SiderMenuOrganism from "../../organisms/sider-menu/sider-menu.organism";
import UpdateManagerOrganism from "../../organisms/update-manager/update-manager.organism";
import JobsPage from "../jobs/jobs.page";
@@ -37,6 +38,7 @@ export function RoutesPage({ bodyshop }) {
+
} />
} />
diff --git a/src/graphql/bodyshop.queries.js b/src/graphql/bodyshop.queries.js
index e66da44..8ab325c 100644
--- a/src/graphql/bodyshop.queries.js
+++ b/src/graphql/bodyshop.queries.js
@@ -16,7 +16,7 @@ export const UPDATE_SHOP = gql`
mutation UPDATE_SHOP($id: uuid, $shop: bodyshops_set_input!) {
update_bodyshops(where: { id: { _eq: $id } }, _set: $shop) {
returning {
- id
+ id
shopname
targets
accepted_ins_co
@@ -26,3 +26,18 @@ export const UPDATE_SHOP = gql`
}
}
`;
+
+export const QUERY_NOTIFICATIONS = gql`
+ query QUERY_NOTIFICATIONS($now: timestamptz) {
+ notifications(
+ where: { acceptedat: { _is_null: true }, effectivedate: { _lte: $now } }
+ ) {
+ effectivedate
+ html
+ id
+ requiresconfirmation
+ requiresconfirmationby
+ updated_at
+ }
+ }
+`;
diff --git a/src/graphql/notification.queries.js b/src/graphql/notification.queries.js
new file mode 100644
index 0000000..2a948a7
--- /dev/null
+++ b/src/graphql/notification.queries.js
@@ -0,0 +1,18 @@
+import gql from "graphql-tag";
+
+export const ACCEPT_NOTIFICATION = gql`
+ mutation ACCEPT_NOTIFICATION(
+ $id: Int!
+ $notification: notifications_set_input
+ ) {
+ update_notifications_by_pk(pk_columns: { id: $id }, _set: $notification) {
+ html
+ id
+ requiresconfirmation
+ requiresconfirmationby
+ updated_at
+ acceptedat
+ effectivedate
+ }
+ }
+`;
diff --git a/src/ipc/suvs.json b/src/ipc/suvs.json
index 494cd73..eba4efb 100644
--- a/src/ipc/suvs.json
+++ b/src/ipc/suvs.json
@@ -150,6 +150,7 @@
"UPLANDER",
"YUKON",
"YUKON DENALI",
+ "YUKON XL",
"EQUINOX LS",
"EQUINOX LT",
"EQUINOX PREMIER",
@@ -164,6 +165,7 @@
"RAV4 XLE HYBRID",
"HIGHLANDER",
"4RUNNER",
+ "SEQUOIA",
"PATHFINDER SE",
"PATHFINDER SL",
diff --git a/src/redux/user/user.actions.js b/src/redux/user/user.actions.js
index ba06e36..db83b3e 100644
--- a/src/redux/user/user.actions.js
+++ b/src/redux/user/user.actions.js
@@ -85,3 +85,10 @@ export const validatePasswordResetFailure = (error) => ({
payload: error,
});
+export const setNotification = (notificationObject) => ({
+ type: UserActionTypes.SET_NOTIFICATIONS,
+ payload: notificationObject,
+});
+export const checkForNotification = () => ({
+ type: UserActionTypes.CHECK_FOR_NOTIFICATION,
+});
diff --git a/src/redux/user/user.reducer.js b/src/redux/user/user.reducer.js
index 840eeb2..0c46460 100644
--- a/src/redux/user/user.reducer.js
+++ b/src/redux/user/user.reducer.js
@@ -15,10 +15,13 @@ const INITIAL_STATE = {
success: false,
},
loginLoading: false,
+ notifications: null,
};
const userReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
+ case UserActionTypes.SET_NOTIFICATIONS:
+ return { ...state, notifications: action.payload };
case UserActionTypes.SET_SHOP_DETAILS:
return { ...state, bodyshop: action.payload };
case UserActionTypes.SET_LOCAL_FINGERPRINT:
diff --git a/src/redux/user/user.sagas.js b/src/redux/user/user.sagas.js
index f3a8e6c..c5f46fe 100644
--- a/src/redux/user/user.sagas.js
+++ b/src/redux/user/user.sagas.js
@@ -1,12 +1,16 @@
-import { message } from "antd";
+import { message, notification } from "antd";
+import moment from "moment";
//import LogRocket from "logrocket";
-import { all, call, put, takeLatest } from "redux-saga/effects";
+import { all, call, put, takeLatest, delay } from "redux-saga/effects";
import {
auth,
getCurrentUser,
updateCurrentUser,
} from "../../firebase/firebase.utils";
-import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
+import {
+ QUERY_BODYSHOP,
+ QUERY_NOTIFICATIONS,
+} from "../../graphql/bodyshop.queries";
import client from "../../graphql/GraphQLClient";
import { UPSERT_USER } from "../../graphql/user.queries";
import ipcTypes from "../../ipc.types";
@@ -20,6 +24,8 @@ import {
signOutSuccess,
unauthorizedUser,
updateUserDetailsSuccess,
+ checkForNotification,
+ setNotification,
} from "./user.actions";
import UserActionTypes from "./user.types";
@@ -144,6 +150,8 @@ export function* signInSuccessSaga({ payload }) {
ipcRenderer.send(ipcTypes.default.fileWatcher.toMain.start, {
startup: true,
});
+ yield put(checkForNotification());
+ //Check for notifications, and continue to check.
} else {
console.log("No bodyshop has been associated.");
yield put(setBodyshop(false));
@@ -153,6 +161,27 @@ export function* signInSuccessSaga({ payload }) {
// yield logImEXEvent("redux_sign_in_success");
}
+export function* onCheckForNotification() {
+ yield takeLatest(
+ UserActionTypes.CHECK_FOR_NOTIFICATION,
+ checkForNotificationSaga
+ );
+}
+export function* checkForNotificationSaga() {
+ const {
+ data: { notifications },
+ } = yield client.query({
+ query: QUERY_NOTIFICATIONS,
+ variables: { now: moment() },
+ });
+
+ if (notifications) {
+ yield put(setNotification(notifications));
+ }
+ yield delay(4 * 60 * 60 * 1000);
+ yield put(checkForNotification());
+}
+
export function* onSendPasswordResetStart() {
yield takeLatest(
UserActionTypes.SEND_PASSWORD_RESET_EMAIL_START,
@@ -181,6 +210,7 @@ export function* userSagas() {
call(onUpdateUserDetails),
call(onSignInSuccess),
call(onSendPasswordResetStart),
+ call(onCheckForNotification),
]);
}
diff --git a/src/redux/user/user.selectors.js b/src/redux/user/user.selectors.js
index 79180d8..b93be58 100644
--- a/src/redux/user/user.selectors.js
+++ b/src/redux/user/user.selectors.js
@@ -26,3 +26,7 @@ export const selectLoginLoading = createSelector(
[selectUser],
(user) => user.loginLoading
);
+export const selectNotifications = createSelector(
+ [selectUser],
+ (user) => user.notifications
+);
diff --git a/src/redux/user/user.types.js b/src/redux/user/user.types.js
index 1ee363c..a007723 100644
--- a/src/redux/user/user.types.js
+++ b/src/redux/user/user.types.js
@@ -27,5 +27,7 @@ const UserActionTypes = {
VALIDATE_PASSWORD_RESET_SUCCESS: "VALIDATE_PASSWORD_RESET_SUCCESS",
VALIDATE_PASSWORD_RESET_FAILURE: "VALIDATE_PASSWORD_RESET_FAILURE",
SET_AUTH_LEVEL: "SET_AUTH_LEVEL",
+ CHECK_FOR_NOTIFICATION: "CHECK_FOR_NOTIFICATION",
+ SET_NOTIFICATIONS: "SET_NOTIFICATIONS",
};
-export default UserActionTypes;
+export default UserActionTypes;