Added polling for watcher.
This commit is contained in:
@@ -330,11 +330,11 @@ async function DecodeLinFile(extensionlessFilePath) {
|
||||
(jobline) =>
|
||||
jobline.part_type &&
|
||||
!jobline.db_ref.startsWith("900") &&
|
||||
!jobline.db_ref.toLowerCase().startsWith("urethane") &&
|
||||
!jobline.db_ref.toLowerCase().startsWith("wheel") &&
|
||||
!jobline.db_ref.toLowerCase().startsWith("hazardous") &&
|
||||
!jobline.db_ref.toLowerCase().startsWith("detail") &&
|
||||
!jobline.db_ref.toLowerCase().startsWith("clean") &&
|
||||
!jobline.line_desc.toLowerCase().startsWith("urethane") &&
|
||||
!jobline.line_desc.toLowerCase().startsWith("wheel") &&
|
||||
!jobline.line_desc.toLowerCase().startsWith("hazardous") &&
|
||||
!jobline.line_desc.toLowerCase().startsWith("detail") &&
|
||||
!jobline.line_desc.toLowerCase().startsWith("clean") &&
|
||||
jobline.part_type.toUpperCase() !== "PAG" &&
|
||||
jobline.part_type.toUpperCase() !== "PAS" &&
|
||||
jobline.part_type.toUpperCase() !== "PASL" &&
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
const Store = require("electron-store");
|
||||
|
||||
const store = new Store({ defaults: { filePaths: [], accepted_ins_co: [] } });
|
||||
const store = new Store({
|
||||
defaults: {
|
||||
filePaths: [],
|
||||
accepted_ins_co: [],
|
||||
polling: {
|
||||
enabled: false,
|
||||
pollingInterval: 100,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
exports.store = store;
|
||||
|
||||
@@ -7,35 +7,38 @@ const { store } = require("../electron-store");
|
||||
const {
|
||||
NewNotification,
|
||||
} = require("../notification-wrapper/notification-wrapper");
|
||||
|
||||
const log = require("electron-log");
|
||||
var watcher;
|
||||
|
||||
async function StartWatcher() {
|
||||
const filePaths =
|
||||
store.get("filePaths").map((fp) => path.join(fp, "**.[eE][nN][vV]")) || [];
|
||||
console.log("StartWatcher -> filePaths", filePaths);
|
||||
|
||||
log.info("StartWatcher -> filePaths", filePaths);
|
||||
log.info("Use polling? ", store.get("polling").enabled);
|
||||
|
||||
if (filePaths.length === 0) {
|
||||
NewNotification({
|
||||
title: "RPS Watcher cannot start",
|
||||
body: "Please set the appropriate file paths and try again.",
|
||||
}).show();
|
||||
log.warn("Cannot start watcher. No file paths set.");
|
||||
return [];
|
||||
}
|
||||
|
||||
if (watcher) {
|
||||
try {
|
||||
console.log("Trying to close watcher - it already existed.");
|
||||
log.info("Trying to close watcher - it already existed.");
|
||||
await watcher.close();
|
||||
|
||||
console.log("Watcher closed successfully!");
|
||||
log.info("Watcher closed successfully!");
|
||||
} catch (error) {
|
||||
console.log("Error trying to close Watcher.", error);
|
||||
log.error("Error trying to close Watcher.", error);
|
||||
}
|
||||
}
|
||||
|
||||
watcher = chokidar.watch(filePaths, {
|
||||
//ignored: /[\/\\]\./,
|
||||
usePolling: store.get("polling").enabled,
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
awaitWriteFinish: {
|
||||
@@ -88,7 +91,7 @@ function onWatcherReady() {
|
||||
|
||||
async function StopWatcher() {
|
||||
await watcher.close();
|
||||
console.log("Watcher stopped.");
|
||||
log.info("Watcher stopped.");
|
||||
const b = BrowserWindow.getAllWindows()[0];
|
||||
b.webContents.send(ipcTypes.default.fileWatcher.toRenderer.stopSuccess);
|
||||
NewNotification({
|
||||
@@ -111,12 +114,13 @@ async function HandleNewFile(path) {
|
||||
ipcTypes.default.estimate.toRenderer.estimateDecodeSuccess,
|
||||
newJob
|
||||
);
|
||||
|
||||
log.info(`Sent job for upload. ${newJob.clm_no}`);
|
||||
NewNotification({
|
||||
title: "Job Uploaded",
|
||||
body: "A new job has been uploaded.",
|
||||
}).show();
|
||||
} else {
|
||||
log.info(`Ignored job. ${newJob.ERROR}`);
|
||||
NewNotification({
|
||||
title: "Job Ignored",
|
||||
body: newJob.ERROR,
|
||||
|
||||
@@ -17,3 +17,20 @@ ipcMain.on("test", async (event, object) => {
|
||||
ipcMain.on(ipcTypes.app.toMain.setAcceptableInsCoNm, (event, insCos) => {
|
||||
store.set("accepted_ins_co", insCos);
|
||||
});
|
||||
|
||||
ipcMain.on(ipcTypes.store.get, (event, key) => {
|
||||
const val = store.get(key);
|
||||
event.sender.send(ipcTypes.store.response, { [key]: val });
|
||||
});
|
||||
|
||||
ipcMain.on(ipcTypes.store.set, (event, key, val) => {
|
||||
store.set(key, val);
|
||||
|
||||
const st = store.get();
|
||||
event.sender.send(ipcTypes.store.response, st);
|
||||
});
|
||||
|
||||
ipcMain.on(ipcTypes.store.getAll, (event, obj) => {
|
||||
const val = store.get();
|
||||
event.sender.send(ipcTypes.store.response, val);
|
||||
});
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
[1014/195617.530:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3)
|
||||
[1015/081931.328:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3)
|
||||
[1020/073641.000:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
18
hasura/migrations/1603204459690_run_sql_migration/up.yaml
Normal file
18
hasura/migrations/1603204459690_run_sql_migration/up.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
- args:
|
||||
cascade: true
|
||||
read_only: false
|
||||
sql: "CREATE OR REPLACE FUNCTION public.search_jobs(search text, startdate date,
|
||||
enddate date)\n RETURNS SETOF jobs\n LANGUAGE plpgsql\n STABLE\nAS $function$
|
||||
BEGIN if search = '' then return query\nselect *\nfrom jobs j;\nelse\n\nif (startDate
|
||||
is null) or (endDate is null) then \nreturn query\nSELECT *\nFROM jobs j2\nWHERE
|
||||
\n\nownr_fn ILIKE '%' || search || '%'\n or ownr_ln ILIKE '%' || search ||
|
||||
'%'\n \n or clm_no ILIKE '%' || search || '%'\nORDER BY \n clm_no ILIKE
|
||||
'%' || search || '%'\n OR null,\n ownr_fn ILIKE '%' || search || '%'\n
|
||||
\ OR NULL,\n ownr_ln ILIKE '%' || search || '%'\n OR NULL;\nelse \nreturn
|
||||
query\nSELECT *\nFROM jobs j2\nWHERE \nclose_date between startDate and endDate
|
||||
and close_date is not null and\n(\nownr_fn ILIKE '%' || search || '%'\n or
|
||||
ownr_ln ILIKE '%' || search || '%'\n \n or clm_no ILIKE '%' || search ||
|
||||
'%')\n\nORDER BY \n clm_no ILIKE '%' || search || '%'\n OR null,\n ownr_fn
|
||||
ILIKE '%' || search || '%'\n OR NULL,\n ownr_ln ILIKE '%' || search ||
|
||||
'%'\n OR NULL;\n\nend if;\n\n\nend if;\nEND $function$;"
|
||||
type: run_sql
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
19
hasura/migrations/1603204604474_run_sql_migration/up.yaml
Normal file
19
hasura/migrations/1603204604474_run_sql_migration/up.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
- args:
|
||||
cascade: true
|
||||
read_only: false
|
||||
sql: "CREATE OR REPLACE FUNCTION public.search_jobs(search text, startdate date,
|
||||
enddate date)\n RETURNS SETOF jobs\n LANGUAGE plpgsql\n STABLE\nAS $function$\nBEGIN
|
||||
if search = '' and ((startDate is null) or (endDate is null)) then return query\nselect
|
||||
*\nfrom jobs j;\nelse\n\nif (startDate is null) or (endDate is null) then \nreturn
|
||||
query\nSELECT *\nFROM jobs j2\nWHERE \n\nownr_fn ILIKE '%' || search || '%'\n
|
||||
\ or ownr_ln ILIKE '%' || search || '%'\n \n or clm_no ILIKE '%' || search
|
||||
|| '%'\nORDER BY \n clm_no ILIKE '%' || search || '%'\n OR null,\n ownr_fn
|
||||
ILIKE '%' || search || '%'\n OR NULL,\n ownr_ln ILIKE '%' || search ||
|
||||
'%'\n OR NULL;\nelse \nreturn query\nSELECT *\nFROM jobs j2\nWHERE \nclose_date
|
||||
between startDate and endDate and close_date is not null and\n(\nownr_fn ILIKE
|
||||
'%' || search || '%'\n or ownr_ln ILIKE '%' || search || '%'\n \n or
|
||||
clm_no ILIKE '%' || search || '%')\n\nORDER BY \n clm_no ILIKE '%' || search
|
||||
|| '%'\n OR null,\n ownr_fn ILIKE '%' || search || '%'\n OR NULL,\n
|
||||
\ ownr_ln ILIKE '%' || search || '%'\n OR NULL;\n\nend if;\n\n\nend if;\nEND
|
||||
$function$;"
|
||||
type: run_sql
|
||||
26
src/components/atoms/data-label/data-label.atom.jsx
Normal file
26
src/components/atoms/data-label/data-label.atom.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React from "react";
|
||||
|
||||
export default function DataLabel({
|
||||
label,
|
||||
hideIfNull,
|
||||
children,
|
||||
vertical,
|
||||
visible = true,
|
||||
...props
|
||||
}) {
|
||||
if (!visible || (hideIfNull && !!!children)) return null;
|
||||
|
||||
return (
|
||||
<div {...props}>
|
||||
<div
|
||||
style={{
|
||||
display: vertical ? "block" : "inline-block",
|
||||
marginRight: ".2rem",
|
||||
}}
|
||||
>{`${label}: `}</div>
|
||||
<div style={{ display: vertical ? "block" : "inline-block" }}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
export default (part_type) => {
|
||||
switch (part_type) {
|
||||
case "PAA":
|
||||
case "PAL":
|
||||
case "PAC":
|
||||
return "A/M";
|
||||
case "PAE":
|
||||
return "Exist.";
|
||||
case "PAN":
|
||||
case "PAP":
|
||||
return "OEM";
|
||||
case "PAL":
|
||||
return "LKQ";
|
||||
|
||||
default:
|
||||
return "?";
|
||||
return part_type;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { InputNumber, Switch } from "antd";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import ipcTypes from "../../../ipc.types";
|
||||
import { selectSettings } from "../../../redux/application/application.selectors";
|
||||
import DataLabel from "../../atoms/data-label/data-label.atom";
|
||||
const { ipcRenderer } = window;
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
appSettings: selectSettings,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
export function WatcherPollingMolecule({ appSettings }) {
|
||||
const handlePollingToggle = (val) => {
|
||||
ipcRenderer.send(ipcTypes.default.store.set, { "polling.enabled": val });
|
||||
};
|
||||
const handleIntervalChange = (val) => {
|
||||
ipcRenderer.send(ipcTypes.default.store.set, {
|
||||
"polling.pollingInterval": val,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DataLabel label="Polling Enabled? (Recommended for Network Monitoring)">
|
||||
<Switch
|
||||
onChange={handlePollingToggle}
|
||||
checked={
|
||||
appSettings && appSettings.polling && appSettings.polling.enabled
|
||||
}
|
||||
/>
|
||||
</DataLabel>
|
||||
<DataLabel label="Polling Interval">
|
||||
<InputNumber
|
||||
onChange={handleIntervalChange}
|
||||
value={
|
||||
appSettings &&
|
||||
appSettings.polling &&
|
||||
appSettings.polling.pollingInterval
|
||||
}
|
||||
/>
|
||||
</DataLabel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(WatcherPollingMolecule);
|
||||
@@ -21,7 +21,6 @@ export function FilePathsList({ watchedPaths }) {
|
||||
ipcRenderer.send(ipcTypes.default.fileWatcher.toMain.filepathsGet);
|
||||
}, []);
|
||||
|
||||
console.log("watchedPaths", watchedPaths);
|
||||
return (
|
||||
<div>
|
||||
<Typography.Title>Watcher File Paths</Typography.Title>
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { Col, Row } from "antd";
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import ipcTypes from "../../../ipc.types";
|
||||
import WatcherPollingMolecule from "../../molecules/watcher-polling/watcher-polling.molecule";
|
||||
import FilePathsListOrganism from "../../organisms/filepaths-list/filepaths-list.organism";
|
||||
import ShopSettingsOrganism from "../../organisms/shop-settings/shop-settings.organism";
|
||||
import WatcherManagerOrganism from "../../organisms/watcher-manager/watcher-manager.organism";
|
||||
const { ipcRenderer } = window;
|
||||
|
||||
export default function SettingsPage() {
|
||||
useEffect(() => {
|
||||
ipcRenderer.send(ipcTypes.default.store.getAll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Row gutter={[16, 16]}>
|
||||
@@ -13,6 +20,7 @@ export default function SettingsPage() {
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<WatcherManagerOrganism />
|
||||
<WatcherPollingMolecule />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
|
||||
@@ -9,6 +9,12 @@ exports.default = {
|
||||
setAcceptableInsCoNm: "setAcceptableInsCoNm",
|
||||
},
|
||||
},
|
||||
store: {
|
||||
get: "store__get",
|
||||
getAll: "store_getAll",
|
||||
set: "store_set",
|
||||
response: "store_response",
|
||||
},
|
||||
fileWatcher: {
|
||||
toMain: {
|
||||
filepathsGet: "filewatcher__filepathsget",
|
||||
@@ -16,6 +22,7 @@ exports.default = {
|
||||
stop: "filewatcher__stop",
|
||||
addPath: "filewatcher__addPath",
|
||||
removePath: "filewatcher__removePath",
|
||||
setPolling: "filewatcher__setPolling",
|
||||
},
|
||||
toRenderer: {
|
||||
filepathsList: "filewatcher__filepathslist",
|
||||
@@ -23,6 +30,7 @@ exports.default = {
|
||||
startFailure: "filewatcher__start-failure",
|
||||
stopSuccess: "filewatcher__stop-success",
|
||||
error: "filewatcher__error",
|
||||
getPolling: "filewatcher__getPolling",
|
||||
},
|
||||
},
|
||||
estimate: {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import ipcTypes from "../ipc.types";
|
||||
import {
|
||||
setSettings,
|
||||
setWatchedPaths,
|
||||
setWatcherStatus,
|
||||
} from "../redux/application/application.actions";
|
||||
@@ -52,3 +53,7 @@ ipcRenderer.on(
|
||||
await UpsertEstimate(obj);
|
||||
}
|
||||
);
|
||||
|
||||
ipcRenderer.on(ipcTypes.default.store.response, (event, obj) => {
|
||||
store.dispatch(setSettings(obj));
|
||||
});
|
||||
|
||||
@@ -38,3 +38,7 @@ export const setSelectedJobTargetPcSuccess = (pct) => ({
|
||||
type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC_SUCCESS,
|
||||
payload: pct,
|
||||
});
|
||||
export const setSettings = (settingsObj) => ({
|
||||
type: ApplicationActionTypes.SET_SETTINGS,
|
||||
payload: settingsObj,
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ const INITIAL_STATE = {
|
||||
watcherError: null,
|
||||
selectedJobId: null,
|
||||
selectedJobTargetPc: 100,
|
||||
settings: {},
|
||||
};
|
||||
|
||||
const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
@@ -41,6 +42,9 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
};
|
||||
case ApplicationActionTypes.SET_SELECTED_JOB_ID:
|
||||
return { ...state, selectedJobId: action.payload };
|
||||
case ApplicationActionTypes.SET_SETTINGS:
|
||||
return { ...state, settings: { ...state.settings, ...action.payload } };
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -26,3 +26,8 @@ export const selectSelectedJobTargetPc = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.selectedJobTargetPc
|
||||
);
|
||||
|
||||
export const selectSettings = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.settings
|
||||
);
|
||||
|
||||
@@ -7,5 +7,6 @@ const ApplicationActionTypes = {
|
||||
SET_SELECTED_JOB_ID: "SET_SELECTED_JOB_ID",
|
||||
SET_SELECTED_JOB_TARGET_PC: "SET_SELECTED_JOB_TARGET_PC",
|
||||
SET_SELECTED_JOB_TARGET_PC_SUCCESS: "SET_SELECTED_JOB_TARGET_PC_SUCCESS",
|
||||
SET_SETTINGS: "SET_SETTINGS",
|
||||
};
|
||||
export default ApplicationActionTypes;
|
||||
|
||||
Reference in New Issue
Block a user