From 0a3c87a6f2ce041df9cc6063d9781516f77d5fd2 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 14 Oct 2020 17:08:47 -0700 Subject: [PATCH] Implemented job upload --- electron/decoder/decoder.js | 106 ++++++++++-------- electron/file-watcher/file-watcher-ipc.js | 49 ++++++-- electron/file-watcher/file-watcher.js | 57 ++++++++-- electron/ipc-main-handler.js | 16 +-- electron/main.js | 34 ++++-- .../down.yaml | 5 + .../up.yaml | 6 + .../down.yaml | 5 + .../up.yaml | 5 + .../down.yaml | 5 + .../up.yaml | 5 + hasura/migrations/metadata.yaml | 12 +- package-lock.json | 64 +++++++---- package.json | 1 + .../filepath-add/filepath-add.molecule.jsx | 11 ++ .../filepath-item/filepath-item.molecule.jsx | 4 +- .../filepaths-list.organism.jsx | 2 + src/components/pages/jobs/jobs.page.jsx | 4 +- src/components/test.jsx | 12 +- src/graphql/jobs.queries.js | 26 +++++ src/ipc.types.js | 2 + src/ipc/ipc-estimate-utils.js | 16 +++ src/ipc/ipc-renderer-handler.js | 27 ++++- src/redux/application/application.sagas.js | 2 +- src/redux/root.reducer.js | 2 +- 25 files changed, 347 insertions(+), 131 deletions(-) create mode 100644 hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/down.yaml create mode 100644 hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/up.yaml create mode 100644 hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/down.yaml create mode 100644 hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/up.yaml create mode 100644 hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/down.yaml create mode 100644 hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/up.yaml create mode 100644 src/components/molecules/filepath-add/filepath-add.molecule.jsx create mode 100644 src/graphql/jobs.queries.js create mode 100644 src/ipc/ipc-estimate-utils.js diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index a787e6d..17e0730 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -5,6 +5,7 @@ const _ = require("lodash"); async function DecodeEstimate(filePath) { const parsedFilePath = path.parse(filePath); let extensionlessFilePath = `${parsedFilePath.dir}\\${parsedFilePath.name}`; + console.log("DecodeEstimate -> extensionlessFilePath", extensionlessFilePath); const ret = { ...(await DecodeAd1File(extensionlessFilePath)), @@ -150,7 +151,7 @@ async function DecodeVehFile(extensionlessFilePath) { // "V_PROD_DT", "V_MODEL_YR", // "V_MAKECODE", - "V_MAKEDESC", + "V_MAKE_DESC", "V_MODEL", "V_TYPE", // "V_BSTYLE", @@ -177,53 +178,62 @@ async function DecodeLinFile(extensionlessFilePath) { let records = await dbf.readRecords(); let joblines = records.map((record) => - _.pick(record, [ - // "LINE_NO", - "LINE_IND", - // "LINE_REF", - // "TRAN_CODE", - // "DB_REF", - "UNQ_SEQ", - // "WHO_PAYS", - "LINE_DESC", - "PART_TYPE", - // "PART_DESCJ", - // "GLASS_FLAG", - "OEM_PARTNO", - // "PRICE_INC", - // "ALT_PART_I", - // "TAX_PART", - "DB_PRICE", - "ACT_PRICE", - // "PRICE_J", - // "CERT_PART", - "PART_QTY", - // "ALT_CO_ID", - // "ALT_PARTNO", - // "ALT_OVERRD", - // "ALT_PARTM", - // "PRT_DSMK_P", - // "PRT_DSMK_M", - // "MOD_LBR_TY", - // "DB_HRS", - // "MOD_LB_HRS", - // "LBR_INC", - // "LBR_OP", - // "LBR_HRS_J", - // "LBR_TYP_J", - // "LBR_OP_J", - // "PAINT_STG", - // "PAINT_TONE", - // "LBR_TAX", - // "LBR_AMT", - // "MISC_AMT", - // "MISC_SUBLT", - // "MISC_TAX", - // "BETT_TYPE", - // "BETT_PCTG", - // "BETT_AMT", - // "BETT_TAX", - ]) + _.transform( + _.pick(record, [ + // "LINE_NO", + "LINE_IND", + // "LINE_REF", + // "TRAN_CODE", + // "DB_REF", + "UNQ_SEQ", + // "WHO_PAYS", + "LINE_DESC", + "PART_TYPE", + // "PART_DESCJ", + // "GLASS_FLAG", + "OEM_PARTNO", + // "PRICE_INC", + // "ALT_PART_I", + // "TAX_PART", + "DB_PRICE", + "ACT_PRICE", + // "PRICE_J", + // "CERT_PART", + "PART_QTY", + // "ALT_CO_ID", + // "ALT_PARTNO", + // "ALT_OVERRD", + // "ALT_PARTM", + // "PRT_DSMK_P", + // "PRT_DSMK_M", + // "MOD_LBR_TY", + // "DB_HRS", + // "MOD_LB_HRS", + // "LBR_INC", + // "LBR_OP", + // "LBR_HRS_J", + // "LBR_TYP_J", + // "LBR_OP_J", + // "PAINT_STG", + // "PAINT_TONE", + // "LBR_TAX", + // "LBR_AMT", + // "MISC_AMT", + // "MISC_SUBLT", + // "MISC_TAX", + // "BETT_TYPE", + // "BETT_PCTG", + // "BETT_AMT", + // "BETT_TAX", + ]), + function (result, val, key) { + if (key === "UNQ_SEQ") { + console.log("unq"); + return (result[key.toLowerCase()] = val.toString()); + } + return (result[key.toLowerCase()] = val); + } + ) ); return { joblines: { data: joblines } }; } diff --git a/electron/file-watcher/file-watcher-ipc.js b/electron/file-watcher/file-watcher-ipc.js index 504cab2..16442b6 100644 --- a/electron/file-watcher/file-watcher-ipc.js +++ b/electron/file-watcher/file-watcher-ipc.js @@ -1,14 +1,49 @@ -const { ipcMain } = require("electron"); +const { ipcMain, dialog } = require("electron"); const { StartWatcher, StopWatcher } = require("./file-watcher"); -const ipcTypes = require("../../src/ipc.types").default; +const ipcTypes = require("../../src/ipc.types"); +const settings = require("electron-settings"); +const { mainWindow } = require("../main"); +const _ = require("lodash"); -ipcMain.on(ipcTypes.fileWatcher.toMain.start, async (event, arg) => { +ipcMain.on( + ipcTypes.default.fileWatcher.toMain.filepathsGet, + async (event, object) => { + const filePaths = await settings.get("filePaths"); + event.reply( + ipcTypes.default.fileWatcher.toRenderer.filepathsList, + filePaths + ); + } +); + +ipcMain.on(ipcTypes.default.fileWatcher.toMain.start, async (event, arg) => { const filePaths = StartWatcher(); - event.sender.send(ipcTypes.fileWatcher.toRenderer.startSuccess, filePaths); - event.sender.send(ipcTypes.fileWatcher.toRenderer.filepathsList, filePaths); + // event.sender.send(ipcTypes.default.fileWatcher.toRenderer.startSuccess); + event.sender.send( + ipcTypes.default.fileWatcher.toRenderer.filepathsList, + filePaths + ); }); -ipcMain.on(ipcTypes.fileWatcher.toMain.stop, async (event, arg) => { +ipcMain.on(ipcTypes.default.fileWatcher.toMain.stop, async (event, arg) => { StopWatcher(); - event.sender.send(ipcTypes.fileWatcher.toRenderer.stopSuccess); + event.sender.send(ipcTypes.default.fileWatcher.toRenderer.stopSuccess); +}); + +ipcMain.on(ipcTypes.default.fileWatcher.toMain.addPath, async (event, arg) => { + const result = await dialog.showOpenDialog(mainWindow, { + properties: ["openDirectory"], + }); + + await settings.set( + "filePaths", + _.union(result.filePaths, await settings.get("filePaths")) + ); + + const newFilePaths = await settings.get("filePaths"); + + event.sender.send( + ipcTypes.default.fileWatcher.toRenderer.filepathsList, + newFilePaths + ); }); diff --git a/electron/file-watcher/file-watcher.js b/electron/file-watcher/file-watcher.js index 33e6528..2f0698b 100644 --- a/electron/file-watcher/file-watcher.js +++ b/electron/file-watcher/file-watcher.js @@ -1,15 +1,27 @@ const chokidar = require("chokidar"); -const { ipcMain } = require("electron"); const settings = require("electron-settings"); -const { default: ipcTypes } = require("../../src/ipc.types"); +const ipcTypes = require("../../src/ipc.types"); +const path = require("path"); +const { DecodeEstimate } = require("../decoder/decoder"); +const { BrowserWindow, Notification } = require("electron"); +const _ = require("lodash"); var watcher; function StartWatcher() { - const filePaths = settings.getSync("filePaths") || []; + const filePaths = + settings + .getSync("filePaths") + .map((fp) => path.join(fp, "**.[eE][nN][vV]")) || []; console.log("StartWatcher -> filePaths", filePaths); + + Notification({ + title: "Watcher started!", + body: "Watcher has been started..", + }).show(); + watcher = chokidar.watch(filePaths, { - ignored: /[\/\\]\./, + //ignored: /[\/\\]\./, persistent: true, ignoreInitial: true, awaitWriteFinish: { @@ -18,14 +30,16 @@ function StartWatcher() { }, }); watcher - .on("add", function (path) { + .on("add", async function (path) { console.log("File", path, "has been added"); + HandleNewFile(path); }) .on("addDir", function (path) { console.log("Directory", path, "has been added"); }) - .on("change", function (path) { + .on("change", async function (path) { console.log("File", path, "has been changed"); + HandleNewFile(path); }) .on("unlink", function (path) { console.log("File", path, "has been removed"); @@ -35,27 +49,48 @@ function StartWatcher() { }) .on("error", function (error) { console.log("Error happened", error); - ipcMain.emit(ipcTypes.fileWatcher.toRenderer.error, error); + const b = BrowserWindow.getFocusedWindow(); + b.webContents.send(ipcTypes.fileWatcher.toRenderer.error, error); }) .on("ready", onWatcherReady) .on("raw", function (event, path, details) { // This event should be triggered everytime something happens. - console.log("Raw event info:", event, path, details); + // console.log("Raw event info:", event, path, details); }); return filePaths; } function onWatcherReady() { console.log("Ready!"); - ipcMain.emit(ipcTypes.fileWatcher.toRenderer.startSuccess); + const b = BrowserWindow.getFocusedWindow(); + b.webContents.send(ipcTypes.default.fileWatcher.toRenderer.startSuccess); } async function StopWatcher() { await watcher.close(); - ipcMain.emit(ipcTypes.fileWatcher.toRenderer.stopSuccess); - console.log("Watcher Stopped!", watcher); + console.log("Watcher Stopped!"); } exports.StartWatcher = StartWatcher; exports.StopWatcher = StopWatcher; exports.watcher = watcher; + +async function HandleNewFile(path) { + const b = BrowserWindow.getAllWindows()[0]; + b.webContents.send(ipcTypes.default.estimate.toRenderer.estimateDecodeStart); + const newJob = await DecodeEstimate(path); + const newJobLow = _.transform(newJob, function (result, val, key) { + result[key.toLowerCase()] = val; + }); + console.log("HandleNewFile -> newJobLow", newJobLow); + + b.webContents.send( + ipcTypes.default.estimate.toRenderer.estimateDecodeSuccess, + newJobLow + ); + + Notification({ + title: "Job Uploaded", + body: "A new job has been uploaded.", + }).show(); +} diff --git a/electron/ipc-main-handler.js b/electron/ipc-main-handler.js index 7060c5e..eccd0a8 100644 --- a/electron/ipc-main-handler.js +++ b/electron/ipc-main-handler.js @@ -8,19 +8,9 @@ require("./file-watcher/file-watcher-ipc"); console.log("*** Added IPC Handlers ***"); -ipcMain.on( - ipcTypes.default.fileWatcher.toMain.filepathsGet, - async (event, object) => { - const filePaths = await settings.get("filePaths"); - event.reply( - ipcTypes.default.fileWatcher.toRenderer.filepathsList, - filePaths - ); - } -); - ipcMain.on("test", async (event, object) => { console.log("Received test IPC Command"); - const job = await DecodeEstimate("C:\\VPS\\EMS\\687_3_A.AD1"); - event.reply("test-success", { status: 0, message: null, data: job }); + //const job = await DecodeEstimate("C:\\VPS\\EMS\\687_3_A.AD1"); + console.log(mainWindow); + event.reply("test-toRenderer", { status: 0, message: null }); }); diff --git a/electron/main.js b/electron/main.js index e172924..c74b575 100644 --- a/electron/main.js +++ b/electron/main.js @@ -1,7 +1,9 @@ const path = require("path"); -const { app, BrowserWindow } = require("electron"); +const { app, BrowserWindow, ipcMain } = require("electron"); const isDev = require("electron-is-dev"); const settings = require("electron-settings"); +const ipcTypes = require("../src/ipc.types"); +const { StartWatcher } = require("./file-watcher/file-watcher"); require("./ipc-main-handler"); @@ -20,8 +22,9 @@ if (require("electron-squirrel-startup")) { console.log(`${__dirname}/preload.js`); -var mainWindow = null; +let mainWindow; function createWindow() { + makeSingleInstance(); // Create the browser window. mainWindow = new BrowserWindow({ width: 800, @@ -35,7 +38,6 @@ function createWindow() { preload: path.join(__dirname, "preload.js"), // use a preload script }, }); - // and load the index.html of the app. // win.loadFile("index.html"); mainWindow.loadURL( @@ -46,15 +48,17 @@ function createWindow() { // Open the DevTools. if (isDev) { - mainWindow.webContents.openDevTools({ mode: "detach" }); + mainWindow.webContents.openDevTools({ + // mode: "detach" + }); } } + exports.mainWindow = mainWindow; // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.whenReady().then(() => { - console.log("*** Ready to launch the app! ***"); createWindow(); if (isDev) { @@ -63,10 +67,14 @@ app.whenReady().then(() => { .then((name) => console.log(`Added Extension: ${name}`)) .catch((error) => console.log(`An error occurred: , ${error}`)); } - - //Start all of the watchers. + StartWatcher(); + // ipcMain.on(ipcTypes.default.webcontent, (event, ...obj) => { + // console.log("event", event); + // mainWindow.webContents.send(event, obj); + // }); }); +if (isDev) app.setAppUserModelId(process.execPath); // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. @@ -86,3 +94,15 @@ app.on("activate", () => { // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here. +function makeSingleInstance() { + if (process.mas) return; + + app.requestSingleInstanceLock(); + + app.on("second-instance", () => { + if (mainWindow) { + if (mainWindow.isMinimized()) mainWindow.restore(); + mainWindow.focus(); + } + }); +} diff --git a/hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/down.yaml b/hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/down.yaml new file mode 100644 index 0000000..adaad75 --- /dev/null +++ b/hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."jobs" drop constraint "jobs_clm_no_bodyshopid_key"; + type: run_sql diff --git a/hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/up.yaml b/hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/up.yaml new file mode 100644 index 0000000..e8b3334 --- /dev/null +++ b/hasura/migrations/1602717130843_alter_table_public_jobs_add_unique_clm_no_bodyshopid/up.yaml @@ -0,0 +1,6 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."jobs" add constraint "jobs_clm_no_bodyshopid_key" unique + ("clm_no", "bodyshopid"); + type: run_sql diff --git a/hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/down.yaml b/hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/down.yaml new file mode 100644 index 0000000..d3bd873 --- /dev/null +++ b/hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."jobs" rename column "v_model" to "v_model_desc"; + type: run_sql diff --git a/hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/up.yaml b/hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/up.yaml new file mode 100644 index 0000000..c4c2b53 --- /dev/null +++ b/hasura/migrations/1602720058650_alter_table_public_jobs_alter_column_v_model_desc/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."jobs" rename column "v_model_desc" to "v_model"; + type: run_sql diff --git a/hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/down.yaml b/hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/down.yaml new file mode 100644 index 0000000..6bf888c --- /dev/null +++ b/hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."jobs" rename column "v_makedesc" to "v_make_desc"; + type: run_sql diff --git a/hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/up.yaml b/hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/up.yaml new file mode 100644 index 0000000..dc17a92 --- /dev/null +++ b/hasura/migrations/1602720224048_alter_table_public_jobs_alter_column_v_make_desc/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."jobs" rename column "v_make_desc" to "v_makedesc"; + type: run_sql diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml index 6ad254f..9a1dd0c 100644 --- a/hasura/migrations/metadata.yaml +++ b/hasura/migrations/metadata.yaml @@ -165,8 +165,8 @@ tables: - ownr_ln - ownr_fn - v_vin - - v_make_desc - - v_model_desc + - v_makedesc + - v_model - v_model_yr - v_type backend_only: false @@ -180,8 +180,8 @@ tables: - ownr_fn - ownr_ln - ro_number - - v_make_desc - - v_model_desc + - v_makedesc + - v_model - v_model_yr - v_type - v_vin @@ -205,8 +205,8 @@ tables: - ownr_fn - ownr_ln - ro_number - - v_make_desc - - v_model_desc + - v_makedesc + - v_model - v_model_yr - v_type - v_vin diff --git a/package-lock.json b/package-lock.json index d92fda7..294235e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2541,6 +2541,28 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "node-notifier": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2548,6 +2570,14 @@ "requires": { "has-flag": "^3.0.0" } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -13890,34 +13920,22 @@ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" }, "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", "requires": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", "shellwords": "^0.1.1", - "which": "^1.3.0" + "uuid": "^8.3.0", + "which": "^2.0.2" }, "dependencies": { - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" } } }, diff --git a/package.json b/package.json index aa937f0..a823908 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "firebase": "^7.23.0", "graphql": "^15.3.0", "lodash": "^4.17.20", + "node-notifier": "^8.0.0", "node-sass": "^4.14.1", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/src/components/molecules/filepath-add/filepath-add.molecule.jsx b/src/components/molecules/filepath-add/filepath-add.molecule.jsx new file mode 100644 index 0000000..40be795 --- /dev/null +++ b/src/components/molecules/filepath-add/filepath-add.molecule.jsx @@ -0,0 +1,11 @@ +import { Button } from "antd"; +import React from "react"; +import ipcTypes from "../../../ipc.types"; +const { ipcRenderer } = window; + +export default function FilepathAddMolecule() { + const handleClick = () => { + ipcRenderer.send(ipcTypes.default.fileWatcher.toMain.addPath); + }; + return ; +} diff --git a/src/components/molecules/filepath-item/filepath-item.molecule.jsx b/src/components/molecules/filepath-item/filepath-item.molecule.jsx index 3ad4325..50c6286 100644 --- a/src/components/molecules/filepath-item/filepath-item.molecule.jsx +++ b/src/components/molecules/filepath-item/filepath-item.molecule.jsx @@ -1,6 +1,6 @@ import { List } from "antd"; import React from "react"; -export default function FilePathMolecule(item) { - return {item}; +export default function FilePathMolecule(item, index) { + return {item}; } diff --git a/src/components/organisms/filepaths-list/filepaths-list.organism.jsx b/src/components/organisms/filepaths-list/filepaths-list.organism.jsx index 522e8a5..4745876 100644 --- a/src/components/organisms/filepaths-list/filepaths-list.organism.jsx +++ b/src/components/organisms/filepaths-list/filepaths-list.organism.jsx @@ -4,6 +4,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import ipcTypes from "../../../ipc.types"; import { selectWatchedPaths } from "../../../redux/application/application.selectors"; +import FilepathAddMolecule from "../../molecules/filepath-add/filepath-add.molecule"; import FilepathItemMolecule from "../../molecules/filepath-item/filepath-item.molecule"; const { ipcRenderer } = window; @@ -24,6 +25,7 @@ export function FilePathsList({ watchedPaths }) {
File Paths +
); } diff --git a/src/components/pages/jobs/jobs.page.jsx b/src/components/pages/jobs/jobs.page.jsx index 9215f6b..ccb9c2e 100644 --- a/src/components/pages/jobs/jobs.page.jsx +++ b/src/components/pages/jobs/jobs.page.jsx @@ -1,8 +1,9 @@ +import { Button } from "antd"; import React from "react"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; -//const { ipcRenderer } = window; +const { ipcRenderer } = window; //const settings = window.require("electron-settings"); const mapStateToProps = createStructuredSelector({}); @@ -26,6 +27,7 @@ export function JobsPage() { return (
Welcome to your new react app.
+
); } diff --git a/src/components/test.jsx b/src/components/test.jsx index a7f07a2..a76ac2b 100644 --- a/src/components/test.jsx +++ b/src/components/test.jsx @@ -12,18 +12,12 @@ const mapDispatchToProps = (dispatch) => ({}); export function App() { useEffect(() => { - ipcRenderer.on("test-success", (event, obj) => { - console.log("Test Success", obj); - }); - ipcRenderer.on(ipcTypes.default.filewatcher.startSuccess, (event, obj) => { - console.log(ipcTypes.default.filewatcher.startSuccess, obj); + ipcRenderer.on("not a real channel", (event, obj) => { + console.log("not a real channel", obj); }); // Cleanup the listener events so that memory leaks are avoided. return function cleanup() { - ipcRenderer.removeAllListeners( - "test-success", - ipcTypes.default.filewatcher.startSuccess - ); + ipcRenderer.removeAllListeners("not a real channel"); }; }, []); diff --git a/src/graphql/jobs.queries.js b/src/graphql/jobs.queries.js new file mode 100644 index 0000000..dc10dd7 --- /dev/null +++ b/src/graphql/jobs.queries.js @@ -0,0 +1,26 @@ +import gql from "graphql-tag"; + +export const INSERT_NEW_JOB = gql` + mutation INSERT_JOB($job: [jobs_insert_input!]!) { + insert_jobs(objects: $job) { + returning { + id + } + } + } +`; + +// on_conflict: { +// constraint: jobs_clm_no_bodyshopid_key +// update_columns: [ +// ins_co_nm +// clm_no +// clm_total +// ownr_ln +// ownr_fn +// v_vin +// v_make_desc +// v_model_desc +// v_type +// ] +// } diff --git a/src/ipc.types.js b/src/ipc.types.js index 692020b..4bad674 100644 --- a/src/ipc.types.js +++ b/src/ipc.types.js @@ -1,4 +1,5 @@ exports.default = { + webcontent: "webcontent-send", test: { start: "test-start", }, @@ -7,6 +8,7 @@ exports.default = { filepathsGet: "filewatcher__filepathsget", start: "filewatcher__start", stop: "filewatcher__stop", + addPath: "filewatcher__addPath", }, toRenderer: { filepathsList: "filewatcher__filepathslist", diff --git a/src/ipc/ipc-estimate-utils.js b/src/ipc/ipc-estimate-utils.js new file mode 100644 index 0000000..bd51bc1 --- /dev/null +++ b/src/ipc/ipc-estimate-utils.js @@ -0,0 +1,16 @@ +import client from "../graphql/GraphQLClient"; +import { INSERT_NEW_JOB } from "../graphql/jobs.queries"; +import { store } from "../redux/store"; + +export async function UpsertEstimate(job) { + const shopId = store.getState().user.bodyshop.id; + console.log("UpsertEstimate -> shopId", shopId); + + const result = await client.mutate({ + mutation: INSERT_NEW_JOB, + variables: { + job: { ...job, bodyshopid: shopId }, + }, + }); + console.log("UpsertEstimate -> result", result); +} diff --git a/src/ipc/ipc-renderer-handler.js b/src/ipc/ipc-renderer-handler.js index 4d0b4bb..f609879 100644 --- a/src/ipc/ipc-renderer-handler.js +++ b/src/ipc/ipc-renderer-handler.js @@ -4,9 +4,15 @@ import { setWatcherStatus, } from "../redux/application/application.actions"; import { store } from "../redux/store"; +import { message } from "antd"; +import { UpsertEstimate } from "./ipc-estimate-utils"; + const { ipcRenderer } = window; console.log("----Initializing IPC Listeners in React App."); +ipcRenderer.on("test-toRenderer", (event, obj) => { + console.log("test-toRenderer", obj); +}); ipcRenderer.on( ipcTypes.default.fileWatcher.toRenderer.filepathsList, @@ -15,10 +21,12 @@ ipcRenderer.on( } ); -//Filewatcher Section +//Filewatcher Status Section ipcRenderer.on( ipcTypes.default.fileWatcher.toRenderer.startSuccess, (event, ...obj) => { + console.log("Watcher ready."); + message.success("Watcher started!"); store.dispatch(setWatcherStatus("READY!")); } ); @@ -28,10 +36,25 @@ ipcRenderer.on( store.dispatch(setWatcherStatus("STOPPED")); } ); - ipcRenderer.on( ipcTypes.default.fileWatcher.toRenderer.error, (event, ...obj) => { store.dispatch(setWatcherStatus(obj)); } ); + +//Estimate Section +ipcRenderer.on( + ipcTypes.default.estimate.toRenderer.estimateDecodeStart, + (event, ...obj) => { + console.log("Decoding started!"); + } +); + +ipcRenderer.on( + ipcTypes.default.estimate.toRenderer.estimateDecodeSuccess, + async (event, ...obj) => { + console.log("Decoding success!", obj[0]); + await UpsertEstimate(obj[0]); + } +); diff --git a/src/redux/application/application.sagas.js b/src/redux/application/application.sagas.js index 9c961be..4d19439 100644 --- a/src/redux/application/application.sagas.js +++ b/src/redux/application/application.sagas.js @@ -1,5 +1,5 @@ //import { all, call, takeLatest } from "redux-saga/effects"; -import ApplicationActionTypes from "./application.types"; +//import ApplicationActionTypes from "./application.types"; // export function* onJoinRoom() { // yield takeLatest(ApplicationActionTypes.JOIN_ROOM, joinRoom); diff --git a/src/redux/root.reducer.js b/src/redux/root.reducer.js index 71c41c8..067e904 100644 --- a/src/redux/root.reducer.js +++ b/src/redux/root.reducer.js @@ -7,7 +7,7 @@ import userReducer from "./user/user.reducer"; const persistConfig = { key: "root", storage, - // blacklist: ["application"], + blacklist: ["application"], }; const rootReducer = combineReducers({