diff --git a/README.md b/README.md index 89b278a..3a21f6d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +Creating Release Notes Tools: +https://onlinestringtools.com/json-stringify-string + This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). ## Available Scripts diff --git a/WIP Changelog.txt b/WIP Changelog.txt new file mode 100644 index 0000000..b72b11e --- /dev/null +++ b/WIP Changelog.txt @@ -0,0 +1,18 @@ +New Features: + +- Vehicles with mileage under 20,000kms will now be included in Watcher filtering criteria. +- Savings on OEM parts will always default to the user enter price and override the estimating system price. +- Wheel related lines will no longer be automatically ignored. +- Glass related lines will no longer be automatically ignored. +- Added 'Variance %' statistic to reporting totals. +- Automatically ignore any lines which have invalid prices from estimating system. +- Force line inclusion/exclusion - Using “ /rps-exclude” or “/rps” in the Part Number field to force inclusion or exclusion of lines for RPS calculation. + + +Bug Fixes: + +- Resolved an issue where the updater would not show update progress to some users. +- Fixed a UI bug during job search that would cause the 'no close date' alert to be incorrectly shown. + + + diff --git a/changelog.json b/changelog.json new file mode 100644 index 0000000..4ae60ec --- /dev/null +++ b/changelog.json @@ -0,0 +1,7 @@ +{ + "1.0.9": { + "title": "Release Notes for 1.0.9", + "date": "11/16/2020", + "notes": "New Features: \n\n- Vehicles with mileage under 20,000kms will now be included in Watcher filtering criteria.\n- Savings on OEM parts will always default to the user enter price and override the estimating system price.\n- Wheel related lines will no longer be automatically ignored.\n- Glass related lines will no longer be automatically ignored.\n- Added 'Variance %' statistic to reporting totals.\n- Automatically ignore any lines which have invalid prices from estimating system.\n- Force line inclusion/exclusion - Using “ /rps-exclude” or “/rps” in the Part Number field to force inclusion or exclusion of lines for RPS calculation.\n\n\nBug Fixes: \n\n- Resolved an issue where the updater would not show update progress to some users.\n- Fixed a UI bug during job search that would cause the 'no close date' alert to be incorrectly shown." + } +} diff --git a/electron/electron-store.js b/electron/electron-store.js index b444ac8..488fe8d 100644 --- a/electron/electron-store.js +++ b/electron/electron-store.js @@ -2,13 +2,14 @@ const Store = require("electron-store"); const store = new Store({ defaults: { + showChangeLog: true, enableNotifications: true, filePaths: [], accepted_ins_co: [], runWatcherOnStartup: true, polling: { enabled: false, - pollingInterval: 1000, + pollingInterval: 30000, }, }, }); diff --git a/electron/ipc-main-handler.js b/electron/ipc-main-handler.js index 54f9858..2d28b1a 100644 --- a/electron/ipc-main-handler.js +++ b/electron/ipc-main-handler.js @@ -1,4 +1,5 @@ -const { ipcMain } = require("electron"); +const { ipcMain, app: electronApp } = require("electron"); +const { app } = require("firebase"); const { default: ipcTypes } = require("../src/ipc.types"); const { store } = require("./electron-store"); //Import Ipc Handlers @@ -32,3 +33,13 @@ ipcMain.on(ipcTypes.store.getAll, (event, obj) => { const val = store.get(); event.sender.send(ipcTypes.store.response, val); }); + +ipcMain.on(ipcTypes.app.toMain.getReleaseNotes, (event, obj) => { + const showNotes = store.get("showChangeLog"); + if (showNotes) { + const rn = require("../changelog.json")[electronApp.getVersion()]; + event.sender.send(ipcTypes.app.toRenderer.setReleaseNotes, rn); + } else { + event.sender.send(ipcTypes.app.toRenderer.setReleaseNotes, null); + } +}); diff --git a/electron/main.js b/electron/main.js index f8f6d25..e9bb080 100644 --- a/electron/main.js +++ b/electron/main.js @@ -81,6 +81,15 @@ var menu = Menu.buildFromTemplate([ checkForUpdates(); }, }, + { + label: `Show Release Notes`, + click() { + mainWindow.webContents.send( + ipcTypes.app.toRenderer.setReleaseNotes, + require("../changelog.json")[app.getVersion()] + ); + }, + }, { label: "Open Config File", click() { @@ -318,6 +327,7 @@ autoUpdater.on("update-downloaded", (ev, info) => { if (buttonIndex === 0) { const isSilent = true; const isForceRunAfter = true; + store.set("showChangeLog", true); autoUpdater.quitAndInstall(isSilent, isForceRunAfter); } else { logger.error("Error"); diff --git a/src/components/molecules/release-notes/release-notes.molecule.jsx b/src/components/molecules/release-notes/release-notes.molecule.jsx new file mode 100644 index 0000000..6f118fc --- /dev/null +++ b/src/components/molecules/release-notes/release-notes.molecule.jsx @@ -0,0 +1,44 @@ +import { Modal } from "antd"; +import React, { useEffect } from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import ipcTypes from "../../../ipc.types"; +import { setReleaseNotes } from "../../../redux/application/application.actions"; +import { selectReleaseNotes } from "../../../redux/application/application.selectors"; +const mapStateToProps = createStructuredSelector({ + releaseNotes: selectReleaseNotes, +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) + setReleaseNotes: (notes) => dispatch(setReleaseNotes(notes)), +}); +const { ipcRenderer } = window; + +export function ReleaseNotes({ releaseNotes, setReleaseNotes }) { + console.log("ReleaseNotes -> releaseNotes", releaseNotes); + + useEffect(() => { + ipcRenderer.send(ipcTypes.default.app.toMain.getReleaseNotes); + }, []); + + const handleOk = () => { + ipcRenderer.send(ipcTypes.default.store.set, { showChangeLog: false }); + setReleaseNotes(null); + }; + + return ( + +
{releaseNotes && releaseNotes.date}
+
+ {releaseNotes && releaseNotes.notes} +
+
+ ); +} +export default connect(mapStateToProps, mapDispatchToProps)(ReleaseNotes); diff --git a/src/components/pages/routes/routes.page.jsx b/src/components/pages/routes/routes.page.jsx index b9299bb..4e89cff 100644 --- a/src/components/pages/routes/routes.page.jsx +++ b/src/components/pages/routes/routes.page.jsx @@ -5,6 +5,7 @@ import { Route } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../../redux/user/user.selectors"; import ErrorResultAtom from "../../atoms/error-result/error-result.atom"; +import ReleaseNotes from "../../molecules/release-notes/release-notes.molecule"; import SiderMenuOrganism from "../../organisms/sider-menu/sider-menu.organism"; import UpdateManagerOrganism from "../../organisms/update-manager/update-manager.organism"; import JobsPage from "../jobs/jobs.page"; @@ -40,7 +41,7 @@ export function RoutesPage({ bodyshop }) { - + diff --git a/src/ipc.types.js b/src/ipc.types.js index c4ebd88..95bdd3f 100644 --- a/src/ipc.types.js +++ b/src/ipc.types.js @@ -12,11 +12,13 @@ exports.default = { checkForUpdates: "app_checkForUpdates", downloadUpdates: "app_downloadUpdates", installUpdates: "app_installupdates", + getReleaseNotes: "app_getReleaseNotes", }, toRenderer: { updateAvailable: "app_updateAvailable", downloadProgress: "app_downloadProgress", signOut: "app_signOut", + setReleaseNotes: "app_setReleaseNotes", }, }, store: { diff --git a/src/ipc/ipc-renderer-handler.js b/src/ipc/ipc-renderer-handler.js index 87faa92..1d47322 100644 --- a/src/ipc/ipc-renderer-handler.js +++ b/src/ipc/ipc-renderer-handler.js @@ -1,5 +1,6 @@ import ipcTypes from "../ipc.types"; import { + setReleaseNotes, setSettings, setUpdateAvailable, setUpdateProgress, @@ -89,3 +90,10 @@ ipcRenderer.on( store.dispatch(signOutStart()); } ); + +ipcRenderer.on( + ipcTypes.default.app.toRenderer.setReleaseNotes, + async (event, releaseNotes) => { + store.dispatch(setReleaseNotes(releaseNotes)); + } +); diff --git a/src/redux/application/application.actions.js b/src/redux/application/application.actions.js index 71c4a0c..e38f2b8 100644 --- a/src/redux/application/application.actions.js +++ b/src/redux/application/application.actions.js @@ -52,3 +52,8 @@ export const setUpdateProgress = (progress) => ({ type: ApplicationActionTypes.SET_UPDATE_PROGRESS, payload: progress, }); + +export const setReleaseNotes = (releaseNotes) => ({ + type: ApplicationActionTypes.SET_RELEASE_NOTES, + payload: releaseNotes, +}); diff --git a/src/redux/application/application.reducer.js b/src/redux/application/application.reducer.js index c4896cc..549bbcc 100644 --- a/src/redux/application/application.reducer.js +++ b/src/redux/application/application.reducer.js @@ -9,6 +9,7 @@ const INITIAL_STATE = { settings: {}, updateAvailable: false, updateProgress: null, + releaseNotes: null, }; const { ipcRenderer } = window; @@ -66,6 +67,8 @@ const applicationReducer = (state = INITIAL_STATE, action) => { return { ...state, updateAvailable: action.payload }; case ApplicationActionTypes.SET_UPDATE_PROGRESS: return { ...state, updateProgress: action.payload }; + case ApplicationActionTypes.SET_RELEASE_NOTES: + return { ...state, releaseNotes: action.payload }; default: return state; } diff --git a/src/redux/application/application.selectors.js b/src/redux/application/application.selectors.js index aad8463..729e391 100644 --- a/src/redux/application/application.selectors.js +++ b/src/redux/application/application.selectors.js @@ -36,7 +36,13 @@ export const selectUpdateAvailable = createSelector( [selectApplication], (application) => application.updateAvailable ); + export const selectUpdateProgress = createSelector( [selectApplication], (application) => application.updateProgress ); + +export const selectReleaseNotes = createSelector( + [selectApplication], + (application) => application.releaseNotes +); diff --git a/src/redux/application/application.types.js b/src/redux/application/application.types.js index 3e24870..bdb4e27 100644 --- a/src/redux/application/application.types.js +++ b/src/redux/application/application.types.js @@ -10,6 +10,6 @@ const ApplicationActionTypes = { SET_SETTINGS: "SET_SETTINGS", SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE", SET_UPDATE_PROGRESS: "SET_UPDATE_PROGRESS", - + SET_RELEASE_NOTES: "SET_RELEASE_NOTES", }; export default ApplicationActionTypes;