Added polling for watcher.

This commit is contained in:
Patrick Fic
2020-10-20 10:53:50 -07:00
parent 900724f660
commit c277f6d32d
20 changed files with 205 additions and 19 deletions

View File

@@ -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" &&

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);
});

View File

@@ -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)

View File

@@ -0,0 +1 @@
[]

View 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

View File

@@ -0,0 +1 @@
[]

View 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

View 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>
);
}

View File

@@ -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;
}
};

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>

View File

@@ -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: {

View File

@@ -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));
});

View File

@@ -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,
});

View File

@@ -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;
}

View File

@@ -26,3 +26,8 @@ export const selectSelectedJobTargetPc = createSelector(
[selectApplication],
(application) => application.selectedJobTargetPc
);
export const selectSettings = createSelector(
[selectApplication],
(application) => application.settings
);

View File

@@ -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;