diff --git a/.env.imex b/.env.imex
new file mode 100644
index 0000000..a772856
--- /dev/null
+++ b/.env.imex
@@ -0,0 +1,4 @@
+VITE_FIREBASE_CONFIG={"apiKey":"AIzaSyDSezy-jGJreo7ulgpLdlpOwAOrgcaEkhU","authDomain":"imex-prod.firebaseapp.com","databaseURL":"https://imex-prod.firebaseio.com","projectId":"imex-prod","storageBucket":"imex-prod.appspot.com","messagingSenderId":"253497221485","appId":"1:253497221485:web:3c81c483b94db84b227a64","measurementId":"G-NTWBKG2L0M"}
+VITE_GRAPHQL_ENDPOINT=https://db.imex.online/v1/graphql
+VITE_FIREBASE_CONFIG_TEST={ "apiKey":"AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c", "authDomain":"imex-test.firebaseapp.com", "projectId":"imex-test", "storageBucket":"imex-test.appspot.com", "messagingSenderId":"991923618608", "appId":"1:991923618608:web:633437569cdad78299bef5", "measurementId":"G-TW0XLZEH18"}
+VITE_GRAPHQL_ENDPOINT_TEST=https://db.test.bodyshop.app/v1/graphql
\ No newline at end of file
diff --git a/.env.local b/.env.local
index b44ada4..704063a 100644
--- a/.env.local
+++ b/.env.local
@@ -1,2 +1,4 @@
VITE_FIREBASE_CONFIG={"apiKey":"AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc","authDomain":"imex-dev.firebaseapp.com","databaseURL":"https://imex-dev.firebaseio.com","projectId":"imex-dev","storageBucket":"imex-dev.appspot.com","messagingSenderId":"759548147434","appId":"1:759548147434:web:e8239868a48ceb36700993","measurementId":"G-K5XRBVVB4S"}
-VITE_GRAPHQL_ENDPOINT=https://db.dev.imex.online/v1/graphql
\ No newline at end of file
+VITE_GRAPHQL_ENDPOINT=https://db.dev.imex.online/v1/graphql
+VITE_FIREBASE_CONFIG_TEST={ "apiKey":"AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c", "authDomain":"imex-test.firebaseapp.com", "projectId":"imex-test", "storageBucket":"imex-test.appspot.com", "messagingSenderId":"991923618608", "appId":"1:991923618608:web:633437569cdad78299bef5", "measurementId":"G-TW0XLZEH18"}
+VITE_GRAPHQL_ENDPOINT_TEST=https://db.test.bodyshop.app/v1/graphql
\ No newline at end of file
diff --git a/.env.rome b/.env.rome
new file mode 100644
index 0000000..b0871ce
--- /dev/null
+++ b/.env.rome
@@ -0,0 +1,4 @@
+VITE_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
+VITE_GRAPHQL_ENDPOINT=https://db.romeonline.io/v1/graphql
+VITE_FIREBASE_CONFIG_TEST={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
+VITE_GRAPHQL_ENDPOINT_TEST=https://db.test.romeonline.io/v1/graphql
\ No newline at end of file
diff --git a/README.md b/README.md
index 1028732..602d47b 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,18 @@
-# bodyshop-desktop
+# Shop Partner
+An electron app that is replacing the existing Bodyshop Partner that was a C#/WPF Application.
-An Electron application with React and TypeScript
+The purpose of this application is to:
+* Parse EMS files, and upload them to the IO back end.
+* Receive requests for EMS file parsing
+
+The following functionality will be coming:
+* Interact with QuickBooks desktop (Windows Only)
+* Paint scale integrations
+* Parts Price Changes for CCC
-## Recommended IDE Setup
+Toggling between the Production and Test servers can be done by pressing `CTRL/CMD + SHIFT + T`, and then going to the application menu, and enabling test. The application will restart automatically.
-- [VSCode](https://code.visualstudio.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
+## Dev and Build Notes
+Unlike the main app, the dev mode will only connect to ImEX Online test data.
-## Project Setup
-
-### Install
-
-```bash
-$ npm install
-```
-
-### Development
-
-```bash
-$ npm run dev
-```
-
-### Build
-
-```bash
-# For windows
-$ npm run build:win
-
-# For macOS
-$ npm run build:mac
-
-# For Linux
-$ npm run build:linux
-```
+Building the app will require specifying the company to build for. Those details are captured in their respective ENV and YAML files.
diff --git a/electron-builder.yml b/electron-builder.imex.yml
similarity index 100%
rename from electron-builder.yml
rename to electron-builder.imex.yml
diff --git a/electron-builder.rome.yml b/electron-builder.rome.yml
new file mode 100644
index 0000000..bb392e3
--- /dev/null
+++ b/electron-builder.rome.yml
@@ -0,0 +1,62 @@
+appId: com.convenientbrands.bodyshop-desktop
+copyright: Convenient Brands, LLC.
+productName: Rome Shop Partner
+generateUpdatesFilesForAllChannels: true
+
+directories:
+ buildResources: build
+files:
+ - "!**/.vscode/*"
+ - "!src/*"
+ - "!electron.vite.config.{js,ts,mjs,cjs}"
+ - "!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}"
+ - "!{.env,.env.*,.npmrc,pnpm-lock.yaml}"
+ - "!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}"
+asarUnpack:
+ - resources/**
+win:
+ executableName: ShopPartner
+ icon: resources/diamond.png
+ azureSignOptions:
+ endpoint: https://eus.codesigning.azure.net
+ certificateProfileName: ImEXRPS
+ codeSigningAccountName: ImEX
+
+nsis:
+ artifactName: ${name}-${version}-setup.${ext}
+ shortcutName: ${productName}
+ uninstallDisplayName: ${productName}
+ createDesktopShortcut: always
+mac:
+ entitlementsInherit: build/entitlements.mac.plist
+ category: public.app-category.business
+ extendInfo:
+ - NSCameraUsageDescription: Application requests access to the device's camera.
+ - NSMicrophoneUsageDescription: Application requests access to the device's microphone.
+ - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
+ - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
+ target:
+ - target: default
+ arch:
+ - arm64
+ - target: default
+ arch:
+ - x64
+dmg:
+ artifactName: ${name}-${version}-${arch}.${ext}
+linux:
+ target:
+ - AppImage
+ - snap
+ - deb
+ maintainer: electronjs.org
+ category: Utility
+appImage:
+ artifactName: ${name}-${version}.${ext}
+npmRebuild: false
+publish:
+ provider: s3
+ bucket: imex-partner
+ region: ca-central-1
+electronDownload:
+ mirror: https://npmmirror.com/mirrors/electron/
diff --git a/package.json b/package.json
index 2763f3e..116dd76 100644
--- a/package.json
+++ b/package.json
@@ -13,12 +13,13 @@
"typecheck": "npm run typecheck:node && npm run typecheck:web",
"start": "electron-vite preview",
"dev": "electron-vite dev",
- "build": "electron-vite build",
+ "build:mac:imex": "electron-vite build --mode imex && electron-builder --config electron-builder.imex.yml",
+ "build:mac:rome": "electron-vite build --mode rome && electron-builder --config electron-builder.rome.yml",
"postinstall": "electron-builder install-app-deps",
"build:unpack": "npm run build && electron-builder --dir",
"build:win": "npm run build && electron-builder --win",
- "build:mac": "electron-vite build && electron-builder --mac",
- "build:linux": "electron-vite build && electron-builder --linux"
+ "build:mac": "npm run build && electron-builder --mac",
+ "build:linux": "npm run build && electron-builder --linux"
},
"dependencies": {
"@apollo/client": "^3.13.5",
diff --git a/src/env.d.ts b/src/env.d.ts
index 33cf21d..c2e6c8b 100644
--- a/src/env.d.ts
+++ b/src/env.d.ts
@@ -3,6 +3,8 @@
export interface ImportMetaEnv {
readonly VITE_FIREBASE_CONFIG: string;
readonly VITE_GRAPHQL_ENDPOINT: string;
+ readonly VITE_FIREBASE_CONFIG_TEST: string;
+ readonly VITE_GRAPHQL_ENDPOINT_TEST: string;
}
export interface ImportMeta {
diff --git a/src/main/graphql/graphql-client.ts b/src/main/graphql/graphql-client.ts
index a1d7d08..d1dad22 100644
--- a/src/main/graphql/graphql-client.ts
+++ b/src/main/graphql/graphql-client.ts
@@ -3,6 +3,7 @@ import log from "electron-log/main";
import { GraphQLClient, RequestMiddleware } from "graphql-request";
import errorTypeCheck from "../../util/errorTypeCheck.js";
import ipcTypes from "../../util/ipcTypes.json";
+import store from "../store/store.js";
const requestMiddleware: RequestMiddleware = async (request) => {
const token = await getTokenFromRenderer();
@@ -20,7 +21,9 @@ const requestMiddleware: RequestMiddleware = async (request) => {
};
const client: GraphQLClient = new GraphQLClient(
- import.meta.env.VITE_GRAPHQL_ENDPOINT,
+ store.get("app.isTest") || false
+ ? import.meta.env.VITE_GRAPHQL_ENDPOINT_TEST
+ : import.meta.env.VITE_GRAPHQL_ENDPOINT,
{
requestMiddleware,
},
diff --git a/src/main/index.ts b/src/main/index.ts
index 6b43085..175428b 100644
--- a/src/main/index.ts
+++ b/src/main/index.ts
@@ -1,6 +1,14 @@
import { electronApp, is, optimizer } from "@electron-toolkit/utils";
import Sentry from "@sentry/electron/main";
-import { app, BrowserWindow, Menu, nativeImage, shell, Tray } from "electron";
+import {
+ app,
+ BrowserWindow,
+ globalShortcut,
+ Menu,
+ nativeImage,
+ shell,
+ Tray,
+} from "electron";
import log from "electron-log/main";
import { autoUpdater } from "electron-updater";
import path, { join } from "path";
@@ -138,6 +146,20 @@ function createWindow(): void {
}
},
},
+ {
+ label: "Connect to Test",
+ checked: store.get("app.isTest") as boolean,
+ visible: false,
+ type: "checkbox",
+ id: "toggleTest",
+ click: (): void => {
+ const currentSetting = store.get("app.isTest") as boolean;
+ store.set("app.isTest", !currentSetting);
+ log.info("Setting isTest to: ", !currentSetting);
+ app.relaunch(); // Relaunch the app
+ app.exit(0); // Exit the current instance
+ },
+ },
],
},
// { role: 'windowMenu' }
@@ -219,6 +241,23 @@ function createWindow(): void {
const menu: Electron.Menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
+ // Register a global shortcut to show the hidden item
+ globalShortcut.register("CommandOrControl+Shift+T", () => {
+ console.log("Shortcut pressed! Revealing hidden item.");
+
+ // Update the menu to make the hidden item visible
+ // Find the menu item dynamically by its id
+ const fileMenu = template.find((item) => item.label === "Application");
+ const hiddenItem = fileMenu?.submenu?.find(
+ (item) => item.id === "toggleTest",
+ );
+ if (hiddenItem) {
+ hiddenItem.visible = true; // Update the visibility dynamically
+ const menu: Electron.Menu = Menu.buildFromTemplate(template);
+ Menu.setApplicationMenu(menu);
+ }
+ });
+
// Store window properties for later
const storeWindowState = (): void => {
const [width, height] = mainWindow.getSize();
@@ -388,7 +427,7 @@ app.on("before-quit", () => {
openAtLogin: !currentSetting,
});
}
-
+ globalShortcut.unregisterAll();
isAppQuitting = true;
});
diff --git a/src/main/store/store.ts b/src/main/store/store.ts
index 0f99b46..fa5d343 100644
--- a/src/main/store/store.ts
+++ b/src/main/store/store.ts
@@ -20,6 +20,7 @@ const store = new Store({
y: undefined,
},
user: null,
+ isTest: false,
bodyshop: {},
masterdata: {
opcodes: null,
diff --git a/src/preload/index.ts b/src/preload/index.ts
index 3f7d1ec..4485593 100644
--- a/src/preload/index.ts
+++ b/src/preload/index.ts
@@ -1,9 +1,16 @@
import { contextBridge } from "electron";
import { electronAPI } from "@electron-toolkit/preload";
import "electron-log/preload";
+import store from "../main/store/store";
// Custom APIs for renderer
-const api = {};
+interface Api {
+ isTest: () => boolean;
+}
+
+const api: Api = {
+ isTest: (): boolean => store.get("app.isTest") || false,
+};
// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
diff --git a/src/renderer/src/components/NavigationHeader/Navigationheader.tsx b/src/renderer/src/components/NavigationHeader/Navigationheader.tsx
index ddea3de..31ecc8c 100644
--- a/src/renderer/src/components/NavigationHeader/Navigationheader.tsx
+++ b/src/renderer/src/components/NavigationHeader/Navigationheader.tsx
@@ -1,5 +1,6 @@
+import { is } from "@electron-toolkit/utils";
import { auth } from "@renderer/util/firebase";
-import { Layout, Menu } from "antd";
+import { Badge, Layout, Menu } from "antd";
import { MenuItemType } from "antd/es/menu/interface";
import { signOut } from "firebase/auth";
import { useTranslation } from "react-i18next";
@@ -18,25 +19,22 @@ const NavigationHeader: React.FC = () => {
},
},
];
+ const isTest = window.api.isTest();
return (
- //
-
-
-
- //
+
+
+
+
+
);
};
diff --git a/src/renderer/src/components/Settings/Settings.tsx b/src/renderer/src/components/Settings/Settings.tsx
index 059bbe1..92e8404 100644
--- a/src/renderer/src/components/Settings/Settings.tsx
+++ b/src/renderer/src/components/Settings/Settings.tsx
@@ -4,6 +4,7 @@ import SettingsWatcher from "./Settings.Watcher";
import Welcome from "../Welcome/Welcome";
const Settings: React.FC = () => {
+ console.log("is test?", window.api.isTest());
return (
diff --git a/src/renderer/src/util/firebase.ts b/src/renderer/src/util/firebase.ts
index b506ba9..6d85c3b 100644
--- a/src/renderer/src/util/firebase.ts
+++ b/src/renderer/src/util/firebase.ts
@@ -2,7 +2,11 @@ import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
// TODO: Replace the following with your app's Firebase project configuration
-const firebaseConfig = JSON.parse(import.meta.env.VITE_FIREBASE_CONFIG);
+const firebaseConfig = JSON.parse(
+ window.api.isTest()
+ ? import.meta.env.VITE_FIREBASE_CONFIG_TEST
+ : import.meta.env.VITE_FIREBASE_CONFIG,
+);
const app = initializeApp(firebaseConfig);
export const auth = getAuth();