From daa763105678d29c2862fc0072384ea420f7974c Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 7 Jun 2023 11:23:00 -0700 Subject: [PATCH 1/2] Integration IO-2278 schema changes made on wrong branch. --- .../down.sql | 1 + .../up.sql | 18 ++++++++++++++++++ .../down.sql | 1 + .../up.sql | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 hasura/migrations/1685561607407_create_table_public_parts_dispatch/down.sql create mode 100644 hasura/migrations/1685561607407_create_table_public_parts_dispatch/up.sql create mode 100644 hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/down.sql create mode 100644 hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/up.sql diff --git a/hasura/migrations/1685561607407_create_table_public_parts_dispatch/down.sql b/hasura/migrations/1685561607407_create_table_public_parts_dispatch/down.sql new file mode 100644 index 000000000..42325ddf5 --- /dev/null +++ b/hasura/migrations/1685561607407_create_table_public_parts_dispatch/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."parts_dispatch"; diff --git a/hasura/migrations/1685561607407_create_table_public_parts_dispatch/up.sql b/hasura/migrations/1685561607407_create_table_public_parts_dispatch/up.sql new file mode 100644 index 000000000..d8c7c2729 --- /dev/null +++ b/hasura/migrations/1685561607407_create_table_public_parts_dispatch/up.sql @@ -0,0 +1,18 @@ +CREATE TABLE "public"."parts_dispatch" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "jobid" uuid NOT NULL, "number" serial NOT NULL, "employeeid" uuid NOT NULL, "dispatched_at" timestamptz NOT NULL, "dispatched_by" text NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("jobid") REFERENCES "public"."jobs"("id") ON UPDATE cascade ON DELETE cascade); +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_parts_dispatch_updated_at" +BEFORE UPDATE ON "public"."parts_dispatch" +FOR EACH ROW +EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"(); +COMMENT ON TRIGGER "set_public_parts_dispatch_updated_at" ON "public"."parts_dispatch" +IS 'trigger to set value of column "updated_at" to current timestamp on row update'; +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/down.sql b/hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/down.sql new file mode 100644 index 000000000..a12867253 --- /dev/null +++ b/hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."parts_dispatch_lines"; diff --git a/hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/up.sql b/hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/up.sql new file mode 100644 index 000000000..5146e2c7e --- /dev/null +++ b/hasura/migrations/1685561715531_create_table_public_parts_dispatch_lines/up.sql @@ -0,0 +1,18 @@ +CREATE TABLE "public"."parts_dispatch_lines" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "partsdispatchid" UUID NOT NULL, "joblineid" uuid NOT NULL, "quantity" numeric NOT NULL DEFAULT 1, "accepted_at" timestamptz NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("joblineid") REFERENCES "public"."joblines"("id") ON UPDATE cascade ON DELETE cascade); +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_parts_dispatch_lines_updated_at" +BEFORE UPDATE ON "public"."parts_dispatch_lines" +FOR EACH ROW +EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"(); +COMMENT ON TRIGGER "set_public_parts_dispatch_lines_updated_at" ON "public"."parts_dispatch_lines" +IS 'trigger to set value of column "updated_at" to current timestamp on row update'; +CREATE EXTENSION IF NOT EXISTS pgcrypto; From b791f9846f2af7df2136bb344511f66bcff67b6d Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 7 Jun 2023 12:03:17 -0700 Subject: [PATCH 2/2] IO-2329 Change update alert to be permanent. --- .../update-alert/update-alert.component.jsx | 73 +++++++++++++++++++ .../pages/manage/manage.page.component.jsx | 2 + .../pages/manage/manage.page.container.jsx | 2 +- client/src/pages/tech/tech.page.component.jsx | 3 + client/src/pages/tech/tech.page.container.jsx | 2 +- .../redux/application/application.actions.js | 5 ++ .../redux/application/application.reducer.js | 6 ++ .../application/application.selectors.js | 4 + .../redux/application/application.types.js | 1 + client/src/translations/en_us/common.json | 2 +- client/src/utils/RegisterSw.js | 4 + 11 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 client/src/components/update-alert/update-alert.component.jsx 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"),