diff --git a/electron-builder.yml b/electron-builder.yml index 24a43d6..5789e01 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -15,7 +15,7 @@ files: asarUnpack: - resources/** win: - executableName: Shop Partner + executableName: ShopPartner icon: resources/diamond.png azureSignOptions: endpoint: https://eus.codesigning.azure.net diff --git a/src/main/index.ts b/src/main/index.ts index e9b69b7..6c6fd65 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -41,6 +41,8 @@ function createWindow(): void { x, y, show: false, + minWidth: 600, + minHeight: 400, //autoHideMenuBar: true, ...(process.platform === "linux" ? { icon } : {}), webPreferences: { diff --git a/src/main/ipc/ipcMainConfig.ts b/src/main/ipc/ipcMainConfig.ts index 98b0f3d..78efde1 100644 --- a/src/main/ipc/ipcMainConfig.ts +++ b/src/main/ipc/ipcMainConfig.ts @@ -13,7 +13,10 @@ import { SettingsWatcherPollingGet, SettingsWatcherPollingSet, } from "./ipcMainHandler.settings"; -import { ipcMainHandleAuthStateChanged } from "./ipcMainHandler.user"; +import { + ipcMainHandleAuthStateChanged, + ipMainHandleResetPassword, +} from "./ipcMainHandler.user"; // Log all IPC messages and their payloads const logIpcMessages = (): void => { @@ -47,6 +50,7 @@ ipcMain.on(ipcTypes.toMain.test, () => //Auth handler ipcMain.on(ipcTypes.toMain.authStateChanged, ipcMainHandleAuthStateChanged); +ipcMain.on(ipcTypes.toMain.user.resetPassword, ipMainHandleResetPassword); //Add debug handlers if in development if (import.meta.env.DEV) { diff --git a/src/main/ipc/ipcMainHandler.user.ts b/src/main/ipc/ipcMainHandler.user.ts index b7874c0..4a00f4a 100644 --- a/src/main/ipc/ipcMainHandler.user.ts +++ b/src/main/ipc/ipcMainHandler.user.ts @@ -1,4 +1,4 @@ -import { IpcMainEvent } from "electron"; +import { IpcMainEvent, shell } from "electron"; import log from "electron-log/main"; import { autoUpdater } from "electron-updater"; import { User } from "firebase/auth"; @@ -10,39 +10,59 @@ import { QUERY_MASTERDATA_TYPED, } from "../graphql/queries"; import Store from "../store/store"; +import errorTypeCheck from "../../util/errorTypeCheck"; +import { sendIpcToRenderer } from "../util/toRenderer"; +import ipcTypes from "../../util/ipcTypes.json"; const ipcMainHandleAuthStateChanged = async ( - event: IpcMainEvent, + _event: IpcMainEvent, user: User | null, ): Promise => { Store.set("user", user); + try { + //Need to query the currently active shop, and store the metadata as well. + //Also need to query the OP Codes for decoding reference. + const activeBodyshop: ActiveBodyshopQueryResult = await client.request( + QUERY_ACTIVE_BODYSHOP_TYPED, + ); - //Need to query the currently active shop, and store the metadata as well. - //Also need to query the OP Codes for decoding reference. - const activeBodyshop: ActiveBodyshopQueryResult = await client.request( - QUERY_ACTIVE_BODYSHOP_TYPED, - ); + Store.set("app.bodyshop", activeBodyshop.bodyshops[0]); - Store.set("app.bodyshop", activeBodyshop.bodyshops[0]); + const OpCodes: MasterdataQueryResult = await client.request( + QUERY_MASTERDATA_TYPED, + { + key: `${activeBodyshop.bodyshops[0].region_config}_ciecaopcodes`, + }, + ); + Store.set( + "app.masterdata.opcodes", + JSON.parse(OpCodes.masterdata[0]?.value), + ); + log.debug("Received authentication state change from Renderer.", user); + log.debug("Requery shop information & master data."); - const OpCodes: MasterdataQueryResult = await client.request( - QUERY_MASTERDATA_TYPED, - { - key: `${activeBodyshop.bodyshops[0].region_config}_ciecaopcodes`, - }, - ); - Store.set("app.masterdata.opcodes", JSON.parse(OpCodes.masterdata[0]?.value)); - log.debug("Received authentication state change from Renderer.", user); - log.debug("Requery shop information & master data."); - - //Check for updates - const convCo = activeBodyshop.bodyshops[0].convenient_company; - if (convCo === "alpha") { - autoUpdater.channel = "alpha"; - } else if (convCo === "beta") { - autoUpdater.channel = "beta"; + //Check for updates + const convCo = activeBodyshop.bodyshops[0].convenient_company; + if (convCo === "alpha") { + autoUpdater.channel = "alpha"; + } else if (convCo === "beta") { + autoUpdater.channel = "beta"; + } + } catch (error) { + log.error( + "Error while querying active bodyshop or masterdata", + errorTypeCheck(error), + ); + sendIpcToRenderer( + ipcTypes.toRenderer.general.showErrorMessage, + "Error connecting to ImEX Online servers to get shop data. Please try again.", + ); } autoUpdater.checkForUpdatesAndNotify(); }; -export { ipcMainHandleAuthStateChanged }; +const ipMainHandleResetPassword = async (): Promise => { + shell.openExternal("https://imex.online/resetpassword"); +}; + +export { ipcMainHandleAuthStateChanged, ipMainHandleResetPassword }; diff --git a/src/main/util/toRenderer.ts b/src/main/util/toRenderer.ts new file mode 100644 index 0000000..9c5754b --- /dev/null +++ b/src/main/util/toRenderer.ts @@ -0,0 +1,21 @@ +import { BrowserWindow } from "electron"; +import log from "electron-log/main"; + +const getMainWindow = (): Electron.BrowserWindow => { + const mainWindow = BrowserWindow.getAllWindows()[0]; + return mainWindow; +}; + +const sendIpcToRenderer = (ipcMessage: string, ...args: any[]): void => { + const window = getMainWindow(); + if (window) { + window.webContents.send(ipcMessage, ...args); + } else { + log.error( + "Unable to find main window. Cannot send IPC message.", + ipcMessage, + args, + ); + } +}; +export { getMainWindow, sendIpcToRenderer }; diff --git a/src/renderer/src/components/ErrorBoundaryFallback/ErrorBoundaryFallback.tsx b/src/renderer/src/components/ErrorBoundaryFallback/ErrorBoundaryFallback.tsx index fb97767..4cdc314 100644 --- a/src/renderer/src/components/ErrorBoundaryFallback/ErrorBoundaryFallback.tsx +++ b/src/renderer/src/components/ErrorBoundaryFallback/ErrorBoundaryFallback.tsx @@ -12,7 +12,7 @@ const ErrorBoundaryFallback: React.FC = ({ return ( diff --git a/src/renderer/src/components/Settings/Settings.Watcher.tsx b/src/renderer/src/components/Settings/Settings.Watcher.tsx index b19554d..644daa5 100644 --- a/src/renderer/src/components/Settings/Settings.Watcher.tsx +++ b/src/renderer/src/components/Settings/Settings.Watcher.tsx @@ -73,7 +73,7 @@ const SettingsWatcher: React.FC = () => { return ( - + {isWatcherStarted ? ( + + + + {error && ( )} - - - + ); }; diff --git a/src/renderer/src/util/ipcRendererHandler.ts b/src/renderer/src/util/ipcRendererHandler.ts index 75feccc..56a516c 100644 --- a/src/renderer/src/util/ipcRendererHandler.ts +++ b/src/renderer/src/util/ipcRendererHandler.ts @@ -12,6 +12,8 @@ import { import store from "@renderer/redux/redux-store"; import ipcTypes from "../../../util/ipcTypes.json"; import { auth } from "./firebase"; +import { notification } from "antd"; +import i18n from "./i18n"; const ipcRenderer = window.electron.ipcRenderer; const dispatch = store.dispatch; @@ -74,3 +76,13 @@ ipcRenderer.on( ); }, ); + +ipcRenderer.on( + ipcTypes.toRenderer.general.showErrorMessage, + (_event: Electron.IpcRendererEvent, error) => { + notification.error({ + message: i18n.t("errors.notificationtitle"), + description: error, + }); + }, +); diff --git a/src/util/ipcTypes.json b/src/util/ipcTypes.json index dd43bf9..195d6ea 100644 --- a/src/util/ipcTypes.json +++ b/src/util/ipcTypes.json @@ -27,7 +27,8 @@ }, "user": { "getTokenResponse": "toMain_user_getTokenResponse", - "getActiveShop": "toMain_user_getActiveShopify" + "getActiveShop": "toMain_user_getActiveShopify", + "resetPassword": "toMain_user_resetPassword" } }, "toRenderer": { @@ -48,6 +49,9 @@ }, "user": { "getToken": "toRenderer_user_getToken" + }, + "general": { + "showErrorMessage": "toRenderer_general_showErrorMessage" } } } diff --git a/src/util/translations/en-US/renderer.json b/src/util/translations/en-US/renderer.json index c5a1c0e..879d190 100644 --- a/src/util/translations/en-US/renderer.json +++ b/src/util/translations/en-US/renderer.json @@ -10,6 +10,10 @@ "resetpassword": "Reset Password" } }, + "errors": { + "errorboundary": "Uh oh - we've hit an error.", + "notificationtitle": "Error Encountered" + }, "navigation": { "home": "Home", "settings": "Settings", diff --git a/translations.babel b/translations.babel index 824dc99..3577ab2 100644 --- a/translations.babel +++ b/translations.babel @@ -112,6 +112,37 @@ + + errors + + + errorboundary + false + + + + + + en-US + false + + + + + notificationtitle + false + + + + + + en-US + false + + + + + navigation