Compare commits
15 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1cda41f56 | ||
|
|
97282740f5 | ||
|
|
150ae02978 | ||
|
|
abeffb2a19 | ||
|
|
70058b6bd4 | ||
|
|
67c63f81d9 | ||
|
|
fb8452b2bb | ||
|
|
1f281e8439 | ||
|
|
223c705e8f | ||
|
|
00d8b533f4 | ||
|
|
3b25a8fe07 | ||
|
|
a57b9cddb5 | ||
|
|
064ed1bb8b | ||
|
|
efda254981 | ||
|
|
3fa6b8b6ac |
@@ -31,3 +31,11 @@
|
||||
|
||||
These allow users to turn fields on or off, turning them all off will show the card in the most minimal form
|
||||
|
||||
|
||||
### Statistics
|
||||
|
||||
- The statistics section allows users to see accumulations of both jobs on the board, and jobs in production.
|
||||
- you can click a statistic to turn it on and off, and drag and drop the statistics to rearrange them
|
||||
|
||||
### Filters
|
||||
- Allows you to set, and persist filters for estimators and insurance companies
|
||||
|
||||
@@ -1,174 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
|
||||
<link rel="icon" href="/ro-favicon.png" />
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
|
||||
<link rel="icon" href="/pm/pm-favicon.ico" />
|
||||
<% } %>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
|
||||
<link rel="icon" href="/favicon.png" />
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
|
||||
<link rel="icon" href="/ro-favicon.png" />
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
|
||||
<link rel="icon" href="/pm/pm-favicon.ico" />
|
||||
<% } %>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#1690ff" />
|
||||
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
|
||||
<!-- TODO:AIo Update the individual logos for each.-->
|
||||
<link rel="apple-touch-icon" href="public/logo192.png" />
|
||||
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#1690ff" />
|
||||
<!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
|
||||
<!-- TODO:AIo Update the individual logos for each.-->
|
||||
<link rel="apple-touch-icon" href="public/logo192.png" />
|
||||
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
|
||||
<meta name="description" content="ImEX Online" />
|
||||
<title>ImEX Online</title>
|
||||
<script type="text/javascript">
|
||||
window.$crisp = [];
|
||||
window.CRISP_WEBSITE_ID = '36724f62-2eb0-4b29-9cdd-9905fb99913e';
|
||||
(function () {
|
||||
d = document;
|
||||
s = d.createElement('script');
|
||||
s.src = 'https://client.crisp.chat/l.js';
|
||||
s.async = 1;
|
||||
d.getElementsByTagName('head')[0].appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
|
||||
<meta name="description" content="Rome Online" />
|
||||
<title>Rome Online</title>
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
|
||||
<meta name="description" content="ImEX Online" />
|
||||
<title>ImEX Online</title>
|
||||
<script type="text/javascript">
|
||||
window.$crisp = [];
|
||||
window.CRISP_WEBSITE_ID = '36724f62-2eb0-4b29-9cdd-9905fb99913e';
|
||||
(function () {
|
||||
d = document;
|
||||
s = d.createElement('script');
|
||||
s.src = 'https://client.crisp.chat/l.js';
|
||||
s.async = 1;
|
||||
d.getElementsByTagName('head')[0].appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
|
||||
<meta name="description" content="Rome Online" />
|
||||
<title>Rome Online</title>
|
||||
|
||||
<!--Use the below code snippet to provide real time updates to the live chat plugin without the need of copying and paste each time to your website when changes are made via PBX-->
|
||||
<!--Use the below code snippet to provide real time updates to the live chat plugin without the need of copying and paste each time to your website when changes are made via PBX-->
|
||||
|
||||
<call-us-selector phonesystem-url=https://rometech.east.3cx.us:5001 party="LiveChat528346"></call-us-selector>
|
||||
<call-us-selector phonesystem-url=https://rometech.east.3cx.us:5001 party="LiveChat528346"></call-us-selector>
|
||||
|
||||
<!--Incase you don't want real time updates to the live chat plugin when options are changed, use the below code snippet. Please note that each time you change the settings you will need to copy and paste the snippet code to your website-->
|
||||
|
||||
<!--<call-us
|
||||
|
||||
phonesystem-url=https://rometech.east.3cx.us:5001
|
||||
|
||||
style="position:fixed;font-size:16px;line-height:17px;z-index: 99999;right: 20px; bottom: 20px;"
|
||||
|
||||
id="wp-live-chat-by-3CX"
|
||||
|
||||
minimized="true"
|
||||
|
||||
animation-style="noanimation"
|
||||
|
||||
party="LiveChat528346"
|
||||
|
||||
minimized-style="bubbleright"
|
||||
|
||||
allow-call="true"
|
||||
|
||||
allow-video="false"
|
||||
|
||||
allow-soundnotifications="true"
|
||||
|
||||
enable-mute="true"
|
||||
|
||||
enable-onmobile="true"
|
||||
|
||||
offline-enabled="true"
|
||||
|
||||
enable="true"
|
||||
|
||||
ignore-queueownership="false"
|
||||
|
||||
authentication="both"
|
||||
|
||||
show-operator-actual-name="true"
|
||||
|
||||
aknowledge-received="true"
|
||||
|
||||
gdpr-enabled="false"
|
||||
|
||||
message-userinfo-format="name"
|
||||
|
||||
message-dateformat="both"
|
||||
|
||||
lang="browser"
|
||||
|
||||
button-icon-type="default"
|
||||
|
||||
greeting-visibility="none"
|
||||
|
||||
greeting-offline-visibility="none"
|
||||
|
||||
chat-delay="2000"
|
||||
|
||||
enable-direct-call="true"
|
||||
|
||||
enable-ga="false"
|
||||
|
||||
></call-us>-->
|
||||
|
||||
<script defer src=https://downloads-global.3cx.com/downloads/livechatandtalk/v1/callus.js id="tcx-callus-js" charset="utf-8"></script>
|
||||
<!--Incase you don't want real time updates to the live chat plugin when options are changed, use the below code snippet. Please note that each time you change the settings you will need to copy and paste the snippet code to your website-->
|
||||
|
||||
<!--<call-us
|
||||
|
||||
phonesystem-url=https://rometech.east.3cx.us:5001
|
||||
|
||||
style="position:fixed;font-size:16px;line-height:17px;z-index: 99999;right: 20px; bottom: 20px;"
|
||||
|
||||
id="wp-live-chat-by-3CX"
|
||||
|
||||
minimized="true"
|
||||
|
||||
animation-style="noanimation"
|
||||
|
||||
party="LiveChat528346"
|
||||
|
||||
minimized-style="bubbleright"
|
||||
|
||||
allow-call="true"
|
||||
|
||||
allow-video="false"
|
||||
|
||||
allow-soundnotifications="true"
|
||||
|
||||
enable-mute="true"
|
||||
|
||||
enable-onmobile="true"
|
||||
|
||||
offline-enabled="true"
|
||||
|
||||
enable="true"
|
||||
|
||||
ignore-queueownership="false"
|
||||
|
||||
authentication="both"
|
||||
|
||||
show-operator-actual-name="true"
|
||||
|
||||
aknowledge-received="true"
|
||||
|
||||
gdpr-enabled="false"
|
||||
|
||||
message-userinfo-format="name"
|
||||
|
||||
message-dateformat="both"
|
||||
|
||||
lang="browser"
|
||||
|
||||
button-icon-type="default"
|
||||
|
||||
greeting-visibility="none"
|
||||
|
||||
greeting-offline-visibility="none"
|
||||
|
||||
chat-delay="2000"
|
||||
|
||||
enable-direct-call="true"
|
||||
|
||||
enable-ga="false"
|
||||
|
||||
></call-us>-->
|
||||
|
||||
<script defer src=https://downloads-global.3cx.com/downloads/livechatandtalk/v1/callus.js id="tcx-callus-js" charset="utf-8"></script>
|
||||
|
||||
|
||||
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
|
||||
<title>ProManager</title>
|
||||
<meta name="description" content="ProManager" />
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
|
||||
<title>ProManager</title>
|
||||
<meta name="description" content="ProManager" />
|
||||
|
||||
<% } %>
|
||||
<script>
|
||||
!(function () {
|
||||
'use strict';
|
||||
var e = [
|
||||
'debug',
|
||||
'destroy',
|
||||
'do',
|
||||
'help',
|
||||
'identify',
|
||||
'is',
|
||||
'off',
|
||||
'on',
|
||||
'ready',
|
||||
'render',
|
||||
'reset',
|
||||
'safe',
|
||||
'set',
|
||||
];
|
||||
if (window.noticeable) console.warn('Noticeable SDK code snippet loaded more than once');
|
||||
else {
|
||||
var n = (window.noticeable = window.noticeable || []);
|
||||
function t(e) {
|
||||
return function () {
|
||||
var t = Array.prototype.slice.call(arguments);
|
||||
return t.unshift(e), n.push(t), n;
|
||||
};
|
||||
}
|
||||
!(function () {
|
||||
for (var o = 0; o < e.length; o++) {
|
||||
var r = e[o];
|
||||
n[r] = t(r);
|
||||
}
|
||||
})(),
|
||||
(function () {
|
||||
var e = document.createElement('script');
|
||||
(e.async = !0), (e.src = 'https://sdk.noticeable.io/l.js');
|
||||
var n = document.head;
|
||||
n.insertBefore(e, n.firstChild);
|
||||
})();
|
||||
<% } %>
|
||||
<script>
|
||||
!(function () {
|
||||
'use strict';
|
||||
var e = [
|
||||
'debug',
|
||||
'destroy',
|
||||
'do',
|
||||
'help',
|
||||
'identify',
|
||||
'is',
|
||||
'off',
|
||||
'on',
|
||||
'ready',
|
||||
'render',
|
||||
'reset',
|
||||
'safe',
|
||||
'set',
|
||||
];
|
||||
if (window.noticeable) console.warn('Noticeable SDK code snippet loaded more than once');
|
||||
else {
|
||||
var n = (window.noticeable = window.noticeable || []);
|
||||
function t(e) {
|
||||
return function () {
|
||||
var t = Array.prototype.slice.call(arguments);
|
||||
return t.unshift(e), n.push(t), n;
|
||||
};
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
!(function () {
|
||||
for (var o = 0; o < e.length; o++) {
|
||||
var r = e[o];
|
||||
n[r] = t(r);
|
||||
}
|
||||
})(),
|
||||
(function () {
|
||||
var e = document.createElement('script');
|
||||
(e.async = !0), (e.src = 'https://sdk.noticeable.io/l.js');
|
||||
var n = document.head;
|
||||
n.insertBefore(e, n.firstChild);
|
||||
})();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="module" src="src/index.jsx"></script>
|
||||
</body>
|
||||
<script type="module" src="src/index.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
1280
client/package-lock.json
generated
1280
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,22 +8,22 @@
|
||||
"private": true,
|
||||
"proxy": "http://localhost:4000",
|
||||
"dependencies": {
|
||||
"@ant-design/pro-layout": "^7.19.11",
|
||||
"@apollo/client": "^3.10.8",
|
||||
"@ant-design/pro-layout": "^7.19.12",
|
||||
"@apollo/client": "^3.11.4",
|
||||
"@emotion/is-prop-valid": "^1.3.0",
|
||||
"@fingerprintjs/fingerprintjs": "^4.4.3",
|
||||
"@jsreport/browser-client": "^3.1.0",
|
||||
"@reduxjs/toolkit": "^2.2.6",
|
||||
"@sentry/cli": "^2.32.2",
|
||||
"@reduxjs/toolkit": "^2.2.7",
|
||||
"@sentry/cli": "^2.33.1",
|
||||
"@sentry/react": "^7.114.0",
|
||||
"@splitsoftware/splitio-react": "^1.12.0",
|
||||
"@splitsoftware/splitio-react": "^1.12.1",
|
||||
"@tanem/react-nprogress": "^5.0.51",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"antd": "^5.19.3",
|
||||
"antd": "^5.20.1",
|
||||
"apollo-link-logger": "^2.0.1",
|
||||
"apollo-link-sentry": "^3.3.0",
|
||||
"autosize": "^6.0.1",
|
||||
"axios": "^1.6.8",
|
||||
"axios": "^1.7.4",
|
||||
"classnames": "^2.5.1",
|
||||
"css-box-model": "^1.2.1",
|
||||
"dayjs": "^1.11.12",
|
||||
@@ -32,45 +32,44 @@
|
||||
"dotenv": "^16.4.5",
|
||||
"env-cmd": "^10.1.0",
|
||||
"exifr": "^7.1.3",
|
||||
"firebase": "^10.12.4",
|
||||
"firebase": "^10.12.5",
|
||||
"graphql": "^16.9.0",
|
||||
"i18next": "^23.12.2",
|
||||
"i18next": "^23.12.3",
|
||||
"i18next-browser-languagedetector": "^8.0.0",
|
||||
"immutability-helper": "^3.1.1",
|
||||
"libphonenumber-js": "^1.11.4",
|
||||
"logrocket": "^8.1.1",
|
||||
"libphonenumber-js": "^1.11.5",
|
||||
"logrocket": "^8.1.2",
|
||||
"markerjs2": "^2.32.1",
|
||||
"memoize-one": "^6.0.0",
|
||||
"normalize-url": "^8.0.1",
|
||||
"object-hash": "^3.0.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"query-string": "^9.0.0",
|
||||
"query-string": "^9.1.0",
|
||||
"raf-schd": "^4.0.3",
|
||||
"react": "^18.3.1",
|
||||
"react-big-calendar": "^1.13.1",
|
||||
"react-big-calendar": "^1.13.2",
|
||||
"react-color": "^2.19.3",
|
||||
"react-cookie": "^7.1.4",
|
||||
"react-cookie": "^7.2.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-drag-listview": "^2.0.0",
|
||||
"react-grid-gallery": "^1.0.1",
|
||||
"react-grid-layout": "1.3.4",
|
||||
"react-i18next": "^14.1.3",
|
||||
"react-icons": "^5.2.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"react-image-lightbox": "^5.1.4",
|
||||
"react-joyride": "^2.8.2",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-number-format": "^5.4.0",
|
||||
"react-popopo": "^2.1.9",
|
||||
"react-product-fruits": "^2.2.6",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-resizable": "^3.0.5",
|
||||
"react-router-dom": "^6.25.1",
|
||||
"react-router-dom": "^6.26.0",
|
||||
"react-sticky": "^6.0.3",
|
||||
"react-virtualized": "^9.22.5",
|
||||
"react-virtuoso": "^4.7.12",
|
||||
"react-virtuoso": "^4.10.1",
|
||||
"recharts": "^2.12.7",
|
||||
"redux": "^5.0.1",
|
||||
"redux-actions": "^3.0.0",
|
||||
"redux-actions": "^3.0.3",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-saga": "^1.3.0",
|
||||
"redux-state-sync": "^3.1.4",
|
||||
@@ -80,7 +79,7 @@
|
||||
"styled-components": "^6.1.12",
|
||||
"subscriptions-transport-ws": "^0.11.0",
|
||||
"use-memo-one": "^1.1.3",
|
||||
"userpilot": "^1.3.2",
|
||||
"userpilot": "^1.3.5",
|
||||
"vite-plugin-ejs": "^1.7.0",
|
||||
"web-vitals": "^3.5.2"
|
||||
},
|
||||
@@ -131,29 +130,29 @@
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"@babel/preset-react": "^7.24.7",
|
||||
"@dotenvx/dotenvx": "^1.6.4",
|
||||
"@dotenvx/dotenvx": "^1.7.0",
|
||||
"@emotion/babel-plugin": "^11.12.0",
|
||||
"@emotion/react": "^11.12.0",
|
||||
"@sentry/webpack-plugin": "^2.21.1",
|
||||
"@emotion/react": "^11.13.0",
|
||||
"@sentry/webpack-plugin": "^2.22.2",
|
||||
"@testing-library/cypress": "^10.0.2",
|
||||
"browserslist": "^4.23.2",
|
||||
"browserslist": "^4.23.3",
|
||||
"browserslist-to-esbuild": "^2.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"cypress": "^13.13.1",
|
||||
"cypress": "^13.13.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-plugin-cypress": "^2.15.1",
|
||||
"memfs": "^4.9.3",
|
||||
"memfs": "^4.11.1",
|
||||
"os-browserify": "^0.3.0",
|
||||
"react-error-overlay": "6.0.11",
|
||||
"redux-logger": "^3.0.6",
|
||||
"source-map-explorer": "^2.5.3",
|
||||
"vite": "^5.3.4",
|
||||
"vite": "^5.4.0",
|
||||
"vite-plugin-babel": "^1.2.0",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-legacy": "^2.1.0",
|
||||
"vite-plugin-node-polyfills": "^0.22.0",
|
||||
"vite-plugin-pwa": "^0.20.0",
|
||||
"vite-plugin-pwa": "^0.20.1",
|
||||
"vite-plugin-style-import": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,3 +161,15 @@
|
||||
.rowWithColor > td {
|
||||
background-color: var(--bgColor) !important;
|
||||
}
|
||||
|
||||
.muted-button {
|
||||
color: lightgray;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-size: 16px; /* Adjust as needed */
|
||||
}
|
||||
|
||||
.muted-button:hover {
|
||||
color: darkgrey;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,6 @@ export default function DashboardScheduledOutToday({ data, ...cardProps }) {
|
||||
};
|
||||
});
|
||||
|
||||
console.log("Scheduled Out Today");
|
||||
console.dir(scheduledOutToday);
|
||||
|
||||
const tvFontSize = 18;
|
||||
const tvFontWeight = "bold";
|
||||
|
||||
|
||||
@@ -16,18 +16,15 @@ import useLocalStorage from "../../utils/useLocalStorage";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import { setJoyRideSteps } from "../../redux/application/application.actions";
|
||||
import { OwnerNameDisplayFunction } from "./../owner-name-display/owner-name-display.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setJoyRideSteps: (steps) => dispatch(setJoyRideSteps(steps))
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({});
|
||||
|
||||
export function JobsList({ bodyshop, setJoyRideSteps }) {
|
||||
export function JobsList({ bodyshop }) {
|
||||
const searchParams = queryString.parse(useLocation().search);
|
||||
const { selected } = searchParams;
|
||||
const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
|
||||
|
||||
@@ -360,14 +360,7 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe
|
||||
const headerContent = (
|
||||
<div className="header-content-container">
|
||||
<div className="inner-container">
|
||||
<ProductionAlert
|
||||
record={{
|
||||
id: card.id,
|
||||
production_vars: card?.metadata.production_vars,
|
||||
refetch: card?.refetch
|
||||
}}
|
||||
key="alert"
|
||||
/>
|
||||
<ProductionAlert id={card.id} productionVars={metadata?.production_vars} refetch={card?.refetch} key="alert" />
|
||||
{metadata?.suspended && <PauseCircleOutlined className="circle-outline" key="suspended" />}
|
||||
{metadata?.iouparent && (
|
||||
<EllipsesToolTip
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ExclamationCircleFilled } from "@ant-design/icons";
|
||||
import { ExclamationCircleFilled, PlusCircleFilled } from "@ant-design/icons";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { Button } from "antd";
|
||||
import { Button, Popconfirm } from "antd";
|
||||
import React, { useCallback } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
@@ -8,6 +8,7 @@ import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({});
|
||||
|
||||
@@ -22,22 +23,24 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
)
|
||||
});
|
||||
|
||||
const ProductionListColumnAlert = ({ record, insertAuditTrail }) => {
|
||||
const ProductionListColumnAlert = ({ id, productionVars, refetch, insertAuditTrail }) => {
|
||||
const [updateAlert] = useMutation(UPDATE_JOB);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleAlertToggle = useCallback(() => {
|
||||
logImEXEvent("production_toggle_alert");
|
||||
|
||||
const newAlertState = !!record.production_vars?.alert ? !record.production_vars.alert : true;
|
||||
const newAlertState = !!productionVars?.alert ? !productionVars?.alert : true;
|
||||
const finalProductionVars = {
|
||||
...productionVars,
|
||||
alert: newAlertState
|
||||
};
|
||||
|
||||
updateAlert({
|
||||
variables: {
|
||||
jobId: record.id,
|
||||
jobId: id,
|
||||
job: {
|
||||
production_vars: {
|
||||
...record.production_vars,
|
||||
alert: newAlertState
|
||||
}
|
||||
production_vars: finalProductionVars
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
@@ -45,17 +48,26 @@ const ProductionListColumnAlert = ({ record, insertAuditTrail }) => {
|
||||
});
|
||||
|
||||
insertAuditTrail({
|
||||
jobid: record.id,
|
||||
jobid: id,
|
||||
operation: AuditTrailMapping.alertToggle(newAlertState),
|
||||
type: "alertToggle"
|
||||
});
|
||||
|
||||
if (record.refetch) record.refetch();
|
||||
}, [updateAlert, insertAuditTrail, record]);
|
||||
if (refetch) refetch();
|
||||
}, [updateAlert, insertAuditTrail, id, productionVars, refetch]);
|
||||
|
||||
if (!record.production_vars?.alert) return null;
|
||||
|
||||
return <Button className="production-alert" icon={<ExclamationCircleFilled />} onClick={handleAlertToggle} />;
|
||||
return productionVars?.alert ? (
|
||||
<Popconfirm
|
||||
title={t("general.actions.remove_alert")}
|
||||
onConfirm={handleAlertToggle}
|
||||
okText={t("general.labels.yes")}
|
||||
cancelText={t("general.labels.no")}
|
||||
>
|
||||
<Button className="production-alert" icon={<ExclamationCircleFilled />} />
|
||||
</Popconfirm>
|
||||
) : (
|
||||
<Button className="muted-button" icon={<PlusCircleFilled />} onClick={handleAlertToggle} />
|
||||
);
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ProductionListColumnAlert);
|
||||
|
||||
@@ -23,7 +23,7 @@ import ProductionListColumnPartsReceived from "./production-list-columns.partsre
|
||||
import ProductionListColumnNote from "./production-list-columns.productionnote.component";
|
||||
import ProductionListColumnCategory from "./production-list-columns.status.category";
|
||||
import ProductionListColumnStatus from "./production-list-columns.status.component";
|
||||
import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component";
|
||||
import ProductionListColumnTouchTime from "./prodution-list-columns.touchtime.component";
|
||||
import { store } from "../../redux/store";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
@@ -349,7 +349,9 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
|
||||
key: "alert",
|
||||
sorter: (a, b) => Number(a.production_vars?.alert || false) - Number(b.production_vars?.alert || false),
|
||||
sortOrder: state.sortedInfo.columnKey === "alert" && state.sortedInfo.order,
|
||||
render: (text, record) => <ProductionListColumnAlert record={{ record }} />
|
||||
render: (text, record) => (
|
||||
<ProductionListColumnAlert id={record.id} productionVars={record?.production_vars} refetch={refetch} />
|
||||
)
|
||||
},
|
||||
{
|
||||
title: i18n.t("production.labels.note"),
|
||||
@@ -370,7 +372,7 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
|
||||
dataIndex: "tt",
|
||||
key: "tt",
|
||||
render: (text, record) => {
|
||||
return <ProductionlistColumnTouchTime job={record} />;
|
||||
return <ProductionListColumnTouchTime job={record} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -148,6 +148,7 @@ export function ProductionListEmpAssignment({ insertAuditTrail, bodyshop, record
|
||||
) : (
|
||||
<PlusCircleFilled
|
||||
style={iconStyle}
|
||||
className="muted-button"
|
||||
onClick={() => {
|
||||
setAssignment({ operation: type });
|
||||
setVisibility(true);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { AlertOutlined } from "@ant-design/icons";
|
||||
import { Alert, Button, Col, Row, Space } from "antd";
|
||||
import i18n from "i18next";
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
@@ -12,39 +12,42 @@ import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
updateAvailable: selectUpdateAvailable
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
// setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(UpdateAlert);
|
||||
const intervalMS = 10 * 60 * 1000;
|
||||
|
||||
export function UpdateAlert({ updateAvailable }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
offlineReady: [
|
||||
offlineReady //setOfflineReady
|
||||
],
|
||||
needRefresh: [
|
||||
needRefresh //setNeedRefresh
|
||||
],
|
||||
offlineReady: [offlineReady],
|
||||
needRefresh: [needRefresh],
|
||||
updateServiceWorker
|
||||
} = useRegisterSW({
|
||||
onRegistered(r) {
|
||||
// eslint-disable-next-line prefer-template
|
||||
console.log("SW Registered: " + r);
|
||||
r &&
|
||||
setInterval(() => {
|
||||
r.update();
|
||||
}, intervalMS);
|
||||
console.log("SW Registered:", r);
|
||||
if (r) {
|
||||
setInterval(
|
||||
() => {
|
||||
r.update();
|
||||
},
|
||||
10 * 60 * 1000
|
||||
);
|
||||
}
|
||||
},
|
||||
onRegisterError(error) {
|
||||
console.log("SW registration error", error);
|
||||
console.error("SW registration error", error);
|
||||
}
|
||||
});
|
||||
|
||||
if (import.meta.env.DEV) console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`);
|
||||
useEffect(() => {
|
||||
if (import.meta.env.DEV) {
|
||||
console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`);
|
||||
}
|
||||
}, [needRefresh, offlineReady]);
|
||||
|
||||
if (!needRefresh) return null;
|
||||
|
||||
return (
|
||||
<Alert
|
||||
message={t("general.messages.newversiontitle", {
|
||||
@@ -69,19 +72,10 @@ export function UpdateAlert({ updateAvailable }) {
|
||||
</Col>
|
||||
<Col sm={24} md={8} lg={6}>
|
||||
<Space wrap>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
window.open("https://imex-online.noticeable.news/", "_blank");
|
||||
}}
|
||||
>
|
||||
<Button onClick={() => window.open("https://imex-online.noticeable.news/", "_blank")}>
|
||||
{i18n.t("general.actions.viewreleasenotes")}
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={async () => {
|
||||
updateServiceWorker(true);
|
||||
}}
|
||||
>
|
||||
<Button type="primary" onClick={() => updateServiceWorker(true)}>
|
||||
{i18n.t("general.actions.refresh")}
|
||||
</Button>
|
||||
</Space>
|
||||
@@ -93,3 +87,5 @@ export function UpdateAlert({ updateAvailable }) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(UpdateAlert);
|
||||
|
||||
@@ -12,7 +12,6 @@ import ErrorBoundary from "../../components/error-boundary/error-boundary.compon
|
||||
//import FooterComponent from "../../components/footer/footer.component";
|
||||
//Component Imports
|
||||
import * as Sentry from "@sentry/react";
|
||||
import Joyride from "react-joyride";
|
||||
import TestComponent from "../../components/_test/test.page";
|
||||
import HeaderContainer from "../../components/header/header.container";
|
||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||
@@ -23,8 +22,6 @@ import { requestForToken } from "../../firebase/firebase.utils";
|
||||
import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors";
|
||||
|
||||
import UpdateAlert from "../../components/update-alert/update-alert.component";
|
||||
import { setJoyRideFinished } from "../../redux/application/application.actions.js";
|
||||
import { selectEnableJoyRide, selectJoyRideSteps } from "../../redux/application/application.selectors.js";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr.js";
|
||||
import "./manage.page.styles.scss";
|
||||
|
||||
@@ -105,16 +102,12 @@ const { Content, Footer } = Layout;
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
conflict: selectInstanceConflict,
|
||||
bodyshop: selectBodyshop,
|
||||
enableJoyRide: selectEnableJoyRide,
|
||||
joyRideSteps: selectJoyRideSteps
|
||||
bodyshop: selectBodyshop
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setJoyRideFinished: (steps) => dispatch(setJoyRideFinished(steps))
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({});
|
||||
|
||||
export function Manage({ conflict, bodyshop, enableJoyRide, joyRideSteps, setJoyRideFinished }) {
|
||||
export function Manage({ conflict, bodyshop }) {
|
||||
const { t } = useTranslation();
|
||||
const [chatVisible] = useState(false);
|
||||
|
||||
@@ -583,21 +576,6 @@ export function Manage({ conflict, bodyshop, enableJoyRide, joyRideSteps, setJoy
|
||||
<UpdateAlert />
|
||||
<HeaderContainer />
|
||||
<Content className="content-container">
|
||||
<Joyride
|
||||
debug
|
||||
run={enableJoyRide}
|
||||
steps={joyRideSteps}
|
||||
continuous
|
||||
hideCloseButton
|
||||
scrollToFirstStep
|
||||
showProgress
|
||||
showSkipButton
|
||||
callback={(props) => {
|
||||
if (props.action === "reset") {
|
||||
setJoyRideFinished();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<PartnerPingComponent />
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundary />} showDialog>
|
||||
{PageContent}
|
||||
|
||||
@@ -67,11 +67,3 @@ export const setUpdateAvailable = (isUpdateAvailable) => ({
|
||||
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
|
||||
payload: isUpdateAvailable
|
||||
});
|
||||
export const setJoyRideSteps = (steps) => ({
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_STEPS,
|
||||
payload: steps
|
||||
});
|
||||
export const setJoyRideFinished = () => ({
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_FINISHED
|
||||
//payload: isUpdateAvailable,
|
||||
});
|
||||
|
||||
@@ -14,9 +14,7 @@ const INITIAL_STATE = {
|
||||
error: null
|
||||
},
|
||||
jobReadOnly: false,
|
||||
partnerVersion: null,
|
||||
enableJoyRide: false,
|
||||
joyRideSteps: []
|
||||
partnerVersion: null
|
||||
};
|
||||
|
||||
const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
@@ -89,12 +87,6 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
case ApplicationActionTypes.SET_PROBLEM_JOBS: {
|
||||
return { ...state, problemJobs: action.payload };
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_STEPS: {
|
||||
return { ...state, enableJoyRide: true, joyRideSteps: action.payload };
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_FINISHED: {
|
||||
return { ...state, enableJoyRide: false, joyRideSteps: [] };
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -22,5 +22,3 @@ export const selectJobReadOnly = createSelector([selectApplication], (applicatio
|
||||
export const selectOnline = createSelector([selectApplication], (application) => application.online);
|
||||
export const selectProblemJobs = createSelector([selectApplication], (application) => application.problemJobs);
|
||||
export const selectUpdateAvailable = createSelector([selectApplication], (application) => application.updateAvailable);
|
||||
export const selectEnableJoyRide = createSelector([selectApplication], (application) => application.enableJoyRide);
|
||||
export const selectJoyRideSteps = createSelector([selectApplication], (application) => application.joyRideSteps);
|
||||
|
||||
@@ -12,8 +12,6 @@ const ApplicationActionTypes = {
|
||||
SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
|
||||
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
|
||||
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
|
||||
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE",
|
||||
SET_JOYRIDE_STEPS: "SET_JOYRIDE_STEPS",
|
||||
SET_JOYRIDE_FINISHED: "SET_JOYRIDE_FINISHED"
|
||||
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE"
|
||||
};
|
||||
export default ApplicationActionTypes;
|
||||
|
||||
@@ -1160,7 +1160,8 @@
|
||||
"submit": "Submit",
|
||||
"tryagain": "Try Again",
|
||||
"view": "View",
|
||||
"viewreleasenotes": "See What's Changed"
|
||||
"viewreleasenotes": "See What's Changed",
|
||||
"remove_alert": "Are you sure you want to dismiss the alert?"
|
||||
},
|
||||
"errors": {
|
||||
"fcm": "You must allow notification permissions to have real time messaging. Click to try again.",
|
||||
|
||||
@@ -1160,7 +1160,8 @@
|
||||
"submit": "",
|
||||
"tryagain": "",
|
||||
"view": "",
|
||||
"viewreleasenotes": ""
|
||||
"viewreleasenotes": "",
|
||||
"remove_alert": ""
|
||||
},
|
||||
"errors": {
|
||||
"fcm": "",
|
||||
|
||||
@@ -1160,7 +1160,8 @@
|
||||
"submit": "",
|
||||
"tryagain": "",
|
||||
"view": "",
|
||||
"viewreleasenotes": ""
|
||||
"viewreleasenotes": "",
|
||||
"remove_alert": ""
|
||||
},
|
||||
"errors": {
|
||||
"fcm": "",
|
||||
|
||||
@@ -6,8 +6,6 @@ import * as url from "url";
|
||||
import { defineConfig } from "vite";
|
||||
import { ViteEjsPlugin } from "vite-plugin-ejs";
|
||||
import eslint from "vite-plugin-eslint";
|
||||
|
||||
//import CompressionPlugin from 'vite-plugin-compression';
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
import InstanceRenderManager from "./src/utils/instanceRenderMgr";
|
||||
|
||||
@@ -16,7 +14,8 @@ process.env.VITE_APP_GIT_SHA_DATE = new Date().toLocaleString("en-US", {
|
||||
});
|
||||
|
||||
const WRONG_CODE = `import { bpfrpt_proptype_WindowScroller } from "../WindowScroller.js";`;
|
||||
function reactVirtualized() {
|
||||
|
||||
function reactVirtualizedFix() {
|
||||
return {
|
||||
name: "flat:react-virtualized",
|
||||
configResolved: async () => {
|
||||
@@ -37,10 +36,7 @@ function reactVirtualized() {
|
||||
export default defineConfig({
|
||||
base: "/",
|
||||
plugins: [
|
||||
ViteEjsPlugin((viteConfig) => {
|
||||
// viteConfig is the current Vite resolved config
|
||||
return { env: viteConfig.env };
|
||||
}),
|
||||
ViteEjsPlugin((viteConfig) => ({ env: viteConfig.env })),
|
||||
VitePWA({
|
||||
injectRegister: "auto",
|
||||
registerType: "prompt",
|
||||
@@ -60,7 +56,6 @@ export default defineConfig({
|
||||
description: "The ultimate bodyshop management system.",
|
||||
icons: [
|
||||
{
|
||||
//TODO:AIO Ensure that these are correct for Rome and IO.
|
||||
src: InstanceRenderManager({
|
||||
instance: process.env.VITE_APP_INSTANCE,
|
||||
imex: "favicon.png",
|
||||
@@ -101,7 +96,7 @@ export default defineConfig({
|
||||
gcm_sender_id: "103953800507"
|
||||
}
|
||||
}),
|
||||
reactVirtualized(),
|
||||
reactVirtualizedFix(),
|
||||
react(),
|
||||
eslint()
|
||||
// CompressionPlugin(), //Cloudfront already compresses assets, so not needed.
|
||||
|
||||
613
package-lock.json
generated
613
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
@@ -19,18 +19,18 @@
|
||||
"makeitpretty": "prettier --write \"**/*.{css,js,json,jsx,scss}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-secrets-manager": "^3.616.0",
|
||||
"@aws-sdk/client-ses": "^3.616.0",
|
||||
"@aws-sdk/credential-provider-node": "^3.616.0",
|
||||
"@opensearch-project/opensearch": "^2.10.0",
|
||||
"aws4": "^1.13.0",
|
||||
"axios": "^1.7.2",
|
||||
"@aws-sdk/client-secrets-manager": "^3.629.0",
|
||||
"@aws-sdk/client-ses": "^3.629.0",
|
||||
"@aws-sdk/credential-provider-node": "^3.629.0",
|
||||
"@opensearch-project/opensearch": "^2.11.0",
|
||||
"aws4": "^1.13.1",
|
||||
"axios": "^1.7.4",
|
||||
"better-queue": "^3.8.12",
|
||||
"bluebird": "^3.7.2",
|
||||
"body-parser": "^1.20.2",
|
||||
"canvas": "^2.11.2",
|
||||
"chart.js": "^4.4.3",
|
||||
"cloudinary": "^2.3.0",
|
||||
"cloudinary": "^2.4.0",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cors": "2.8.5",
|
||||
@@ -38,24 +38,24 @@
|
||||
"dinero.js": "^1.9.1",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"firebase-admin": "^12.2.0",
|
||||
"firebase-admin": "^12.3.1",
|
||||
"graphql": "^16.9.0",
|
||||
"graphql-request": "^6.1.0",
|
||||
"graylog2": "^0.2.1",
|
||||
"inline-css": "^4.0.2",
|
||||
"intuit-oauth": "^4.1.2",
|
||||
"json-2-csv": "^5.5.4",
|
||||
"json-2-csv": "^5.5.5",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"node-mailjet": "^6.0.5",
|
||||
"node-persist": "^4.0.2",
|
||||
"node-persist": "^4.0.3",
|
||||
"nodemailer": "^6.9.14",
|
||||
"phone": "^3.1.49",
|
||||
"recursive-diff": "^1.0.9",
|
||||
"rimraf": "^6.0.1",
|
||||
"soap": "^1.1.0",
|
||||
"soap": "^1.1.1",
|
||||
"socket.io": "^4.7.5",
|
||||
"ssh2-sftp-client": "^10.0.3",
|
||||
"twilio": "^4.23.0",
|
||||
|
||||
@@ -273,7 +273,7 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
|
||||
return result && result.json && result.json.Bill;
|
||||
} catch (error) {
|
||||
logger.log("qbo-payables-error", "DEBUG", req.user.email, bill.id, {
|
||||
error: (error && error.authResponse && error.authResponse.body) || (error && error.message),
|
||||
error: error, //(error && error.authResponse && error.authResponse.body) || (error && error.message),
|
||||
method: "InsertBill"
|
||||
});
|
||||
throw error;
|
||||
|
||||
@@ -33,7 +33,7 @@ const ftpSetup = {
|
||||
exports.default = async (req, res) => {
|
||||
//Query for the List of Bodyshop Clients.
|
||||
logger.log("kaizen-start", "DEBUG", "api", null, null);
|
||||
const kaizenShopsIDs = ["SUMMIT", "STRATHMORE", "SUNRIDGE"];
|
||||
const kaizenShopsIDs = ["SUMMIT", "STRATHMORE", "SUNRIDGE", "SHAW"];
|
||||
|
||||
const { bodyshops } = await client.request(queries.GET_KAIZEN_SHOPS, {
|
||||
imexshopid: kaizenShopsIDs
|
||||
|
||||
Reference in New Issue
Block a user