Compare commits

...

23 Commits

Author SHA1 Message Date
Patrick Fic
b1cda41f56 - Remove Joyride and its cause
- Package updates (front + back)

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-08-14 11:54:52 -04:00
Dave Richer
97282740f5 Merged in release/2024-08-09-no-zoho (pull request #1596)
Release/2024 08 09 no zoho
2024-08-13 21:10:30 +00:00
Patrick Fic
150ae02978 - revert change to zoho
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-08-13 17:06:40 -04:00
Allan Carr
abeffb2a19 Merged in feature/IO-2520-Kaizen-Data-Pump (pull request #1594)
IO-2520 Add SHAW to Shop list
2024-08-13 19:29:26 +00:00
Allan Carr
70058b6bd4 IO-2520 Add SHAW to Shop list
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-08-13 12:32:14 -07:00
Allan Carr
67c63f81d9 Merge branch 'master-AIO' into feature/IO-2520-Kaizen-Data-Pump
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-08-13 12:30:42 -07:00
Allan Carr
fb8452b2bb Merged in feature/IO-2874-InsertBill-full-Error-Logging (pull request #1593)
IO-2874 InsertBill Full Error Log
2024-08-13 18:00:39 +00:00
Dave Richer
223c705e8f Merged in feature/IO-2869-Production-Board-List-Alert-2 (pull request #1587)
- mute gray more, mute more buttons
2024-08-09 17:28:44 +00:00
Dave Richer
00d8b533f4 - mute gray more, mute more buttons
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-08-09 13:28:01 -04:00
Dave Richer
3b25a8fe07 - Hotfix for rome ZOHO
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-08-09 12:40:21 -04:00
Dave Richer
a57b9cddb5 Merged in feature/IO-2869-Production-Board-List-Alert-2 (pull request #1583)
- Fix alert in table view - (modify some docs)

Approved-by: Allan Carr
2024-08-08 17:02:45 +00:00
Dave Richer
064ed1bb8b - Enhance Production Alert
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-08-08 12:16:56 -04:00
Dave Richer
efda254981 - Fix alert in table view
- (modify some docs)

Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-08-08 11:46:42 -04:00
Dave Richer
3fa6b8b6ac Merged in feature/IO-2868-Add-Tasks-To-Production-Board (pull request #1581)
- Add Tasks to production board (and required refactors)
2024-08-08 14:15:41 +00:00
Dave Richer
4603643240 Merged release/2024-08-09 into feature/IO-2868-Add-Tasks-To-Production-Board 2024-08-07 14:38:29 +00:00
Allan Carr
f82b02958f Merged in feature/IO-2866-Add-OP20-to-masterdata (pull request #1580)
IO-2866 Add OP20 to masterdata

Approved-by: Dave Richer
2024-08-07 14:36:59 +00:00
Dave Richer
5d1f61753b - Add Tasks to production board (and required refactors)
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-08-07 10:36:00 -04:00
Allan Carr
883043cde3 IO-2866 Add OP20 to masterdata
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-08-06 17:39:55 -07:00
Allan Carr
85ce7c638d Merged in feature/IO-2861-Disable-Edit-Vendor-&-Invoice-Number-on-In-House (pull request #1574)
IO-2861 Disable Editing of Vendor and Invoice Number when In House

Approved-by: Dave Richer
2024-08-06 20:26:00 +00:00
Allan Carr
fa6d4cce2a Merged in feature/IO-2864-LAET-&-LAUT-Labor-Type (pull request #1575)
IO-2864 Adjust to LAET and LAUT adjustment to target both Rome and ProManager
2024-08-06 19:22:48 +00:00
Allan Carr
c7188d5a71 Merged in feature/IO-2865-Job-Total-Labor-InstanceManager (pull request #1576)
IO-2865 Job Total Labor InstanceManger
2024-08-06 19:22:15 +00:00
Allan Carr
c333d72743 IO-2864 Adjust to LAET and LAUT adjustment to target both Rome and ProManager
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-08-06 11:54:22 -07:00
Allan Carr
2a1ec4eff3 IO-2861 Disable Editing of Vendor and Invoice Number when In House
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-08-06 09:15:37 -07:00
38 changed files with 1331 additions and 1408 deletions

View File

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

View File

@@ -1,174 +1,174 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %> <% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
<link rel="icon" href="/favicon.png" /> <link rel="icon" href="/favicon.png" />
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %> <% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
<link rel="icon" href="/ro-favicon.png" /> <link rel="icon" href="/ro-favicon.png" />
<% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %> <% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
<link rel="icon" href="/pm/pm-favicon.ico" /> <link rel="icon" href="/pm/pm-favicon.ico" />
<% } %> <% } %>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#1690ff" /> <meta name="theme-color" content="#1690ff" />
<!-- <link rel="apple-touch-icon" href="logo192.png" /> --> <!-- <link rel="apple-touch-icon" href="logo192.png" /> -->
<!-- TODO:AIo Update the individual logos for each.--> <!-- TODO:AIo Update the individual logos for each.-->
<link rel="apple-touch-icon" href="public/logo192.png" /> <link rel="apple-touch-icon" href="public/logo192.png" />
<link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF"> <link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
<!-- <!--
manifest.json provides metadata used when your web app is installed on a 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/ 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. Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build. 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. Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL. 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`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %> <% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
<meta name="description" content="ImEX Online" /> <meta name="description" content="ImEX Online" />
<title>ImEX Online</title> <title>ImEX Online</title>
<script type="text/javascript"> <script type="text/javascript">
window.$crisp = []; window.$crisp = [];
window.CRISP_WEBSITE_ID = '36724f62-2eb0-4b29-9cdd-9905fb99913e'; window.CRISP_WEBSITE_ID = '36724f62-2eb0-4b29-9cdd-9905fb99913e';
(function () { (function () {
d = document; d = document;
s = d.createElement('script'); s = d.createElement('script');
s.src = 'https://client.crisp.chat/l.js'; s.src = 'https://client.crisp.chat/l.js';
s.async = 1; s.async = 1;
d.getElementsByTagName('head')[0].appendChild(s); d.getElementsByTagName('head')[0].appendChild(s);
})(); })();
</script> </script>
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %> <% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
<meta name="description" content="Rome Online" /> <meta name="description" content="Rome Online" />
<title>Rome Online</title> <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--> <!--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 <!--<call-us
phonesystem-url=https://rometech.east.3cx.us:5001 phonesystem-url=https://rometech.east.3cx.us:5001
style="position:fixed;font-size:16px;line-height:17px;z-index: 99999;right: 20px; bottom: 20px;" style="position:fixed;font-size:16px;line-height:17px;z-index: 99999;right: 20px; bottom: 20px;"
id="wp-live-chat-by-3CX" id="wp-live-chat-by-3CX"
minimized="true" minimized="true"
animation-style="noanimation" animation-style="noanimation"
party="LiveChat528346" party="LiveChat528346"
minimized-style="bubbleright" minimized-style="bubbleright"
allow-call="true" allow-call="true"
allow-video="false" allow-video="false"
allow-soundnotifications="true" allow-soundnotifications="true"
enable-mute="true" enable-mute="true"
enable-onmobile="true" enable-onmobile="true"
offline-enabled="true" offline-enabled="true"
enable="true" enable="true"
ignore-queueownership="false" ignore-queueownership="false"
authentication="both" authentication="both"
show-operator-actual-name="true" show-operator-actual-name="true"
aknowledge-received="true" aknowledge-received="true"
gdpr-enabled="false" gdpr-enabled="false"
message-userinfo-format="name" message-userinfo-format="name"
message-dateformat="both" message-dateformat="both"
lang="browser" lang="browser"
button-icon-type="default" button-icon-type="default"
greeting-visibility="none" greeting-visibility="none"
greeting-offline-visibility="none" greeting-offline-visibility="none"
chat-delay="2000" chat-delay="2000"
enable-direct-call="true" enable-direct-call="true"
enable-ga="false" enable-ga="false"
></call-us>--> ></call-us>-->
<script defer src=https://downloads-global.3cx.com/downloads/livechatandtalk/v1/callus.js id="tcx-callus-js" charset="utf-8"></script> <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') { %> <% } %> <% if (env.VITE_APP_INSTANCE === 'PROMANAGER') { %>
<title>ProManager</title> <title>ProManager</title>
<meta name="description" content="ProManager" /> <meta name="description" content="ProManager" />
<% } %> <% } %>
<script> <script>
!(function () { !(function () {
'use strict'; 'use strict';
var e = [ var e = [
'debug', 'debug',
'destroy', 'destroy',
'do', 'do',
'help', 'help',
'identify', 'identify',
'is', 'is',
'off', 'off',
'on', 'on',
'ready', 'ready',
'render', 'render',
'reset', 'reset',
'safe', 'safe',
'set', 'set',
]; ];
if (window.noticeable) console.warn('Noticeable SDK code snippet loaded more than once'); if (window.noticeable) console.warn('Noticeable SDK code snippet loaded more than once');
else { else {
var n = (window.noticeable = window.noticeable || []); var n = (window.noticeable = window.noticeable || []);
function t(e) { function t(e) {
return function () { return function () {
var t = Array.prototype.slice.call(arguments); var t = Array.prototype.slice.call(arguments);
return t.unshift(e), n.push(t), n; 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);
})();
} }
})(); !(function () {
</script> for (var o = 0; o < e.length; o++) {
</head> var r = e[o];
<body> n[r] = t(r);
<noscript>You need to enable JavaScript to run this app.</noscript> }
<div id="root"></div> })(),
(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> <script type="module" src="src/index.jsx"></script>
</body> </body>
</html> </html>

1280
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,22 +8,22 @@
"private": true, "private": true,
"proxy": "http://localhost:4000", "proxy": "http://localhost:4000",
"dependencies": { "dependencies": {
"@ant-design/pro-layout": "^7.19.11", "@ant-design/pro-layout": "^7.19.12",
"@apollo/client": "^3.10.8", "@apollo/client": "^3.11.4",
"@emotion/is-prop-valid": "^1.3.0", "@emotion/is-prop-valid": "^1.3.0",
"@fingerprintjs/fingerprintjs": "^4.4.3", "@fingerprintjs/fingerprintjs": "^4.4.3",
"@jsreport/browser-client": "^3.1.0", "@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.2.6", "@reduxjs/toolkit": "^2.2.7",
"@sentry/cli": "^2.32.2", "@sentry/cli": "^2.33.1",
"@sentry/react": "^7.114.0", "@sentry/react": "^7.114.0",
"@splitsoftware/splitio-react": "^1.12.0", "@splitsoftware/splitio-react": "^1.12.1",
"@tanem/react-nprogress": "^5.0.51", "@tanem/react-nprogress": "^5.0.51",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"antd": "^5.19.3", "antd": "^5.20.1",
"apollo-link-logger": "^2.0.1", "apollo-link-logger": "^2.0.1",
"apollo-link-sentry": "^3.3.0", "apollo-link-sentry": "^3.3.0",
"autosize": "^6.0.1", "autosize": "^6.0.1",
"axios": "^1.6.8", "axios": "^1.7.4",
"classnames": "^2.5.1", "classnames": "^2.5.1",
"css-box-model": "^1.2.1", "css-box-model": "^1.2.1",
"dayjs": "^1.11.12", "dayjs": "^1.11.12",
@@ -32,45 +32,44 @@
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"env-cmd": "^10.1.0", "env-cmd": "^10.1.0",
"exifr": "^7.1.3", "exifr": "^7.1.3",
"firebase": "^10.12.4", "firebase": "^10.12.5",
"graphql": "^16.9.0", "graphql": "^16.9.0",
"i18next": "^23.12.2", "i18next": "^23.12.3",
"i18next-browser-languagedetector": "^8.0.0", "i18next-browser-languagedetector": "^8.0.0",
"immutability-helper": "^3.1.1", "immutability-helper": "^3.1.1",
"libphonenumber-js": "^1.11.4", "libphonenumber-js": "^1.11.5",
"logrocket": "^8.1.1", "logrocket": "^8.1.2",
"markerjs2": "^2.32.1", "markerjs2": "^2.32.1",
"memoize-one": "^6.0.0", "memoize-one": "^6.0.0",
"normalize-url": "^8.0.1", "normalize-url": "^8.0.1",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"query-string": "^9.0.0", "query-string": "^9.1.0",
"raf-schd": "^4.0.3", "raf-schd": "^4.0.3",
"react": "^18.3.1", "react": "^18.3.1",
"react-big-calendar": "^1.13.1", "react-big-calendar": "^1.13.2",
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-cookie": "^7.1.4", "react-cookie": "^7.2.0",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-drag-listview": "^2.0.0", "react-drag-listview": "^2.0.0",
"react-grid-gallery": "^1.0.1", "react-grid-gallery": "^1.0.1",
"react-grid-layout": "1.3.4", "react-grid-layout": "1.3.4",
"react-i18next": "^14.1.3", "react-i18next": "^14.1.3",
"react-icons": "^5.2.1", "react-icons": "^5.3.0",
"react-image-lightbox": "^5.1.4", "react-image-lightbox": "^5.1.4",
"react-joyride": "^2.8.2",
"react-markdown": "^9.0.1", "react-markdown": "^9.0.1",
"react-number-format": "^5.4.0", "react-number-format": "^5.4.0",
"react-popopo": "^2.1.9", "react-popopo": "^2.1.9",
"react-product-fruits": "^2.2.6", "react-product-fruits": "^2.2.6",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"react-resizable": "^3.0.5", "react-resizable": "^3.0.5",
"react-router-dom": "^6.25.1", "react-router-dom": "^6.26.0",
"react-sticky": "^6.0.3", "react-sticky": "^6.0.3",
"react-virtualized": "^9.22.5", "react-virtualized": "^9.22.5",
"react-virtuoso": "^4.7.12", "react-virtuoso": "^4.10.1",
"recharts": "^2.12.7", "recharts": "^2.12.7",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-actions": "^3.0.0", "redux-actions": "^3.0.3",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"redux-saga": "^1.3.0", "redux-saga": "^1.3.0",
"redux-state-sync": "^3.1.4", "redux-state-sync": "^3.1.4",
@@ -80,7 +79,7 @@
"styled-components": "^6.1.12", "styled-components": "^6.1.12",
"subscriptions-transport-ws": "^0.11.0", "subscriptions-transport-ws": "^0.11.0",
"use-memo-one": "^1.1.3", "use-memo-one": "^1.1.3",
"userpilot": "^1.3.2", "userpilot": "^1.3.5",
"vite-plugin-ejs": "^1.7.0", "vite-plugin-ejs": "^1.7.0",
"web-vitals": "^3.5.2" "web-vitals": "^3.5.2"
}, },
@@ -131,29 +130,29 @@
"devDependencies": { "devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-react": "^7.24.7", "@babel/preset-react": "^7.24.7",
"@dotenvx/dotenvx": "^1.6.4", "@dotenvx/dotenvx": "^1.7.0",
"@emotion/babel-plugin": "^11.12.0", "@emotion/babel-plugin": "^11.12.0",
"@emotion/react": "^11.12.0", "@emotion/react": "^11.13.0",
"@sentry/webpack-plugin": "^2.21.1", "@sentry/webpack-plugin": "^2.22.2",
"@testing-library/cypress": "^10.0.2", "@testing-library/cypress": "^10.0.2",
"browserslist": "^4.23.2", "browserslist": "^4.23.3",
"browserslist-to-esbuild": "^2.1.1", "browserslist-to-esbuild": "^2.1.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"cypress": "^13.13.1", "cypress": "^13.13.3",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-react-app": "^7.0.1", "eslint-config-react-app": "^7.0.1",
"eslint-plugin-cypress": "^2.15.1", "eslint-plugin-cypress": "^2.15.1",
"memfs": "^4.9.3", "memfs": "^4.11.1",
"os-browserify": "^0.3.0", "os-browserify": "^0.3.0",
"react-error-overlay": "6.0.11", "react-error-overlay": "6.0.11",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
"source-map-explorer": "^2.5.3", "source-map-explorer": "^2.5.3",
"vite": "^5.3.4", "vite": "^5.4.0",
"vite-plugin-babel": "^1.2.0", "vite-plugin-babel": "^1.2.0",
"vite-plugin-eslint": "^1.8.1", "vite-plugin-eslint": "^1.8.1",
"vite-plugin-legacy": "^2.1.0", "vite-plugin-legacy": "^2.1.0",
"vite-plugin-node-polyfills": "^0.22.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" "vite-plugin-style-import": "^2.0.0"
} }
} }

View File

@@ -161,3 +161,15 @@
.rowWithColor > td { .rowWithColor > td {
background-color: var(--bgColor) !important; 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;
}

View File

@@ -1,6 +1,6 @@
import { PageHeader } from "@ant-design/pro-layout";
import { useMutation, useQuery } from "@apollo/client"; import { useMutation, useQuery } from "@apollo/client";
import { Button, Divider, Form, Popconfirm, Space } from "antd"; import { Button, Divider, Form, Popconfirm, Space } from "antd";
import dayjs from "../../utils/day";
import queryString from "query-string"; import queryString from "query-string";
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -13,6 +13,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions";
import { setModalContext } from "../../redux/modals/modals.actions"; import { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings"; import AuditTrailMapping from "../../utils/AuditTrailMappings";
import dayjs from "../../utils/day";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import BillFormContainer from "../bill-form/bill-form.container"; import BillFormContainer from "../bill-form/bill-form.container";
import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component"; import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component";
@@ -22,7 +23,6 @@ import JobDocumentsGallery from "../jobs-documents-gallery/jobs-documents-galler
import JobsDocumentsLocalGallery from "../jobs-documents-local-gallery/jobs-documents-local-gallery.container"; import JobsDocumentsLocalGallery from "../jobs-documents-local-gallery/jobs-documents-local-gallery.container";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component"; import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
import BillDetailEditReturn from "./bill-detail-edit-return.component"; import BillDetailEditReturn from "./bill-detail-edit-return.component";
import { PageHeader } from "@ant-design/pro-layout";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop bodyshop: selectBodyshop
@@ -153,6 +153,7 @@ export function BillDetailEditcontainer({ setPartsOrderContext, insertAuditTrail
if (!search.billid) return <></>; //<div>{t("bills.labels.noneselected")}</div>; if (!search.billid) return <></>; //<div>{t("bills.labels.noneselected")}</div>;
const exported = data && data.bills_by_pk && data.bills_by_pk.exported; const exported = data && data.bills_by_pk && data.bills_by_pk.exported;
const isinhouse = data && data.bills_by_pk && data.bills_by_pk.isinhouse;
return ( return (
<> <>
@@ -188,7 +189,7 @@ export function BillDetailEditcontainer({ setPartsOrderContext, insertAuditTrail
} }
/> />
<Form form={form} onFinish={handleFinish} initialValues={transformData(data)} layout="vertical"> <Form form={form} onFinish={handleFinish} initialValues={transformData(data)} layout="vertical">
<BillFormContainer form={form} billEdit disabled={exported} /> <BillFormContainer form={form} billEdit disabled={exported} disableInHouse={isinhouse} />
<Divider orientation="left">{t("general.labels.media")}</Divider> <Divider orientation="left">{t("general.labels.media")}</Divider>
{bodyshop.uselocalmediaserver ? ( {bodyshop.uselocalmediaserver ? (
<JobsDocumentsLocalGallery <JobsDocumentsLocalGallery

View File

@@ -41,7 +41,8 @@ export function BillFormComponent({
job, job,
loadOutstandingReturns, loadOutstandingReturns,
loadInventory, loadInventory,
preferredMake preferredMake,
disableInHouse
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const client = useApolloClient(); const client = useApolloClient();
@@ -177,7 +178,7 @@ export function BillFormComponent({
]} ]}
> >
<VendorSearchSelect <VendorSearchSelect
disabled={disabled} disabled={disabled || disableInHouse}
options={vendorAutoCompleteOptions} options={vendorAutoCompleteOptions}
preferredMake={preferredMake} preferredMake={preferredMake}
onSelect={handleVendorSelect} onSelect={handleVendorSelect}
@@ -243,7 +244,7 @@ export function BillFormComponent({
}) })
]} ]}
> >
<Input disabled={disabled || disableInvNumber} /> <Input disabled={disabled || disableInvNumber || disableInHouse} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("bills.fields.date")} label={t("bills.fields.date")}

View File

@@ -16,7 +16,7 @@ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop bodyshop: selectBodyshop
}); });
export function BillFormContainer({ bodyshop, form, billEdit, disabled, disableInvNumber }) { export function BillFormContainer({ bodyshop, form, billEdit, disabled, disableInvNumber, disableInHouse }) {
const { const {
treatments: { Simple_Inventory } treatments: { Simple_Inventory }
} = useSplitTreatments({ } = useSplitTreatments({
@@ -47,6 +47,7 @@ export function BillFormContainer({ bodyshop, form, billEdit, disabled, disableI
job={lineData ? lineData.jobs_by_pk : null} job={lineData ? lineData.jobs_by_pk : null}
responsibilityCenters={bodyshop.md_responsibility_centers || null} responsibilityCenters={bodyshop.md_responsibility_centers || null}
disableInvNumber={disableInvNumber} disableInvNumber={disableInvNumber}
disableInHouse={disableInHouse}
loadOutstandingReturns={loadOutstandingReturns} loadOutstandingReturns={loadOutstandingReturns}
loadInventory={loadInventory} loadInventory={loadInventory}
preferredMake={lineData ? lineData.jobs_by_pk.v_make_desc : null} preferredMake={lineData ? lineData.jobs_by_pk.v_make_desc : null}

View File

@@ -36,9 +36,6 @@ export default function DashboardScheduledOutToday({ data, ...cardProps }) {
}; };
}); });
console.log("Scheduled Out Today");
console.dir(scheduledOutToday);
const tvFontSize = 18; const tvFontSize = 18;
const tvFontWeight = "bold"; const tvFontWeight = "bold";

View File

@@ -3,7 +3,6 @@ import { useSplitTreatments } from "@splitsoftware/splitio-react";
import { Col, Row, notification } from "antd"; import { Col, Row, notification } from "antd";
import Axios from "axios"; import Axios from "axios";
import _ from "lodash"; import _ from "lodash";
import dayjs from "../../utils/day";
import queryString from "query-string"; import queryString from "query-string";
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -24,6 +23,8 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto
import AuditTrailMapping from "../../utils/AuditTrailMappings"; import AuditTrailMapping from "../../utils/AuditTrailMappings";
import confirmDialog from "../../utils/asyncConfirm"; import confirmDialog from "../../utils/asyncConfirm";
import CriticalPartsScan from "../../utils/criticalPartsScan"; import CriticalPartsScan from "../../utils/criticalPartsScan";
import dayjs from "../../utils/day";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component"; import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
import JobsFindModalContainer from "../jobs-find-modal/jobs-find-modal.container"; import JobsFindModalContainer from "../jobs-find-modal/jobs-find-modal.container";
@@ -32,7 +33,6 @@ import OwnerFindModalContainer from "../owner-find-modal/owner-find-modal.contai
import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util"; import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util";
import HeaderFields from "./jobs-available-supplement.headerfields"; import HeaderFields from "./jobs-available-supplement.headerfields";
import JobsAvailableTableComponent from "./jobs-available-table.component"; import JobsAvailableTableComponent from "./jobs-available-table.component";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
@@ -580,12 +580,13 @@ function ResolveCCCLineIssues(estData, bodyshop) {
InstanceRenderManager({ InstanceRenderManager({
executeFunction: true, executeFunction: true,
args: [], args: [],
promanager: () => { rome: () => {
if (line.mod_lbr_ty === "LAET" || line.mod_lbr_ty === "LAUT") { if (line.mod_lbr_ty === "LAET" || line.mod_lbr_ty === "LAUT") {
// line.notes += ` | ET/UT Update (prev = ${line.mod_lbr_ty})`; // line.notes += ` | ET/UT Update (prev = ${line.mod_lbr_ty})`;
line.mod_lbr_ty = "LAR"; line.mod_lbr_ty = "LAR";
} }
} },
promanager: "USE_ROME"
}); });
}); });

View File

@@ -16,18 +16,15 @@ import useLocalStorage from "../../utils/useLocalStorage";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import ChatOpenButton from "../chat-open-button/chat-open-button.component"; import ChatOpenButton from "../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.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"; import { OwnerNameDisplayFunction } from "./../owner-name-display/owner-name-display.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop bodyshop: selectBodyshop
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({});
setJoyRideSteps: (steps) => dispatch(setJoyRideSteps(steps))
});
export function JobsList({ bodyshop, setJoyRideSteps }) { export function JobsList({ bodyshop }) {
const searchParams = queryString.parse(useLocation().search); const searchParams = queryString.parse(useLocation().search);
const { selected } = searchParams; const { selected } = searchParams;
const selectedBreakpoint = Object.entries(Grid.useBreakpoint()) const selectedBreakpoint = Object.entries(Grid.useBreakpoint())

View File

@@ -290,6 +290,22 @@ const PartsStatusComponent = ({ metadata, cardSettings }) =>
</Col> </Col>
); );
const TasksToolTip = ({ metadata, cardSettings, t }) =>
cardSettings?.tasks && (
<Col span={12}>
<EllipsesToolTip
title={`${t("production.labels.tasks")}: ${metadata.tasks_aggregate?.aggregate?.count || 0}`}
kiosk={cardSettings.kiosk}
>
{metadata.tasks_aggregate?.aggregate?.count ? (
`T: ${metadata.tasks_aggregate.aggregate.count}`
) : (
<span>T: 0</span>
)}
</EllipsesToolTip>
</Col>
);
export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings, clone }) { export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings, clone }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { metadata } = card; const { metadata } = card;
@@ -336,21 +352,15 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe
cardSettings?.production_note || cardSettings?.production_note ||
cardSettings?.partsstatus || cardSettings?.partsstatus ||
cardSettings?.estimator || cardSettings?.estimator ||
cardSettings?.subtotal cardSettings?.subtotal ||
cardSettings?.tasks
); );
}, [cardSettings]); }, [cardSettings]);
const headerContent = ( const headerContent = (
<div className="header-content-container"> <div className="header-content-container">
<div className="inner-container"> <div className="inner-container">
<ProductionAlert <ProductionAlert id={card.id} productionVars={metadata?.production_vars} refetch={card?.refetch} key="alert" />
record={{
id: card.id,
production_vars: card?.metadata.production_vars,
refetch: card?.refetch
}}
key="alert"
/>
{metadata?.suspended && <PauseCircleOutlined className="circle-outline" key="suspended" />} {metadata?.suspended && <PauseCircleOutlined className="circle-outline" key="suspended" />}
{metadata?.iouparent && ( {metadata?.iouparent && (
<EllipsesToolTip <EllipsesToolTip
@@ -393,6 +403,7 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe
employee_csr={employee_csr} employee_csr={employee_csr}
/> />
<EstimatorToolTip metadata={metadata} cardSettings={cardSettings} /> <EstimatorToolTip metadata={metadata} cardSettings={cardSettings} />
<TasksToolTip metadata={metadata} cardSettings={cardSettings} t={t} />
<SubtotalTooltip metadata={metadata} cardSettings={cardSettings} t={t} /> <SubtotalTooltip metadata={metadata} cardSettings={cardSettings} t={t} />
<ActualInToolTip metadata={metadata} cardSettings={cardSettings} /> <ActualInToolTip metadata={metadata} cardSettings={cardSettings} />
<ScheduledCompletionToolTip metadata={metadata} cardSettings={cardSettings} pastDueAlert={pastDueAlert} /> <ScheduledCompletionToolTip metadata={metadata} cardSettings={cardSettings} pastDueAlert={pastDueAlert} />

View File

@@ -15,13 +15,13 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings";
import IndefiniteLoading from "../indefinite-loading/indefinite-loading.component"; import IndefiniteLoading from "../indefinite-loading/indefinite-loading.component";
import ProductionBoardFilters from "../production-board-filters/production-board-filters.component"; import ProductionBoardFilters from "../production-board-filters/production-board-filters.component";
import ProductionListDetailComponent from "../production-list-detail/production-list-detail.component"; import ProductionListDetailComponent from "../production-list-detail/production-list-detail.component";
import CardColorLegend from "../production-board-kanban-card/production-board-kanban-card-color-legend.component"; import CardColorLegend from "./production-board-kanban-card-color-legend.component.jsx";
import "./production-board-kanban.styles.scss"; import "./production-board-kanban.styles.scss";
import { createBoardData } from "./production-board-kanban.utils.js"; import { createBoardData } from "./production-board-kanban.utils.js";
import ProductionBoardKanbanSettings from "./settings/production-board-kanban.settings.component.jsx"; import ProductionBoardKanbanSettings from "./settings/production-board-kanban.settings.component.jsx";
import cloneDeep from "lodash/cloneDeep"; import cloneDeep from "lodash/cloneDeep";
import isEqual from "lodash/isEqual"; import isEqual from "lodash/isEqual";
import { defaultKanbanSettings } from "./settings/defaultKanbanSettings.js"; import { mergeWithDefaults } from "./settings/defaultKanbanSettings.js";
import NoteUpsertModal from "../../components/note-upsert-modal/note-upsert-modal.container"; import NoteUpsertModal from "../../components/note-upsert-modal/note-upsert-modal.container";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
@@ -182,13 +182,10 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
[boardLanes, client, getCardByID, isMoving, t, insertAuditTrail] [boardLanes, client, getCardByID, isMoving, t, insertAuditTrail]
); );
const cardSettings = useMemo( const cardSettings = useMemo(() => {
() => const kanbanSettings = associationSettings?.kanban_settings;
associationSettings?.kanban_settings && Object.keys(associationSettings.kanban_settings).length > 0 return mergeWithDefaults(kanbanSettings);
? associationSettings.kanban_settings }, [associationSettings]);
: defaultKanbanSettings,
[associationSettings]
);
const handleSettingsChange = useCallback((newSettings) => { const handleSettingsChange = useCallback((newSettings) => {
setLoading(true); setLoading(true);

View File

@@ -2,11 +2,13 @@ import React, { useMemo } from "react";
import { Card, Statistic } from "antd"; import { Card, Statistic } from "antd";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { statisticsItems, defaultKanbanSettings } from "./settings/defaultKanbanSettings.js"; import { defaultKanbanSettings, statisticsItems } from "./settings/defaultKanbanSettings.js";
export const StatisticType = { export const StatisticType = {
HOURS: "hours", HOURS: "hours",
AMOUNT: "amount", AMOUNT: "amount",
JOBS: "jobs" JOBS: "jobs",
TASKS: "tasks"
}; };
const mergeStatistics = (items, values) => { const mergeStatistics = (items, values) => {
@@ -122,6 +124,20 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
return parseFloat(total.toFixed(2)); return parseFloat(total.toFixed(2));
}, [reducerData, cardSettings.totalAmountOnBoard]); }, [reducerData, cardSettings.totalAmountOnBoard]);
const tasksInProduction = useMemo(() => {
if (!data || !cardSettings.tasksInProduction) return null;
return data.reduce((acc, item) => acc + (item.tasks_aggregate?.aggregate?.count || 0), 0);
}, [data, cardSettings.tasksInProduction]);
const tasksOnBoard = useMemo(() => {
if (!reducerData || !cardSettings.tasksOnBoard) return null;
return reducerData.lanes.reduce((acc, lane) => {
return (
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata.tasks_aggregate?.aggregate?.count || 0), 0)
);
}, 0);
}, [reducerData, cardSettings.tasksOnBoard]);
const statistics = useMemo( const statistics = useMemo(
() => () =>
mergeStatistics(statisticsItems, [ mergeStatistics(statisticsItems, [
@@ -134,7 +150,9 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
{ id: 6, value: totalAmountOnBoard, type: StatisticType.AMOUNT }, { id: 6, value: totalAmountOnBoard, type: StatisticType.AMOUNT },
{ id: 7, value: totalLABOnBoard, type: StatisticType.HOURS }, { id: 7, value: totalLABOnBoard, type: StatisticType.HOURS },
{ id: 8, value: totalLAROnBoard, type: StatisticType.HOURS }, { id: 8, value: totalLAROnBoard, type: StatisticType.HOURS },
{ id: 9, value: jobsOnBoard, type: StatisticType.JOBS } { id: 9, value: jobsOnBoard, type: StatisticType.JOBS },
{ id: 10, value: tasksOnBoard, type: StatisticType.TASKS },
{ id: 11, value: tasksInProduction, type: StatisticType.TASKS }
]), ]),
[ [
totalHrs, totalHrs,
@@ -146,7 +164,9 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
totalAmountOnBoard, totalAmountOnBoard,
totalLABOnBoard, totalLABOnBoard,
totalLAROnBoard, totalLAROnBoard,
jobsOnBoard jobsOnBoard,
tasksOnBoard,
tasksInProduction
] ]
); );
@@ -187,37 +207,9 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
}; };
ProductionStatistics.propTypes = { ProductionStatistics.propTypes = {
data: PropTypes.arrayOf( data: PropTypes.array.isRequired,
PropTypes.shape({ cardSettings: PropTypes.object.isRequired,
labhrs: PropTypes.object, reducerData: PropTypes.object
larhrs: PropTypes.object,
job_totals: PropTypes.object
})
).isRequired,
cardSettings: PropTypes.shape({
totalHrs: PropTypes.bool,
totalLAB: PropTypes.bool,
totalLAR: PropTypes.bool,
jobsInProduction: PropTypes.bool,
totalAmountInProduction: PropTypes.bool,
totalHrsOnBoard: PropTypes.bool,
totalLABOnBoard: PropTypes.bool,
totalLAROnBoard: PropTypes.bool,
jobsOnBoard: PropTypes.bool,
totalAmountOnBoard: PropTypes.bool,
statisticsOrder: PropTypes.arrayOf(PropTypes.number)
}).isRequired,
reducerData: PropTypes.shape({
lanes: PropTypes.arrayOf(
PropTypes.shape({
cards: PropTypes.arrayOf(
PropTypes.shape({
metadata: PropTypes.object
})
).isRequired
})
).isRequired
})
}; };
export default ProductionStatistics; export default ProductionStatistics;

View File

@@ -18,7 +18,8 @@ const InformationSettings = ({ t }) => (
"sublets", "sublets",
"partsstatus", "partsstatus",
"estimator", "estimator",
"subtotal" "subtotal",
"tasks"
].map((item) => ( ].map((item) => (
<Col span={4} key={item}> <Col span={4} key={item}>
<Form.Item name={item} valuePropName="checked"> <Form.Item name={item} valuePropName="checked">

View File

@@ -8,7 +8,9 @@ const statisticsItems = [
{ id: 6, name: "totalAmountOnBoard", label: "total_amount_on_board" }, { id: 6, name: "totalAmountOnBoard", label: "total_amount_on_board" },
{ id: 7, name: "totalLABOnBoard", label: "total_lab_on_board" }, { id: 7, name: "totalLABOnBoard", label: "total_lab_on_board" },
{ id: 8, name: "totalLAROnBoard", label: "total_lar_on_board" }, { id: 8, name: "totalLAROnBoard", label: "total_lar_on_board" },
{ id: 9, name: "jobsOnBoard", label: "total_jobs_on_board" } { id: 9, name: "jobsOnBoard", label: "total_jobs_on_board" },
{ id: 10, name: "tasksOnBoard", label: "tasks_on_board" },
{ id: 11, name: "tasksInProduction", label: "tasks_in_production" }
]; ];
const defaultKanbanSettings = { const defaultKanbanSettings = {
@@ -23,6 +25,7 @@ const defaultKanbanSettings = {
scheduled_completion: true, scheduled_completion: true,
cardcolor: false, cardcolor: false,
orientation: false, orientation: false,
tasks: false,
cardSize: "small", cardSize: "small",
model_info: true, model_info: true,
kiosk: false, kiosk: false,
@@ -35,6 +38,8 @@ const defaultKanbanSettings = {
totalLABOnBoard: false, totalLABOnBoard: false,
totalLAROnBoard: false, totalLAROnBoard: false,
jobsOnBoard: false, jobsOnBoard: false,
tasksOnBoard: false,
tasksInProduction: false,
totalAmountOnBoard: true, totalAmountOnBoard: true,
estimator: false, estimator: false,
subtotal: false, subtotal: false,
@@ -43,4 +48,20 @@ const defaultKanbanSettings = {
selectedEstimators: [] selectedEstimators: []
}; };
export { defaultKanbanSettings, statisticsItems }; const mergeWithDefaults = (settings) => {
// Create a new object that starts with the default settings
const mergedSettings = { ...defaultKanbanSettings };
// Override with the provided settings, if any
if (settings) {
for (const key in settings) {
if (settings.hasOwnProperty(key)) {
mergedSettings[key] = settings[key];
}
}
}
return mergedSettings;
};
export { defaultKanbanSettings, statisticsItems, mergeWithDefaults };

View File

@@ -3,13 +3,14 @@ import { Button, Card, Col, Form, notification, Popover, Row, Tabs } from "antd"
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { UPDATE_KANBAN_SETTINGS } from "../../../graphql/user.queries.js"; import { UPDATE_KANBAN_SETTINGS } from "../../../graphql/user.queries.js";
import { defaultKanbanSettings } from "./defaultKanbanSettings.js"; import { defaultKanbanSettings, mergeWithDefaults } from "./defaultKanbanSettings.js";
import LayoutSettings from "./LayoutSettings.jsx"; import LayoutSettings from "./LayoutSettings.jsx";
import InformationSettings from "./InformationSettings.jsx"; import InformationSettings from "./InformationSettings.jsx";
import StatisticsSettings from "./StatisticsSettings.jsx"; import StatisticsSettings from "./StatisticsSettings.jsx";
import FilterSettings from "./FilterSettings.jsx"; import FilterSettings from "./FilterSettings.jsx";
import PropTypes from "prop-types";
export default function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bodyshop, data }) { function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bodyshop, data }) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@@ -23,16 +24,11 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
useEffect(() => { useEffect(() => {
if (associationSettings?.kanban_settings) { if (associationSettings?.kanban_settings) {
form.setFieldsValue(associationSettings.kanban_settings); const finalSettings = mergeWithDefaults(associationSettings.kanban_settings);
if (associationSettings.kanban_settings.statisticsOrder) { form.setFieldsValue(finalSettings);
setStatisticsOrder(associationSettings.kanban_settings.statisticsOrder); setStatisticsOrder(finalSettings.statisticsOrder);
} setSelectedMdInsCos(finalSettings.selectedMdInsCos);
if (associationSettings.kanban_settings.selectedMdInsCos) { setSelectedEstimators(finalSettings.selectedEstimators);
setSelectedMdInsCos(associationSettings.kanban_settings.selectedMdInsCos);
}
if (associationSettings.kanban_settings.selectedEstimators) {
setSelectedEstimators(associationSettings.kanban_settings.selectedEstimators);
}
} }
}, [form, associationSettings]); }, [form, associationSettings]);
@@ -155,3 +151,12 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
</Popover> </Popover>
); );
} }
ProductionBoardKanbanSettings.propTypes = {
associationSettings: PropTypes.object,
parentLoading: PropTypes.func.isRequired,
bodyshop: PropTypes.object.isRequired,
data: PropTypes.array
};
export default ProductionBoardKanbanSettings;

View File

@@ -12,7 +12,7 @@ import { EyeInvisibleOutlined, EyeOutlined } from "@ant-design/icons";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../../../redux/user/user.selectors.js"; import { selectBodyshop } from "../../../../redux/user/user.selectors.js";
import { selectTechnician } from "../../../../redux/tech/tech.selectors.js"; import { selectTechnician } from "../../../../redux/tech/tech.selectors.js";
import ProductionBoardCard from "../../../production-board-kanban-card/production-board-kanban-card.component.jsx"; import ProductionBoardCard from "../../production-board-kanban-card.component.jsx";
import HeightMemoryWrapper from "../components/HeightMemoryWrapper.jsx"; import HeightMemoryWrapper from "../components/HeightMemoryWrapper.jsx";
import SizeMemoryWrapper from "../components/SizeMemoryWrapper.jsx"; import SizeMemoryWrapper from "../components/SizeMemoryWrapper.jsx";
import ListComponent from "../components/ListComponent.jsx"; import ListComponent from "../components/ListComponent.jsx";

View File

@@ -1,6 +1,6 @@
import { ExclamationCircleFilled } from "@ant-design/icons"; import { ExclamationCircleFilled, PlusCircleFilled } from "@ant-design/icons";
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import { Button } from "antd"; import { Button, Popconfirm } from "antd";
import React, { useCallback } from "react"; import React, { useCallback } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
@@ -8,6 +8,7 @@ import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { insertAuditTrail } from "../../redux/application/application.actions"; import { insertAuditTrail } from "../../redux/application/application.actions";
import AuditTrailMapping from "../../utils/AuditTrailMappings"; import AuditTrailMapping from "../../utils/AuditTrailMappings";
import { useTranslation } from "react-i18next";
const mapStateToProps = createStructuredSelector({}); 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 [updateAlert] = useMutation(UPDATE_JOB);
const { t } = useTranslation();
const handleAlertToggle = useCallback(() => { const handleAlertToggle = useCallback(() => {
logImEXEvent("production_toggle_alert"); 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({ updateAlert({
variables: { variables: {
jobId: record.id, jobId: id,
job: { job: {
production_vars: { production_vars: finalProductionVars
...record.production_vars,
alert: newAlertState
}
} }
} }
}).catch((err) => { }).catch((err) => {
@@ -45,17 +48,26 @@ const ProductionListColumnAlert = ({ record, insertAuditTrail }) => {
}); });
insertAuditTrail({ insertAuditTrail({
jobid: record.id, jobid: id,
operation: AuditTrailMapping.alertToggle(newAlertState), operation: AuditTrailMapping.alertToggle(newAlertState),
type: "alertToggle" type: "alertToggle"
}); });
if (record.refetch) record.refetch(); if (refetch) refetch();
}, [updateAlert, insertAuditTrail, record]); }, [updateAlert, insertAuditTrail, id, productionVars, refetch]);
if (!record.production_vars?.alert) return null; return productionVars?.alert ? (
<Popconfirm
return <Button className="production-alert" icon={<ExclamationCircleFilled />} onClick={handleAlertToggle} />; 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); export default connect(mapStateToProps, mapDispatchToProps)(ProductionListColumnAlert);

View File

@@ -23,7 +23,7 @@ import ProductionListColumnPartsReceived from "./production-list-columns.partsre
import ProductionListColumnNote from "./production-list-columns.productionnote.component"; import ProductionListColumnNote from "./production-list-columns.productionnote.component";
import ProductionListColumnCategory from "./production-list-columns.status.category"; import ProductionListColumnCategory from "./production-list-columns.status.category";
import ProductionListColumnStatus from "./production-list-columns.status.component"; 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 { store } from "../../redux/store";
import { setModalContext } from "../../redux/modals/modals.actions"; import { setModalContext } from "../../redux/modals/modals.actions";
import InstanceRenderManager from "../../utils/instanceRenderMgr"; import InstanceRenderManager from "../../utils/instanceRenderMgr";
@@ -349,7 +349,9 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
key: "alert", key: "alert",
sorter: (a, b) => Number(a.production_vars?.alert || false) - Number(b.production_vars?.alert || false), sorter: (a, b) => Number(a.production_vars?.alert || false) - Number(b.production_vars?.alert || false),
sortOrder: state.sortedInfo.columnKey === "alert" && state.sortedInfo.order, 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"), title: i18n.t("production.labels.note"),
@@ -370,7 +372,7 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
dataIndex: "tt", dataIndex: "tt",
key: "tt", key: "tt",
render: (text, record) => { render: (text, record) => {
return <ProductionlistColumnTouchTime job={record} />; return <ProductionListColumnTouchTime job={record} />;
} }
}, },
{ {

View File

@@ -148,6 +148,7 @@ export function ProductionListEmpAssignment({ insertAuditTrail, bodyshop, record
) : ( ) : (
<PlusCircleFilled <PlusCircleFilled
style={iconStyle} style={iconStyle}
className="muted-button"
onClick={() => { onClick={() => {
setAssignment({ operation: type }); setAssignment({ operation: type });
setVisibility(true); setVisibility(true);

View File

@@ -1,7 +1,7 @@
import { AlertOutlined } from "@ant-design/icons"; import { AlertOutlined } from "@ant-design/icons";
import { Alert, Button, Col, Row, Space } from "antd"; import { Alert, Button, Col, Row, Space } from "antd";
import i18n from "i18next"; import i18n from "i18next";
import React from "react"; import React, { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
@@ -12,39 +12,42 @@ import InstanceRenderManager from "../../utils/instanceRenderMgr";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
updateAvailable: selectUpdateAvailable updateAvailable: selectUpdateAvailable
}); });
const mapDispatchToProps = (dispatch) => ({ 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 }) { export function UpdateAlert({ updateAvailable }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { const {
offlineReady: [ offlineReady: [offlineReady],
offlineReady //setOfflineReady needRefresh: [needRefresh],
],
needRefresh: [
needRefresh //setNeedRefresh
],
updateServiceWorker updateServiceWorker
} = useRegisterSW({ } = useRegisterSW({
onRegistered(r) { onRegistered(r) {
// eslint-disable-next-line prefer-template console.log("SW Registered:", r);
console.log("SW Registered: " + r); if (r) {
r && setInterval(
setInterval(() => { () => {
r.update(); r.update();
}, intervalMS); },
10 * 60 * 1000
);
}
}, },
onRegisterError(error) { 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; if (!needRefresh) return null;
return ( return (
<Alert <Alert
message={t("general.messages.newversiontitle", { message={t("general.messages.newversiontitle", {
@@ -69,19 +72,10 @@ export function UpdateAlert({ updateAvailable }) {
</Col> </Col>
<Col sm={24} md={8} lg={6}> <Col sm={24} md={8} lg={6}>
<Space wrap> <Space wrap>
<Button <Button onClick={() => window.open("https://imex-online.noticeable.news/", "_blank")}>
onClick={async () => {
window.open("https://imex-online.noticeable.news/", "_blank");
}}
>
{i18n.t("general.actions.viewreleasenotes")} {i18n.t("general.actions.viewreleasenotes")}
</Button> </Button>
<Button <Button type="primary" onClick={() => updateServiceWorker(true)}>
type="primary"
onClick={async () => {
updateServiceWorker(true);
}}
>
{i18n.t("general.actions.refresh")} {i18n.t("general.actions.refresh")}
</Button> </Button>
</Space> </Space>
@@ -93,3 +87,5 @@ export function UpdateAlert({ updateAvailable }) {
/> />
); );
} }
export default connect(mapStateToProps, mapDispatchToProps)(UpdateAlert);

View File

@@ -2465,6 +2465,11 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
export const QUERY_JOBS_IN_PRODUCTION = gql` export const QUERY_JOBS_IN_PRODUCTION = gql`
query QUERY_JOBS_IN_PRODUCTION { query QUERY_JOBS_IN_PRODUCTION {
jobs(where: { inproduction: { _eq: true } }) { jobs(where: { inproduction: { _eq: true } }) {
tasks_aggregate(where: { completed: { _eq: false }, deleted: { _eq: false } }) {
aggregate {
count
}
}
id id
updated_at updated_at
comment comment

View File

@@ -12,7 +12,6 @@ import ErrorBoundary from "../../components/error-boundary/error-boundary.compon
//import FooterComponent from "../../components/footer/footer.component"; //import FooterComponent from "../../components/footer/footer.component";
//Component Imports //Component Imports
import * as Sentry from "@sentry/react"; import * as Sentry from "@sentry/react";
import Joyride from "react-joyride";
import TestComponent from "../../components/_test/test.page"; import TestComponent from "../../components/_test/test.page";
import HeaderContainer from "../../components/header/header.container"; import HeaderContainer from "../../components/header/header.container";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; 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 { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors";
import UpdateAlert from "../../components/update-alert/update-alert.component"; 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 InstanceRenderManager from "../../utils/instanceRenderMgr.js";
import "./manage.page.styles.scss"; import "./manage.page.styles.scss";
@@ -105,16 +102,12 @@ const { Content, Footer } = Layout;
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
conflict: selectInstanceConflict, conflict: selectInstanceConflict,
bodyshop: selectBodyshop, bodyshop: selectBodyshop
enableJoyRide: selectEnableJoyRide,
joyRideSteps: selectJoyRideSteps
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({});
setJoyRideFinished: (steps) => dispatch(setJoyRideFinished(steps))
});
export function Manage({ conflict, bodyshop, enableJoyRide, joyRideSteps, setJoyRideFinished }) { export function Manage({ conflict, bodyshop }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [chatVisible] = useState(false); const [chatVisible] = useState(false);
@@ -583,21 +576,6 @@ export function Manage({ conflict, bodyshop, enableJoyRide, joyRideSteps, setJoy
<UpdateAlert /> <UpdateAlert />
<HeaderContainer /> <HeaderContainer />
<Content className="content-container"> <Content className="content-container">
<Joyride
debug
run={enableJoyRide}
steps={joyRideSteps}
continuous
hideCloseButton
scrollToFirstStep
showProgress
showSkipButton
callback={(props) => {
if (props.action === "reset") {
setJoyRideFinished();
}
}}
/>
<PartnerPingComponent /> <PartnerPingComponent />
<Sentry.ErrorBoundary fallback={<ErrorBoundary />} showDialog> <Sentry.ErrorBoundary fallback={<ErrorBoundary />} showDialog>
{PageContent} {PageContent}

View File

@@ -67,11 +67,3 @@ export const setUpdateAvailable = (isUpdateAvailable) => ({
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE, type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
payload: isUpdateAvailable payload: isUpdateAvailable
}); });
export const setJoyRideSteps = (steps) => ({
type: ApplicationActionTypes.SET_JOYRIDE_STEPS,
payload: steps
});
export const setJoyRideFinished = () => ({
type: ApplicationActionTypes.SET_JOYRIDE_FINISHED
//payload: isUpdateAvailable,
});

View File

@@ -14,9 +14,7 @@ const INITIAL_STATE = {
error: null error: null
}, },
jobReadOnly: false, jobReadOnly: false,
partnerVersion: null, partnerVersion: null
enableJoyRide: false,
joyRideSteps: []
}; };
const applicationReducer = (state = INITIAL_STATE, action) => { const applicationReducer = (state = INITIAL_STATE, action) => {
@@ -89,12 +87,6 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
case ApplicationActionTypes.SET_PROBLEM_JOBS: { case ApplicationActionTypes.SET_PROBLEM_JOBS: {
return { ...state, problemJobs: action.payload }; 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: default:
return state; return state;
} }

View File

@@ -22,5 +22,3 @@ export const selectJobReadOnly = createSelector([selectApplication], (applicatio
export const selectOnline = createSelector([selectApplication], (application) => application.online); export const selectOnline = createSelector([selectApplication], (application) => application.online);
export const selectProblemJobs = createSelector([selectApplication], (application) => application.problemJobs); export const selectProblemJobs = createSelector([selectApplication], (application) => application.problemJobs);
export const selectUpdateAvailable = createSelector([selectApplication], (application) => application.updateAvailable); export const selectUpdateAvailable = createSelector([selectApplication], (application) => application.updateAvailable);
export const selectEnableJoyRide = createSelector([selectApplication], (application) => application.enableJoyRide);
export const selectJoyRideSteps = createSelector([selectApplication], (application) => application.joyRideSteps);

View File

@@ -12,8 +12,6 @@ const ApplicationActionTypes = {
SET_ONLINE_STATUS: "SET_ONLINE_STATUS", SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL", INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS", SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE", SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE"
SET_JOYRIDE_STEPS: "SET_JOYRIDE_STEPS",
SET_JOYRIDE_FINISHED: "SET_JOYRIDE_FINISHED"
}; };
export default ApplicationActionTypes; export default ApplicationActionTypes;

View File

@@ -1160,7 +1160,8 @@
"submit": "Submit", "submit": "Submit",
"tryagain": "Try Again", "tryagain": "Try Again",
"view": "View", "view": "View",
"viewreleasenotes": "See What's Changed" "viewreleasenotes": "See What's Changed",
"remove_alert": "Are you sure you want to dismiss the alert?"
}, },
"errors": { "errors": {
"fcm": "You must allow notification permissions to have real time messaging. Click to try again.", "fcm": "You must allow notification permissions to have real time messaging. Click to try again.",
@@ -2757,7 +2758,9 @@
"total_lab_on_board": "Body Hours on Board", "total_lab_on_board": "Body Hours on Board",
"total_lar_on_board": "Refinish Hours on Board", "total_lar_on_board": "Refinish Hours on Board",
"total_amount_on_board": "Dollars on Board", "total_amount_on_board": "Dollars on Board",
"total_jobs_on_board": "Jobs on Board" "total_jobs_on_board": "Jobs on Board",
"tasks_in_production": "Tasks in Production",
"tasks_on_board": "Tasks on Board"
} }
}, },
"actions": { "actions": {
@@ -2792,6 +2795,7 @@
"model_info": "Vehicle Info", "model_info": "Vehicle Info",
"actual_in": "Actual In", "actual_in": "Actual In",
"alert": "Alert", "alert": "Alert",
"tasks": "Tasks",
"alertoff": "Remove alert from Job", "alertoff": "Remove alert from Job",
"alerton": "Add alert to Job", "alerton": "Add alert to Job",
"ats": "Alternative Transportation", "ats": "Alternative Transportation",
@@ -2845,6 +2849,9 @@
"total_lar_on_board": "Refinish Hours on Board", "total_lar_on_board": "Refinish Hours on Board",
"total_amount_on_board": "Dollars on Board", "total_amount_on_board": "Dollars on Board",
"total_jobs_on_board": "Jobs on Board", "total_jobs_on_board": "Jobs on Board",
"tasks_in_production": "Tasks in Production",
"tasks_on_board": "Tasks on Board",
"tasks": "Tasks",
"hours": "Hours", "hours": "Hours",
"currency_symbol": "$", "currency_symbol": "$",
"jobs": "Jobs" "jobs": "Jobs"

View File

@@ -1160,7 +1160,8 @@
"submit": "", "submit": "",
"tryagain": "", "tryagain": "",
"view": "", "view": "",
"viewreleasenotes": "" "viewreleasenotes": "",
"remove_alert": ""
}, },
"errors": { "errors": {
"fcm": "", "fcm": "",
@@ -2757,7 +2758,9 @@
"total_lab_on_board": "", "total_lab_on_board": "",
"total_lar_on_board": "", "total_lar_on_board": "",
"total_amount_on_board": "", "total_amount_on_board": "",
"total_jobs_on_board": "" "total_jobs_on_board": "",
"tasks_in_production": "",
"tasks_on_board": ""
} }
}, },
"actions": { "actions": {
@@ -2792,6 +2795,7 @@
"model_info": "", "model_info": "",
"actual_in": "", "actual_in": "",
"alert": "", "alert": "",
"tasks": "",
"alertoff": "", "alertoff": "",
"alerton": "", "alerton": "",
"ats": "", "ats": "",
@@ -2845,6 +2849,9 @@
"total_lar_on_board": "", "total_lar_on_board": "",
"total_amount_on_board": "", "total_amount_on_board": "",
"total_jobs_on_board": "", "total_jobs_on_board": "",
"tasks_in_production": "",
"tasks_on_board": "",
"tasks": "",
"hours": "", "hours": "",
"currency_symbol": "", "currency_symbol": "",
"jobs": "" "jobs": ""

View File

@@ -1160,7 +1160,8 @@
"submit": "", "submit": "",
"tryagain": "", "tryagain": "",
"view": "", "view": "",
"viewreleasenotes": "" "viewreleasenotes": "",
"remove_alert": ""
}, },
"errors": { "errors": {
"fcm": "", "fcm": "",
@@ -2757,7 +2758,9 @@
"total_lab_on_board": "", "total_lab_on_board": "",
"total_lar_on_board": "", "total_lar_on_board": "",
"total_amount_on_board": "", "total_amount_on_board": "",
"total_jobs_on_board": "" "total_jobs_on_board": "",
"tasks_in_production": "",
"tasks_on_board": ""
} }
}, },
"actions": { "actions": {
@@ -2792,6 +2795,7 @@
"model_info": "", "model_info": "",
"actual_in": "", "actual_in": "",
"alert": "", "alert": "",
"tasks": "",
"alertoff": "", "alertoff": "",
"alerton": "", "alerton": "",
"ats": "", "ats": "",
@@ -2845,6 +2849,9 @@
"total_lar_on_board": "", "total_lar_on_board": "",
"total_amount_on_board": "", "total_amount_on_board": "",
"total_jobs_on_board": "", "total_jobs_on_board": "",
"tasks_in_production": "",
"tasks_on_board": "",
"tasks": "",
"hours": "", "hours": "",
"currency_symbol": "", "currency_symbol": "",
"jobs": "" "jobs": ""

View File

@@ -6,8 +6,6 @@ import * as url from "url";
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import { ViteEjsPlugin } from "vite-plugin-ejs"; import { ViteEjsPlugin } from "vite-plugin-ejs";
import eslint from "vite-plugin-eslint"; import eslint from "vite-plugin-eslint";
//import CompressionPlugin from 'vite-plugin-compression';
import { VitePWA } from "vite-plugin-pwa"; import { VitePWA } from "vite-plugin-pwa";
import InstanceRenderManager from "./src/utils/instanceRenderMgr"; 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";`; const WRONG_CODE = `import { bpfrpt_proptype_WindowScroller } from "../WindowScroller.js";`;
function reactVirtualized() {
function reactVirtualizedFix() {
return { return {
name: "flat:react-virtualized", name: "flat:react-virtualized",
configResolved: async () => { configResolved: async () => {
@@ -37,10 +36,7 @@ function reactVirtualized() {
export default defineConfig({ export default defineConfig({
base: "/", base: "/",
plugins: [ plugins: [
ViteEjsPlugin((viteConfig) => { ViteEjsPlugin((viteConfig) => ({ env: viteConfig.env })),
// viteConfig is the current Vite resolved config
return { env: viteConfig.env };
}),
VitePWA({ VitePWA({
injectRegister: "auto", injectRegister: "auto",
registerType: "prompt", registerType: "prompt",
@@ -60,7 +56,6 @@ export default defineConfig({
description: "The ultimate bodyshop management system.", description: "The ultimate bodyshop management system.",
icons: [ icons: [
{ {
//TODO:AIO Ensure that these are correct for Rome and IO.
src: InstanceRenderManager({ src: InstanceRenderManager({
instance: process.env.VITE_APP_INSTANCE, instance: process.env.VITE_APP_INSTANCE,
imex: "favicon.png", imex: "favicon.png",
@@ -101,7 +96,7 @@ export default defineConfig({
gcm_sender_id: "103953800507" gcm_sender_id: "103953800507"
} }
}), }),
reactVirtualized(), reactVirtualizedFix(),
react(), react(),
eslint() eslint()
// CompressionPlugin(), //Cloudfront already compresses assets, so not needed. // CompressionPlugin(), //Cloudfront already compresses assets, so not needed.

View File

@@ -0,0 +1,9 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- UPDATE "public"."masterdata"
-- SET value = jsonb_set(
-- value::jsonb,
-- '{OP20}',
-- '{"desc": "REMOVE AND REINSTALL", "opcode": "OP20", "partcode": "PAE"}'::jsonb,
-- true
-- );

View File

@@ -0,0 +1,7 @@
UPDATE "public"."masterdata"
SET value = jsonb_set(
value::jsonb,
'{OP20}',
'{"desc": "REMOVE AND REINSTALL", "opcode": "OP20", "partcode": "PAE"}'::jsonb,
true
);

613
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -19,18 +19,18 @@
"makeitpretty": "prettier --write \"**/*.{css,js,json,jsx,scss}\"" "makeitpretty": "prettier --write \"**/*.{css,js,json,jsx,scss}\""
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-secrets-manager": "^3.616.0", "@aws-sdk/client-secrets-manager": "^3.629.0",
"@aws-sdk/client-ses": "^3.616.0", "@aws-sdk/client-ses": "^3.629.0",
"@aws-sdk/credential-provider-node": "^3.616.0", "@aws-sdk/credential-provider-node": "^3.629.0",
"@opensearch-project/opensearch": "^2.10.0", "@opensearch-project/opensearch": "^2.11.0",
"aws4": "^1.13.0", "aws4": "^1.13.1",
"axios": "^1.7.2", "axios": "^1.7.4",
"better-queue": "^3.8.12", "better-queue": "^3.8.12",
"bluebird": "^3.7.2", "bluebird": "^3.7.2",
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"canvas": "^2.11.2", "canvas": "^2.11.2",
"chart.js": "^4.4.3", "chart.js": "^4.4.3",
"cloudinary": "^2.3.0", "cloudinary": "^2.4.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "2.8.5", "cors": "2.8.5",
@@ -38,24 +38,24 @@
"dinero.js": "^1.9.1", "dinero.js": "^1.9.1",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.19.2", "express": "^4.19.2",
"firebase-admin": "^12.2.0", "firebase-admin": "^12.3.1",
"graphql": "^16.9.0", "graphql": "^16.9.0",
"graphql-request": "^6.1.0", "graphql-request": "^6.1.0",
"graylog2": "^0.2.1", "graylog2": "^0.2.1",
"inline-css": "^4.0.2", "inline-css": "^4.0.2",
"intuit-oauth": "^4.1.2", "intuit-oauth": "^4.1.2",
"json-2-csv": "^5.5.4", "json-2-csv": "^5.5.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-timezone": "^0.5.45", "moment-timezone": "^0.5.45",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"node-mailjet": "^6.0.5", "node-mailjet": "^6.0.5",
"node-persist": "^4.0.2", "node-persist": "^4.0.3",
"nodemailer": "^6.9.14", "nodemailer": "^6.9.14",
"phone": "^3.1.49", "phone": "^3.1.49",
"recursive-diff": "^1.0.9", "recursive-diff": "^1.0.9",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"soap": "^1.1.0", "soap": "^1.1.1",
"socket.io": "^4.7.5", "socket.io": "^4.7.5",
"ssh2-sftp-client": "^10.0.3", "ssh2-sftp-client": "^10.0.3",
"twilio": "^4.23.0", "twilio": "^4.23.0",

View File

@@ -33,7 +33,7 @@ const ftpSetup = {
exports.default = async (req, res) => { exports.default = async (req, res) => {
//Query for the List of Bodyshop Clients. //Query for the List of Bodyshop Clients.
logger.log("kaizen-start", "DEBUG", "api", null, null); 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, { const { bodyshops } = await client.request(queries.GET_KAIZEN_SHOPS, {
imexshopid: kaizenShopsIDs imexshopid: kaizenShopsIDs