15 Commits

Author SHA1 Message Date
Patrick Fic
83ca7a251b Final release for 1.0.6. Resolve issue with destructure on CCC PPC. 2025-09-17 12:02:57 -07:00
Patrick FIc
41caa76b28 Remove notification for update. 2025-09-10 14:59:24 -07:00
Allan Carr
45bc12a2f5 IO-3361 PPG Mix Data 2025-09-10 13:51:43 -07:00
Patrick FIc
093012c8f7 Merge branch 'main' of bitbucket.org:snaptsoft/bodyshop-desktop 2025-09-09 16:07:43 -07:00
Patrick FIc
bd9fa67087 Check release channel each time. 2025-09-09 16:07:26 -07:00
Patrick Fic
c5bdb62cb6 Merge branch '1.0.5' 2025-09-09 16:06:38 -07:00
Patrick Fic
e9dd8ff760 Finalize release. 2025-09-09 16:06:20 -07:00
Patrick FIc
1c839ee3f8 Update executable names for beta and alpha paths. 2025-09-09 15:47:31 -07:00
Patrick Fic
9fdd88526c IO-3358 Resolve update channel & null claim number. 2025-09-08 10:30:53 -07:00
Patrick FIc
d5b40ef6f4 Merge branch '1.0.3' 2025-08-28 13:01:44 -07:00
Patrick FIc
59162e3028 Increase version to 1.0.4 to prevent conflicts. 2025-08-28 13:01:30 -07:00
Patrick FIc
f41728550c Include prior 1.0.3 fix. 2025-08-28 13:01:03 -07:00
Patrick Fic
3b918d3fcb Merge branch '1.0.3' 2025-08-28 12:55:02 -07:00
Patrick Fic
cf18acc661 IO-3350 Update cors in partner to accept www. 2025-08-28 12:51:09 -07:00
Patrick Fic
be079a2e48 Merged in release/1.0.2 (pull request #4)
Release/1.0.2
2025-05-22 17:29:09 +00:00
20 changed files with 446 additions and 86 deletions

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env node
// Cross-platform script to set artifact naming based on version
const fs = require('fs');
const path = require('path');
const { spawn } = require('child_process');
// Read the package.json to get the version
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const version = packageJson.version;
console.log(`Current version: ${version}`);
// Determine the artifact suffix based on the version
let artifactSuffix = '';
if (version.includes('alpha')) {
artifactSuffix = `alpha-${version}-`;
console.log(`Detected alpha version, setting suffix to: ${artifactSuffix}`);
} else if (version.includes('beta')) {
artifactSuffix = `beta-${version}-`;
console.log(`Detected beta version, setting suffix to: ${artifactSuffix}`);
} else {
artifactSuffix = '';
console.log('Detected release version, no suffix will be added');
}
// Set the environment variable for the current process
process.env.ARTIFACT_SUFFIX = artifactSuffix;
console.log(`ARTIFACT_SUFFIX set to: '${artifactSuffix}'`);
// If arguments are passed, execute the remaining command with the environment variable set
if (process.argv.length > 2) {
const command = process.argv[2];
const args = process.argv.slice(3);
console.log(`Executing: ${command} ${args.join(' ')}`);
const child = spawn(command, args, {
stdio: 'inherit',
env: { ...process.env, ARTIFACT_SUFFIX: artifactSuffix },
shell: true
});
child.on('close', (code) => {
process.exit(code);
});
} else {
// Just setting the environment variable
console.log('Environment variable set. Use this script with additional arguments to run commands with the variable set.');
}

View File

@@ -0,0 +1,38 @@
# PowerShell script to set artifact naming based on version
param(
[string]$ConfigType = "imex"
)
# Read the package.json to get the version
$packageJsonPath = Join-Path $PSScriptRoot "..\package.json"
$packageJson = Get-Content $packageJsonPath | ConvertFrom-Json
$version = $packageJson.version
Write-Host "Current version: $version"
# Determine the artifact suffix based on the version
$artifactSuffix = ""
if ($version -match "alpha") {
$artifactSuffix = "alpha-${version}-"
Write-Host "Detected alpha version, setting suffix to: $artifactSuffix"
}
elseif ($version -match "beta") {
$artifactSuffix = "beta-${version}-"
Write-Host "Detected beta version, setting suffix to: $artifactSuffix"
}
else {
$artifactSuffix = ""
Write-Host "Detected release version, no suffix will be added"
}
# Set the environment variable
$env:ARTIFACT_SUFFIX = $artifactSuffix
# Export for the current session
[Environment]::SetEnvironmentVariable("ARTIFACT_SUFFIX", $artifactSuffix, "Process")
Write-Host "ARTIFACT_SUFFIX set to: '$env:ARTIFACT_SUFFIX'"
# Return the suffix for use in other scripts
return $artifactSuffix

View File

@@ -0,0 +1,33 @@
#!/bin/bash
# Bash script to set artifact naming based on version
# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Read the package.json to get the version
PACKAGE_JSON_PATH="$SCRIPT_DIR/../package.json"
VERSION=$(node -p "require('$PACKAGE_JSON_PATH').version")
echo "Current version: $VERSION"
# Determine the artifact suffix based on the version
ARTIFACT_SUFFIX=""
if [[ $VERSION == *"alpha"* ]]; then
ARTIFACT_SUFFIX="alpha-${VERSION}-"
echo "Detected alpha version, setting suffix to: $ARTIFACT_SUFFIX"
elif [[ $VERSION == *"beta"* ]]; then
ARTIFACT_SUFFIX="beta-${VERSION}-"
echo "Detected beta version, setting suffix to: $ARTIFACT_SUFFIX"
else
ARTIFACT_SUFFIX=""
echo "Detected release version, no suffix will be added"
fi
# Export the environment variable
export ARTIFACT_SUFFIX="$ARTIFACT_SUFFIX"
echo "ARTIFACT_SUFFIX set to: '$ARTIFACT_SUFFIX'"
# Also write to a temporary file for sourcing in other scripts
echo "export ARTIFACT_SUFFIX='$ARTIFACT_SUFFIX'" > "$SCRIPT_DIR/.artifact-suffix.env"

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env node
// Cross-platform test script to demonstrate artifact naming for different versions
const fs = require('fs');
const path = require('path');
console.log('=== Artifact Naming Test (Cross-Platform) ===');
console.log('');
// Get current version
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const currentVersion = packageJson.version;
console.log(`Current version: ${currentVersion}`);
// Function to get artifact suffix
function getArtifactSuffix(version) {
if (version.includes('alpha')) {
return `alpha-${version}-`;
} else if (version.includes('beta')) {
return `beta-${version}-`;
} else {
return '';
}
}
// Test scenarios
const testVersions = [
'1.0.5', // Release version
'1.0.5-alpha.2', // Alpha version
'1.0.5-beta.1', // Beta version
'2.0.0-alpha.1', // Another alpha
'1.5.0-beta.3' // Another beta
];
console.log('Test scenarios:');
console.log('==================');
testVersions.forEach(version => {
const suffix = getArtifactSuffix(version);
// Different artifact names for different platforms
const windowsArtifact = `imex-partner-${suffix}x64.exe`;
const macArtifact = `imex-partner-${suffix}x64.dmg`;
const linuxArtifact = `imex-partner-${suffix}x64.AppImage`;
console.log(`Version: ${version}`);
console.log(` Suffix: '${suffix}'`);
console.log(` Windows: ${windowsArtifact}`);
console.log(` Mac: ${macArtifact}`);
console.log(` Linux: ${linuxArtifact}`);
console.log('');
});
console.log('Current configuration will produce:');
const currentSuffix = getArtifactSuffix(currentVersion);
console.log(` Windows: imex-partner-${currentSuffix}x64.exe`);
console.log(` Mac: imex-partner-${currentSuffix}x64.dmg`);
console.log(` Linux: imex-partner-${currentSuffix}x64.AppImage`);
console.log('');
console.log(`Platform detected: ${process.platform}`);
console.log(`Architecture: ${process.arch}`);

View File

@@ -0,0 +1,48 @@
# Test script to demonstrate artifact naming for different versions
Write-Host "=== Artifact Naming Test ==="
Write-Host ""
# Test current version
$packageJsonPath = ".\package.json"
$packageJson = Get-Content $packageJsonPath | ConvertFrom-Json
$currentVersion = $packageJson.version
Write-Host "Current version: $currentVersion"
# Function to get artifact suffix
function Get-ArtifactSuffix($version) {
if ($version -match "alpha") {
return "alpha-${version}-"
} elseif ($version -match "beta") {
return "beta-${version}-"
} else {
return ""
}
}
# Test scenarios
$testVersions = @(
"1.0.5", # Release version
"1.0.5-alpha.2", # Alpha version
"1.0.5-beta.1", # Beta version
"2.0.0-alpha.1", # Another alpha
"1.5.0-beta.3" # Another beta
)
Write-Host "Test scenarios:"
Write-Host "=================="
foreach ($version in $testVersions) {
$suffix = Get-ArtifactSuffix $version
$artifactName = "imex-partner-${suffix}x64.exe"
Write-Host "Version: $version"
Write-Host " Suffix: '$suffix'"
Write-Host " Result: $artifactName"
Write-Host ""
}
Write-Host "Current configuration will produce:"
$currentSuffix = Get-ArtifactSuffix $currentVersion
$currentArtifact = "imex-partner-${currentSuffix}x64.exe"
Write-Host " $currentArtifact"

View File

@@ -0,0 +1,50 @@
#!/bin/bash
# Test script to demonstrate artifact naming for different versions on Mac
echo "=== Artifact Naming Test (Mac) ==="
echo ""
# Get current version
PACKAGE_JSON_PATH="./package.json"
CURRENT_VERSION=$(node -p "require('$PACKAGE_JSON_PATH').version")
echo "Current version: $CURRENT_VERSION"
# Function to get artifact suffix
get_artifact_suffix() {
local version=$1
if [[ $version == *"alpha"* ]]; then
echo "alpha-${version}-"
elif [[ $version == *"beta"* ]]; then
echo "beta-${version}-"
else
echo ""
fi
}
# Test scenarios
TEST_VERSIONS=(
"1.0.5" # Release version
"1.0.5-alpha.2" # Alpha version
"1.0.5-beta.1" # Beta version
"2.0.0-alpha.1" # Another alpha
"1.5.0-beta.3" # Another beta
)
echo "Test scenarios:"
echo "=================="
for version in "${TEST_VERSIONS[@]}"; do
suffix=$(get_artifact_suffix "$version")
artifact_name="imex-partner-${suffix}x64.dmg"
echo "Version: $version"
echo " Suffix: '$suffix'"
echo " Result: $artifact_name"
echo ""
done
echo "Current configuration will produce:"
current_suffix=$(get_artifact_suffix "$CURRENT_VERSION")
current_artifact="imex-partner-${current_suffix}x64.dmg"
echo " $current_artifact"

View File

@@ -23,7 +23,7 @@ win:
certificateProfileName: ImEXRPS certificateProfileName: ImEXRPS
codeSigningAccountName: ImEX codeSigningAccountName: ImEX
nsis: nsis:
artifactName: imex-partner-${arch}.${ext} artifactName: imex-partner-${env.ARTIFACT_SUFFIX}${arch}.${ext}
shortcutName: ${productName} shortcutName: ${productName}
uninstallDisplayName: ${productName} uninstallDisplayName: ${productName}
createDesktopShortcut: always createDesktopShortcut: always
@@ -49,7 +49,7 @@ mac:
arch: arch:
- x64 - x64
dmg: dmg:
artifactName: imex-partner-${arch}.${ext} artifactName: imex-partner-${env.ARTIFACT_SUFFIX}${arch}.${ext}
linux: linux:
target: target:
- AppImage - AppImage
@@ -59,7 +59,7 @@ linux:
category: Utility category: Utility
desktop: scripts/imex-shop-partner.desktop desktop: scripts/imex-shop-partner.desktop
appImage: appImage:
artifactName: imex-partner-${arch}.${ext} artifactName: imex-partner-${env.ARTIFACT_SUFFIX}${arch}.${ext}
npmRebuild: false npmRebuild: false
publish: publish:
provider: s3 provider: s3

View File

@@ -23,7 +23,7 @@ win:
certificateProfileName: ImEXRPS certificateProfileName: ImEXRPS
codeSigningAccountName: ImEX codeSigningAccountName: ImEX
nsis: nsis:
artifactName: rome-partner-${arch}.${ext} artifactName: rome-partner-${env.ARTIFACT_SUFFIX}${arch}.${ext}
shortcutName: ${productName} shortcutName: ${productName}
uninstallDisplayName: ${productName} uninstallDisplayName: ${productName}
createDesktopShortcut: always createDesktopShortcut: always
@@ -50,7 +50,7 @@ mac:
arch: arch:
- x64 - x64
dmg: dmg:
artifactName: rome-partner-${arch}.${ext} artifactName: rome-partner-${env.ARTIFACT_SUFFIX}${arch}.${ext}
linux: linux:
target: target:
- AppImage - AppImage
@@ -60,7 +60,7 @@ linux:
category: Utility category: Utility
desktop: scripts/rome-shop-partner.desktop desktop: scripts/rome-shop-partner.desktop
appImage: appImage:
artifactName: rome-partner-${arch}.${ext} artifactName: rome-partner-${env.ARTIFACT_SUFFIX}${arch}.${ext}
npmRebuild: false npmRebuild: false
publish: publish:
provider: s3 provider: s3

30
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "bodyshop-desktop", "name": "bodyshop-desktop",
"version": "0.0.1-alpha.11", "version": "1.0.6-alpha.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "bodyshop-desktop", "name": "bodyshop-desktop",
"version": "0.0.1-alpha.11", "version": "1.0.6-alpha.1",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@apollo/client": "^3.13.6", "@apollo/client": "^3.13.6",
@@ -41,6 +41,7 @@
"archiver": "^7.0.1", "archiver": "^7.0.1",
"chokidar": "^4.0.3", "chokidar": "^4.0.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-env": "^10.0.0",
"dbffile": "^1.12.0", "dbffile": "^1.12.0",
"electron": "^35.1.5", "electron": "^35.1.5",
"electron-builder": "^25.1.8", "electron-builder": "^25.1.8",
@@ -1002,6 +1003,13 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@epic-web/invariant": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
"dev": true,
"license": "MIT"
},
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.25.2", "version": "0.25.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
@@ -6936,6 +6944,24 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
} }
}, },
"node_modules/cross-env": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.0.0.tgz",
"integrity": "sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@epic-web/invariant": "^1.0.0",
"cross-spawn": "^7.0.6"
},
"bin": {
"cross-env": "dist/bin/cross-env.js",
"cross-env-shell": "dist/bin/cross-env-shell.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.6", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",

View File

@@ -1,6 +1,6 @@
{ {
"name": "bodyshop-desktop", "name": "bodyshop-desktop",
"version": "1.0.2", "version": "1.0.6",
"description": "Shop Management System Partner", "description": "Shop Management System Partner",
"main": "./out/main/index.js", "main": "./out/main/index.js",
"author": "Convenient Brands, LLC", "author": "Convenient Brands, LLC",
@@ -13,17 +13,17 @@
"typecheck": "npm run typecheck:node && npm run typecheck:web", "typecheck": "npm run typecheck:node && npm run typecheck:web",
"start": "electron-vite preview", "start": "electron-vite preview",
"dev": "electron-vite dev", "dev": "electron-vite dev",
"build:imex": "electron-vite build --mode imex && electron-builder --config electron-builder.imex.yml", "build:imex": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --config electron-builder.imex.yml",
"build:rome": "electron-vite build --mode rome && electron-builder --config electron-builder.rome.yml", "build:rome": "node deploy/set-artifact-name.js electron-vite build --mode rome && node deploy/set-artifact-name.js electron-builder --config electron-builder.rome.yml",
"build:imex:publish": "electron-vite build --mode imex && electron-builder --config electron-builder.imex.yml --publish always", "build:imex:publish": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --config electron-builder.imex.yml --publish always",
"build:rome:publish": "electron-vite build --mode rome && electron-builder --config electron-builder.rome.yml --publish always", "build:rome:publish": "node deploy/set-artifact-name.js electron-vite build --mode rome && node deploy/set-artifact-name.js electron-builder --config electron-builder.rome.yml --publish always",
"build:imex:linux": "electron-vite build --mode imex && electron-builder --config electron-builder.imex.yml --linux", "build:imex:linux": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --config electron-builder.imex.yml --linux",
"build:rome:linux": "electron-vite build --mode rome && electron-builder --config electron-builder.rome.yml --linux", "build:rome:linux": "node deploy/set-artifact-name.js electron-vite build --mode rome && node deploy/set-artifact-name.js electron-builder --config electron-builder.rome.yml --linux",
"postinstall": "electron-builder install-app-deps", "postinstall": "electron-builder install-app-deps",
"build:unpack": "electron-vite build --mode imex && electron-builder --dir", "build:unpack": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --dir",
"build:win": "electron-vite build --mode imex && electron-builder --win", "build:win": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --win",
"build:mac": "electron-vite build --mode imex && electron-builder --mac", "build:mac": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --mac",
"build:linux": "electron-vite build --mode imex && electron-builder --linux" "build:linux": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --linux"
}, },
"dependencies": { "dependencies": {
"@apollo/client": "^3.13.6", "@apollo/client": "^3.13.6",
@@ -58,6 +58,7 @@
"archiver": "^7.0.1", "archiver": "^7.0.1",
"chokidar": "^4.0.3", "chokidar": "^4.0.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-env": "^10.0.0",
"dbffile": "^1.12.0", "dbffile": "^1.12.0",
"electron": "^35.1.5", "electron": "^35.1.5",
"electron-builder": "^25.1.8", "electron-builder": "^25.1.8",

View File

@@ -182,7 +182,9 @@ const DecodeAD1 = async (
if (!rawAd1Data.ownr_ph1 || _.isEmpty(rawAd1Data.ownr_ph1)) { if (!rawAd1Data.ownr_ph1 || _.isEmpty(rawAd1Data.ownr_ph1)) {
rawAd1Data.ownr_ph1 = rawAd1Data.ownr_ph2; rawAd1Data.ownr_ph1 = rawAd1Data.ownr_ph2;
} }
if (rawAd1Data.clm_no === "") {
rawAd1Data.clm_no = undefined;
}
let ownerRecord: OwnerRecordInterface; let ownerRecord: OwnerRecordInterface;
//Check if the owner information is there. If not, use the insured information as a fallback. //Check if the owner information is there. If not, use the insured information as a fallback.
if ( if (

View File

@@ -157,14 +157,16 @@ async function ImportJob(filepath: string): Promise<void> {
console.log("Available Job record to upload;", newAvailableJob); console.log("Available Job record to upload;", newAvailableJob);
setAppProgressbar(0.95); setAppProgressbar(0.95);
const existingJobRecord: QueryJobByClmNoResult = await client.request( if (jobObject.clm_no) {
QUERY_JOB_BY_CLM_NO_TYPED, const existingJobRecord: QueryJobByClmNoResult = await client.request(
{ clm_no: jobObject.clm_no }, QUERY_JOB_BY_CLM_NO_TYPED,
); { clm_no: jobObject.clm_no },
);
if (existingJobRecord.jobs.length > 0) { if (existingJobRecord.jobs.length > 0) {
newAvailableJob.issupplement = true; newAvailableJob.issupplement = true;
newAvailableJob.jobid = existingJobRecord.jobs[0].id; newAvailableJob.jobid = existingJobRecord.jobs[0].id;
}
} }
const insertRecordResult: InsertAvailableJobResult = await client.request( const insertRecordResult: InsertAvailableJobResult = await client.request(

View File

@@ -33,6 +33,10 @@ export default class LocalServer {
"https://imex.online", "https://imex.online",
"https://test.romeonline.io", "https://test.romeonline.io",
"https://romeonline.io", "https://romeonline.io",
"https://www.test.imex.online",
"https://www.imex.online",
"https://www.test.romeonline.io",
"https://www.romeonline.io",
]; ];
this.app.use( this.app.use(

View File

@@ -531,7 +531,7 @@ app.whenReady().then(async () => {
//Check for app updates. //Check for app updates.
autoUpdater.logger = log; autoUpdater.logger = log;
autoUpdater.allowDowngrade = true;
// if (import.meta.env.DEV) { // if (import.meta.env.DEV) {
// // Useful for some dev/debugging tasks, but download can // // Useful for some dev/debugging tasks, but download can
// // not be validated because dev app is not signed // // not be validated because dev app is not signed

View File

@@ -20,19 +20,26 @@ const ipcMainHandleAuthStateChanged = async (
user: User | null, user: User | null,
): Promise<void> => { ): Promise<void> => {
Store.set("user", user); Store.set("user", user);
log.debug("Received authentication state change from Renderer.", user);
await setReleaseChannel();
checkForAppUpdatesContinuously();
};
async function setReleaseChannel() {
try { try {
//Need to query the currently active shop, and store the metadata as well. //Need to query the currently active shop, and store the metadata as well.
//Also need to query the OP Codes for decoding reference. //Also need to query the OP Codes for decoding reference.
log.debug("Received authentication state change from Renderer.", user); await handleShopMetaDataFetch();
handleShopMetaDataFetch();
//Check for updates //Check for updates
const bodyshop = Store.get("app.bodyshop"); const bodyshop = Store.get("app.bodyshop");
if (bodyshop?.convenient_company === "alpha") { if (bodyshop?.convenient_company?.toLowerCase() === "alpha") {
autoUpdater.channel = "alpha"; autoUpdater.channel = "alpha";
log.debug("Setting update channel to ALPHA channel."); log.debug("Setting update channel to ALPHA channel.");
} else if (bodyshop?.convenient_company === "beta") { } else if (bodyshop?.convenient_company?.toLowerCase() === "beta") {
autoUpdater.channel = "beta"; autoUpdater.channel = "beta";
log.debug("Setting update channel to BETA channel."); log.debug("Setting update channel to BETA channel.");
} else {
log.debug("Setting update channel to LATEST channel.");
} }
} catch (error) { } catch (error) {
log.error( log.error(
@@ -44,8 +51,7 @@ const ipcMainHandleAuthStateChanged = async (
"Error connecting to ImEX Online servers to get shop data. Please try again.", "Error connecting to ImEX Online servers to get shop data. Please try again.",
); );
} }
checkForAppUpdatesContinuously(); }
};
const handleShopMetaDataFetch = async ( const handleShopMetaDataFetch = async (
reloadWindow?: boolean, reloadWindow?: boolean,
@@ -89,7 +95,8 @@ const ipMainHandleResetPassword = async (): Promise<void> => {
}; };
export { export {
handleShopMetaDataFetch,
ipcMainHandleAuthStateChanged, ipcMainHandleAuthStateChanged,
ipMainHandleResetPassword, ipMainHandleResetPassword,
handleShopMetaDataFetch, setReleaseChannel,
}; };

View File

@@ -14,7 +14,7 @@ const handlePartsPriceChangeRequest = async (
): Promise<void> => { ): Promise<void> => {
//Route handler here only. //Route handler here only.
const { job } = req.body as { job: PpcJob }; const job = req.body as PpcJob;
try { try {
await generatePartsPriceChange(job); await generatePartsPriceChange(job);
res.status(200).json({ success: true }); res.status(200).json({ success: true });

View File

@@ -1,6 +1,7 @@
import { autoUpdater } from "electron-updater"; import { autoUpdater } from "electron-updater";
import { setReleaseChannel } from "../ipc/ipcMainHandler.user";
function checkForAppUpdatesContinuously(): void { async function checkForAppUpdatesContinuously(): Promise<void> {
checkForAppUpdates(); checkForAppUpdates();
setInterval( setInterval(
() => { () => {
@@ -9,11 +10,9 @@ function checkForAppUpdatesContinuously(): void {
1000 * 60 * 30, 1000 * 60 * 30,
); );
} }
function checkForAppUpdates(): void { async function checkForAppUpdates(): Promise<void> {
autoUpdater.checkForUpdatesAndNotify({ await setReleaseChannel();
title: "Shop Partner Update", autoUpdater.checkForUpdates();
body: "A new version of Shop Partner is available. Click to update.",
});
} }
export { checkForAppUpdatesContinuously, checkForAppUpdates }; export { checkForAppUpdates, checkForAppUpdatesContinuously };

View File

@@ -1,71 +1,98 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from "react";
import ipcTypes from '../../../../../util/ipcTypes.json'; import ipcTypes from "../../../../../util/ipcTypes.json";
import { PaintScaleConfig, PaintScaleType } from '../../../../../util/types/paintScale'; import {
PaintScaleConfig,
PaintScaleType,
} from "../../../../../util/types/paintScale";
import { message } from "antd"; import { message } from "antd";
import {useTranslation} from "react-i18next"; import { useTranslation } from "react-i18next";
type ConfigType = 'input' | 'output'; type ConfigType = "input" | "output";
export const usePaintScaleConfig = (configType: ConfigType) => { export const usePaintScaleConfig = (configType: ConfigType) => {
const [paintScaleConfigs, setPaintScaleConfigs] = useState<PaintScaleConfig[]>([]); const [paintScaleConfigs, setPaintScaleConfigs] = useState<
PaintScaleConfig[]
>([]);
const { t } = useTranslation(); const { t } = useTranslation();
// Get the appropriate IPC methods based on config type // Get the appropriate IPC methods based on config type
const getConfigsMethod = configType === 'input' const getConfigsMethod =
configType === "input"
? ipcTypes.toMain.settings.paintScale.getInputConfigs ? ipcTypes.toMain.settings.paintScale.getInputConfigs
: ipcTypes.toMain.settings.paintScale.getOutputConfigs; : ipcTypes.toMain.settings.paintScale.getOutputConfigs;
const setConfigsMethod = configType === 'input' const setConfigsMethod =
configType === "input"
? ipcTypes.toMain.settings.paintScale.setInputConfigs ? ipcTypes.toMain.settings.paintScale.setInputConfigs
: ipcTypes.toMain.settings.paintScale.setOutputConfigs; : ipcTypes.toMain.settings.paintScale.setOutputConfigs;
const setPathMethod = configType === 'input' const setPathMethod =
configType === "input"
? ipcTypes.toMain.settings.paintScale.setInputPath ? ipcTypes.toMain.settings.paintScale.setInputPath
: ipcTypes.toMain.settings.paintScale.setOutputPath; : ipcTypes.toMain.settings.paintScale.setOutputPath;
// Load paint scale configs on mount // Load paint scale configs on mount
useEffect(() => { useEffect(() => {
window.electron.ipcRenderer window.electron.ipcRenderer
.invoke(getConfigsMethod) .invoke(getConfigsMethod)
.then((configs: PaintScaleConfig[]) => { .then((configs: PaintScaleConfig[]) => {
// Ensure all configs have a pollingInterval and type (for backward compatibility) // Ensure all configs have a pollingInterval and type (for backward compatibility)
const updatedConfigs = configs.map(config => ({ const defaultPolling = configType === "input" ? 1440 : 60;
...config, const updatedConfigs = configs.map((config) => ({
pollingInterval: config.pollingInterval || 1440, // Default to 1440 seconds ...config,
type: config.type || PaintScaleType.PPG, // Default type if missing pollingInterval: config.pollingInterval || defaultPolling, // Default to 1440 for input, 60 for output
})); type: config.type || PaintScaleType.PPG, // Default type if missing
setPaintScaleConfigs(updatedConfigs || []); }));
}) setPaintScaleConfigs(updatedConfigs || []);
.catch((error) => { })
console.error(`Failed to load paint scale ${configType} configs:`, error); .catch((error) => {
}); console.error(
`Failed to load paint scale ${configType} configs:`,
error,
);
});
}, [getConfigsMethod]); }, [getConfigsMethod]);
// Save configs to store and notify main process of config changes // Save configs to store and notify main process of config changes
const saveConfigs = (configs: PaintScaleConfig[]) => { const saveConfigs = (configs: PaintScaleConfig[]) => {
window.electron.ipcRenderer window.electron.ipcRenderer
.invoke(setConfigsMethod, configs) .invoke(setConfigsMethod, configs)
.then(() => { .then(() => {
// Notify main process to update cron job // Notify main process to update cron job
if (configType === 'input') { if (configType === "input") {
window.electron.ipcRenderer.send(ipcTypes.toMain.settings.paintScale.updateInputCron, configs); window.electron.ipcRenderer.send(
} else if (configType === 'output') { ipcTypes.toMain.settings.paintScale.updateInputCron,
window.electron.ipcRenderer.send(ipcTypes.toMain.settings.paintScale.updateOutputCron, configs); configs,
} );
}) } else if (configType === "output") {
.catch((error) => { window.electron.ipcRenderer.send(
console.error(`Failed to save paint scale ${configType} configs:`, error); ipcTypes.toMain.settings.paintScale.updateOutputCron,
}); configs,
);
}
})
.catch((error) => {
console.error(
`Failed to save paint scale ${configType} configs:`,
error,
);
});
}; };
// New helper to check if a path is unique across input and output configs // New helper to check if a path is unique across input and output configs
const checkPathUnique = async (newPath: string): Promise<boolean> => { const checkPathUnique = async (newPath: string): Promise<boolean> => {
try { try {
const inputConfigs: PaintScaleConfig[] = await window.electron.ipcRenderer.invoke(ipcTypes.toMain.settings.paintScale.getInputConfigs); const inputConfigs: PaintScaleConfig[] =
const outputConfigs: PaintScaleConfig[] = await window.electron.ipcRenderer.invoke(ipcTypes.toMain.settings.paintScale.getOutputConfigs); await window.electron.ipcRenderer.invoke(
ipcTypes.toMain.settings.paintScale.getInputConfigs,
);
const outputConfigs: PaintScaleConfig[] =
await window.electron.ipcRenderer.invoke(
ipcTypes.toMain.settings.paintScale.getOutputConfigs,
);
const allConfigs = [...inputConfigs, ...outputConfigs]; const allConfigs = [...inputConfigs, ...outputConfigs];
// Allow updating the current config even if its current value equals newPath. // Allow updating the current config even if its current value equals newPath.
return !allConfigs.some(config => config.path === newPath); return !allConfigs.some((config) => config.path === newPath);
} catch (error) { } catch (error) {
console.error("Failed to check unique path:", error); console.error("Failed to check unique path:", error);
return false; return false;
@@ -74,10 +101,11 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
// Handle adding a new paint scale config // Handle adding a new paint scale config
const handleAddConfig = (type: PaintScaleType) => { const handleAddConfig = (type: PaintScaleType) => {
const defaultPolling = configType === "input" ? 1440 : 60;
const newConfig: PaintScaleConfig = { const newConfig: PaintScaleConfig = {
id: Date.now().toString(), id: Date.now().toString(),
type, type,
pollingInterval: 1440, // Default to 1440 seconds pollingInterval: defaultPolling, // Default to 1440 for input, 60 for output
}; };
const updatedConfigs = [...paintScaleConfigs, newConfig]; const updatedConfigs = [...paintScaleConfigs, newConfig];
setPaintScaleConfigs(updatedConfigs); setPaintScaleConfigs(updatedConfigs);
@@ -86,7 +114,9 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
// Handle removing a config // Handle removing a config
const handleRemoveConfig = (id: string) => { const handleRemoveConfig = (id: string) => {
const updatedConfigs = paintScaleConfigs.filter((config) => config.id !== id); const updatedConfigs = paintScaleConfigs.filter(
(config) => config.id !== id,
);
setPaintScaleConfigs(updatedConfigs); setPaintScaleConfigs(updatedConfigs);
saveConfigs(updatedConfigs); saveConfigs(updatedConfigs);
}; };
@@ -94,7 +124,10 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
// Handle path selection (modified to check directory uniqueness) // Handle path selection (modified to check directory uniqueness)
const handlePathChange = async (id: string) => { const handlePathChange = async (id: string) => {
try { try {
const path: string | null = await window.electron.ipcRenderer.invoke(setPathMethod, id); const path: string | null = await window.electron.ipcRenderer.invoke(
setPathMethod,
id,
);
if (path) { if (path) {
const isUnique = await checkPathUnique(path); const isUnique = await checkPathUnique(path);
if (!isUnique) { if (!isUnique) {
@@ -115,7 +148,7 @@ export const usePaintScaleConfig = (configType: ConfigType) => {
// Handle polling interval change // Handle polling interval change
const handlePollingIntervalChange = (id: string, pollingInterval: number) => { const handlePollingIntervalChange = (id: string, pollingInterval: number) => {
const updatedConfigs = paintScaleConfigs.map((config) => const updatedConfigs = paintScaleConfigs.map((config) =>
config.id === id ? { ...config, pollingInterval } : config, config.id === id ? { ...config, pollingInterval } : config,
); );
setPaintScaleConfigs(updatedConfigs); setPaintScaleConfigs(updatedConfigs);
saveConfigs(updatedConfigs); saveConfigs(updatedConfigs);

View File

@@ -35,7 +35,7 @@ const SettingsPaintScaleInputPaths = (): JSX.Element => {
handleRemoveConfig, handleRemoveConfig,
handlePathChange, handlePathChange,
handlePollingIntervalChange, handlePollingIntervalChange,
} = usePaintScaleConfig("input"); } = usePaintScaleConfig("output");
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [selectedType, setSelectedType] = useState<PaintScaleType | null>(null); const [selectedType, setSelectedType] = useState<PaintScaleType | null>(null);

View File

@@ -33,7 +33,7 @@ const SettingsPaintScaleOutputPaths = (): JSX.Element => {
handleRemoveConfig, handleRemoveConfig,
handlePathChange, handlePathChange,
handlePollingIntervalChange, handlePollingIntervalChange,
} = usePaintScaleConfig("output"); } = usePaintScaleConfig("input");
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [selectedType, setSelectedType] = useState<PaintScaleType | null>(null); const [selectedType, setSelectedType] = useState<PaintScaleType | null>(null);