General bug fixes from testing, refresh on shop change, update display

This commit is contained in:
Patrick Fic
2025-04-14 15:59:04 -07:00
parent 0ec741912e
commit affe412586
7 changed files with 131 additions and 58 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "bodyshop-desktop",
"version": "0.0.1-alpha.4",
"version": "0.0.1-alpha.5",
"description": "Shop Management System Partner",
"main": "./out/main/index.js",
"author": "Convenient Brands, LLC",

View File

@@ -6,9 +6,11 @@ import http from "http";
import errorTypeCheck from "../../util/errorTypeCheck";
import ImportJob from "../decoder/decoder";
import folderScan from "../decoder/folder-scan";
import { handleEMSPartsOrder } from "../ems-parts-order/ems-parts-order-handler";
import { handleShopMetaDataFetch } from "../ipc/ipcMainHandler.user";
import { handlePartsPariceChangeRequest } from "../ppc/ppc-handler";
import { handleQuickBookRequest } from "../quickbooks-desktop/quickbooks-desktop";
import { handleEMSPartsOrder } from "../ems-parts-order/ems-parts-order-handler";
import { c } from "vite/dist/node/moduleRunnerTransport.d-CXw_Ws6P";
export default class LocalServer {
private app: express.Application;
@@ -146,6 +148,26 @@ export default class LocalServer {
}
},
);
this.app.post(
"/refresh",
async (req: express.Request, res: express.Response) => {
log.debug("[HTTP Server] Refresh request received");
try {
await handleShopMetaDataFetch(true);
res.status(200).json({ success: true });
} catch (error) {
log.error(
"[HTTP Server] Error refreshing shop metadata",
errorTypeCheck(error),
);
res.status(500).json({
success: false,
error: "Error importing file",
...errorTypeCheck(error),
});
}
},
);
// Add more routes as needed
}

View File

@@ -1,4 +1,4 @@
import { is, optimizer } from "@electron-toolkit/utils";
import { is, optimizer, platform } from "@electron-toolkit/utils";
import Sentry from "@sentry/electron/main";
import {
app,
@@ -88,7 +88,10 @@ function createWindow(): void {
// { role: 'fileMenu' }
{
label: "File",
submenu: [isMac ? { role: "close" } : { role: "quit" }],
submenu: [
...(!isMac ? [{ role: "about" }] : []),
isMac ? { role: "close" } : { role: "quit" },
],
},
// { role: 'editMenu' }
{
@@ -149,7 +152,7 @@ function createWindow(): void {
},
},
{
label: "Check for Updates",
label: `Check for Updates (${app.getVersion()})`,
click: (): void => {
checkForAppUpdates();
},
@@ -169,6 +172,7 @@ function createWindow(): void {
store.set("app.isTest", !currentSetting);
log.info("Setting isTest to: ", !currentSetting);
app.relaunch(); // Relaunch the app
preQuitMethods(); //Quitting handlers aren't called. Manually execute to clean up the app.
app.exit(0); // Exit the current instance
},
},
@@ -321,6 +325,10 @@ app.whenReady().then(async () => {
// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
if (platform.isWindows) {
app.setAppUserModelId(app.name);
}
app.on("browser-window-created", (_, window) => {
optimizer.watchWindowShortcuts(window);
});

View File

@@ -13,7 +13,7 @@ import {
} from "../graphql/queries";
import { default as Store, default as store } from "../store/store";
import { checkForAppUpdatesContinuously } from "../util/checkForAppUpdates";
import { sendIpcToRenderer } from "../util/toRenderer";
import { getMainWindow, sendIpcToRenderer } from "../util/toRenderer";
const ipcMainHandleAuthStateChanged = async (
_event: IpcMainEvent,
@@ -23,27 +23,10 @@ const ipcMainHandleAuthStateChanged = async (
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,
);
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.");
handleShopMetaDataFetch();
//Check for updates
const convCo = activeBodyshop.bodyshops[0].convenient_company;
const convCo = Store.get("app.bodyshop");
if (convCo === "alpha") {
autoUpdater.channel = "alpha";
log.debug("Setting update channel to ALPHA channel.");
@@ -64,6 +47,39 @@ const ipcMainHandleAuthStateChanged = async (
checkForAppUpdatesContinuously();
};
const handleShopMetaDataFetch = async (
reloadWindow: boolean,
): Promise<void> => {
try {
log.debug("Requery shop information & master data.");
const activeBodyshop: ActiveBodyshopQueryResult = await client.request(
QUERY_ACTIVE_BODYSHOP_TYPED,
);
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),
);
if (reloadWindow) {
const mainWindow = getMainWindow();
if (mainWindow) {
mainWindow.reload();
}
}
} catch (error) {
log.error("Error while fetching shop metadata", errorTypeCheck(error));
throw error;
}
};
const ipMainHandleResetPassword = async (): Promise<void> => {
shell.openExternal(
store.get("app.isTest")
@@ -72,4 +88,8 @@ const ipMainHandleResetPassword = async (): Promise<void> => {
);
};
export { ipcMainHandleAuthStateChanged, ipMainHandleResetPassword };
export {
ipcMainHandleAuthStateChanged,
ipMainHandleResetPassword,
handleShopMetaDataFetch,
};

View File

@@ -134,16 +134,18 @@ const SettingsWatcher: React.FC = () => {
checkedChildren={t("settings.labels.watchermoderealtime")}
unCheckedChildren={t("settings.labels.watchermodepolling")}
/>
<Space size="small" wrap>
<span>{t("settings.labels.pollinginterval")}</span>
<InputNumber
title={t("settings.labels.pollinginterval")}
disabled={!pollingState.enabled}
min={1000}
value={pollingState.interval}
onChange={handlePollingIntervalChange}
/>
</Space>
{pollingState.enabled && (
<Space size="small" direction="vertical" wrap>
<span>{t("settings.labels.pollinginterval")}</span>
<InputNumber
title={t("settings.labels.pollinginterval")}
disabled={!pollingState.enabled}
min={1000}
value={pollingState.interval}
onChange={handlePollingIntervalChange}
/>
</Space>
)}
{watcherError && <Alert message={watcherError} />}
</Space>
</Col>

View File

@@ -8,6 +8,7 @@ import { useAppSelector } from "@renderer/redux/reduxHooks";
import { Affix, Button, Card, Progress, Space, Statistic } from "antd";
import { useTranslation } from "react-i18next";
import ipcTypes from "../../../../util/ipcTypes.json";
import { useState } from "react";
const UpdateAvailable: React.FC = () => {
const { t } = useTranslation();
@@ -16,12 +17,14 @@ const UpdateAvailable: React.FC = () => {
const updateSpeed = useAppSelector(selectAppUpdateSpeed);
const updateProgress = useAppSelector(selectAppUpdateProgress);
const isUpdateComplete = useAppSelector(selectAppUpdateCompleted);
const [applyingUpdate, setApplyingUpdate] = useState<boolean>(false);
const handleDownload = (): void => {
window.electron.ipcRenderer.send(ipcTypes.toMain.updates.download);
};
const handleApply = (): void => {
setApplyingUpdate(true);
window.electron.ipcRenderer.send(ipcTypes.toMain.updates.apply);
};
@@ -30,28 +33,45 @@ const UpdateAvailable: React.FC = () => {
}
return (
<Affix offsetTop={40} style={{ position: "absolute", right: 20 }}>
<Card title={t("updates.available")} style={{ width: "40vw" }}>
{updateProgress === 0 && (
<Button onClick={handleDownload}>{t("updates.download")}</Button>
)}
<Progress
percent={updateProgress}
percentPosition={{ align: "center", type: "outer" }}
/>
{!isUpdateComplete && formatSpeed(updateSpeed)}
{isUpdateComplete && (
<Space wrap>
<Button onClick={handleApply}>{t("updates.apply")}</Button>
<Statistic.Countdown
title="Auto update in:"
format="mm:ss"
value={Date.now() + 10 * 1000}
onFinish={(): void =>
window.electron.ipcRenderer.send(ipcTypes.toMain.updates.apply)
}
/>
</Space>
)}
<Card
title={t("updates.available")}
style={{
maxWidth: 600,
margin: "auto auto",
borderRadius: 8,
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
}}
>
<Space direction="vertical" style={{ width: "100%" }}>
{updateProgress === 0 && (
<Button onClick={handleDownload}>{t("updates.download")}</Button>
)}
<Progress
percent={updateProgress}
percentPosition={{ align: "center", type: "outer" }}
/>
{!isUpdateComplete && formatSpeed(updateSpeed)}
{isUpdateComplete && (
<>
<Button
type="primary"
loading={applyingUpdate}
style={{ width: "100%" }}
onClick={handleApply}
>
{applyingUpdate ? t("updates.applying") : t("updates.apply")}
</Button>
<Statistic.Countdown
title="Auto update in:"
format="mm:ss"
style={{ width: "100%", textAlign: "center" }}
value={Date.now() + 10 * 1000}
onFinish={(): void => handleApply()}
/>
</>
)}
</Space>
</Card>
</Affix>
);

File diff suppressed because one or more lines are too long