Merged in feature/IO-1828-Front-End-Package-Updates (pull request #1155)

Feature/IO-1828 Front End Package Updates
This commit is contained in:
Dave Richer
2024-01-13 00:33:16 +00:00
85 changed files with 1134 additions and 995 deletions

View File

@@ -8872,13 +8872,13 @@
│ ├─ email: luis@luisrudge.net │ ├─ email: luis@luisrudge.net
│ ├─ path: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-flexbugs-fixes │ ├─ path: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-flexbugs-fixes
│ └─ licenseFile: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-flexbugs-fixes/LICENSE │ └─ licenseFile: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-flexbugs-fixes/LICENSE
├─ postcss-focus-visible@4.0.0 ├─ postcss-focus-open@4.0.0
│ ├─ licenses: CC0-1.0 │ ├─ licenses: CC0-1.0
│ ├─ repository: https://github.com/jonathantneal/postcss-focus-visible │ ├─ repository: https://github.com/jonathantneal/postcss-focus-open
│ ├─ publisher: Jonathan Neal │ ├─ publisher: Jonathan Neal
│ ├─ email: jonathantneal@hotmail.com │ ├─ email: jonathantneal@hotmail.com
│ ├─ path: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-visible │ ├─ path: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-open
│ └─ licenseFile: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-visible/LICENSE.md │ └─ licenseFile: /Users/pfic/Documents/Development/bodyshop/client/node_modules/postcss-focus-open/LICENSE.md
├─ postcss-focus-within@3.0.0 ├─ postcss-focus-within@3.0.0
│ ├─ licenses: CC0-1.0 │ ├─ licenses: CC0-1.0
│ ├─ repository: https://github.com/jonathantneal/postcss-focus-within │ ├─ repository: https://github.com/jonathantneal/postcss-focus-within

277
client/package-lock.json generated
View File

@@ -16,8 +16,8 @@
"@fingerprintjs/fingerprintjs": "^4.2.1", "@fingerprintjs/fingerprintjs": "^4.2.1",
"@jsreport/browser-client": "^3.1.0", "@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.0.1", "@reduxjs/toolkit": "^2.0.1",
"@sentry/react": "^7.92.0", "@sentry/react": "^7.93.0",
"@sentry/tracing": "^7.92.0", "@sentry/tracing": "^7.93.0",
"@splitsoftware/splitio-react": "^1.10.2", "@splitsoftware/splitio-react": "^1.10.2",
"@tanem/react-nprogress": "^5.0.51", "@tanem/react-nprogress": "^5.0.51",
"antd": "^5.12.8", "antd": "^5.12.8",
@@ -56,13 +56,13 @@
"react-grid-gallery": "^1.0.0", "react-grid-gallery": "^1.0.0",
"react-grid-layout": "^1.3.4", "react-grid-layout": "^1.3.4",
"react-i18next": "^14.0.0", "react-i18next": "^14.0.0",
"react-icons": "^4.7.1", "react-icons": "^5.0.1",
"react-image-lightbox": "^5.1.4", "react-image-lightbox": "^5.1.4",
"react-intersection-observer": "^9.5.3", "react-intersection-observer": "^9.5.3",
"react-number-format": "^5.1.4", "react-number-format": "^5.1.4",
"react-redux": "^9.0.4", "react-redux": "^9.1.0",
"react-resizable": "^3.0.5", "react-resizable": "^3.0.5",
"react-router-dom": "^6.21.1", "react-router-dom": "^6.21.2",
"react-scripts": "^5.0.1", "react-scripts": "^5.0.1",
"react-sticky": "^6.0.3", "react-sticky": "^6.0.3",
"react-sublime-video": "^0.2.5", "react-sublime-video": "^0.2.5",
@@ -74,7 +74,7 @@
"redux-state-sync": "^3.1.4", "redux-state-sync": "^3.1.4",
"reselect": "^5.1.0", "reselect": "^5.1.0",
"sass": "^1.69.7", "sass": "^1.69.7",
"socket.io-client": "^4.7.3", "socket.io-client": "^4.7.4",
"styled-components": "^6.1.8", "styled-components": "^6.1.8",
"subscriptions-transport-ws": "^0.11.0", "subscriptions-transport-ws": "^0.11.0",
"terser-webpack-plugin": "^5.3.10", "terser-webpack-plugin": "^5.3.10",
@@ -4402,9 +4402,9 @@
} }
}, },
"node_modules/@remix-run/router": { "node_modules/@remix-run/router": {
"version": "1.14.1", "version": "1.14.2",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.1.tgz", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz",
"integrity": "sha512-Qg4DMQsfPNAs88rb2xkdk03N3bjK4jgX5fR24eHCTR9q6PrhZQZ4UJBPzCHJkIpTRN1UKxx2DzjZmnC+7Lj0Ow==", "integrity": "sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==",
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
} }
@@ -4508,44 +4508,44 @@
"integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==" "integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA=="
}, },
"node_modules/@sentry-internal/feedback": { "node_modules/@sentry-internal/feedback": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.93.0.tgz",
"integrity": "sha512-/jEALRtVqboxB9kcK2tag8QCO6XANTlGBb9RV3oeGXJe0DDNJXRq6wVZbfgztXJRrfgx4XVDcNt1pRVoGGG++g==", "integrity": "sha512-4G7rMeQbYGfCHxEoFroABX+UREYc2BSbFqjLmLbIcWowSpgzcwweLLphWHKOciqK6f7DnNDK0jZzx3u7NrkWHw==",
"dependencies": { "dependencies": {
"@sentry/core": "7.92.0", "@sentry/core": "7.93.0",
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@sentry-internal/feedback/node_modules/@sentry/core": { "node_modules/@sentry-internal/feedback/node_modules/@sentry/core": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.93.0.tgz",
"integrity": "sha512-1Tly7YB2I1byI5xb0Cwrxs56Rhww+6mQ7m9P7rTmdC3/ijOzbEoohtYIUPwcooCEarpbEJe/tAayRx6BrH2UbQ==", "integrity": "sha512-vZQSUiDn73n+yu2fEcH+Wpm4GbRmtxmnXnYCPgM6IjnXqkVm3awWAkzrheADblx3kmxrRiOlTXYHw9NTWs56fg==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry-internal/feedback/node_modules/@sentry/types": { "node_modules/@sentry-internal/feedback/node_modules/@sentry/types": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.93.0.tgz",
"integrity": "sha512-APmSOuZuoRGpbPpPeYIbMSplPjiWNLZRQa73QiXuTflW4Tu/ItDlU8hOa2+A6JKVkJCuD2EN6yUrxDGSMyNXeg==", "integrity": "sha512-UnzUccNakhFRA/esWBWP+0v7cjNg+RilFBQC03Mv9OEMaZaS29zSbcOGtRzuFOXXLBdbr44BWADqpz3VW0XaNw==",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry-internal/feedback/node_modules/@sentry/utils": { "node_modules/@sentry-internal/feedback/node_modules/@sentry/utils": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.93.0.tgz",
"integrity": "sha512-3nEfrQ1z28b/2zgFGANPh5yMVtgwXmrasZxTvKbrAj+KWJpjrJHrIR84r9W277J44NMeZ5RhRW2uoDmuBslPnA==", "integrity": "sha512-Iovj7tUnbgSkh/WrAaMrd5UuYjW7AzyzZlFDIUrwidsyIdUficjCG2OIxYzh76H6nYIx9SxewW0R54Q6XoB4uA==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0" "@sentry/types": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -4566,60 +4566,60 @@
} }
}, },
"node_modules/@sentry/browser": { "node_modules/@sentry/browser": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.93.0.tgz",
"integrity": "sha512-loMr02/zQ38u8aQhYLtIBg0i5n3ps2e3GUXrt3CdsJQdkRYfa62gcrE7SzvoEpMVHTk7VOI4fWGht8cWw/1k3A==", "integrity": "sha512-MtLTcQ7y3rfk+aIvnnwCfSJvYhTJnIJi+Mf6y/ap6SKObdlsKMbQoJLlRViglGLq+nKxHLAvU0fONiCEmKfV6A==",
"dependencies": { "dependencies": {
"@sentry-internal/feedback": "7.92.0", "@sentry-internal/feedback": "7.93.0",
"@sentry-internal/tracing": "7.92.0", "@sentry-internal/tracing": "7.93.0",
"@sentry/core": "7.92.0", "@sentry/core": "7.93.0",
"@sentry/replay": "7.92.0", "@sentry/replay": "7.93.0",
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/browser/node_modules/@sentry-internal/tracing": { "node_modules/@sentry/browser/node_modules/@sentry-internal/tracing": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.93.0.tgz",
"integrity": "sha512-ur55vPcUUUWFUX4eVLNP71ohswK7ZZpleNZw9Y1GfLqyI+0ILQUwjtzqItJrdClvVsdRZJMRmDV40Hp9Lbb9mA==", "integrity": "sha512-DjuhmQNywPp+8fxC9dvhGrqgsUb6wI/HQp25lS2Re7VxL1swCasvpkg8EOYP4iBniVQ86QK0uITkOIRc5tdY1w==",
"dependencies": { "dependencies": {
"@sentry/core": "7.92.0", "@sentry/core": "7.93.0",
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/browser/node_modules/@sentry/core": { "node_modules/@sentry/browser/node_modules/@sentry/core": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.93.0.tgz",
"integrity": "sha512-1Tly7YB2I1byI5xb0Cwrxs56Rhww+6mQ7m9P7rTmdC3/ijOzbEoohtYIUPwcooCEarpbEJe/tAayRx6BrH2UbQ==", "integrity": "sha512-vZQSUiDn73n+yu2fEcH+Wpm4GbRmtxmnXnYCPgM6IjnXqkVm3awWAkzrheADblx3kmxrRiOlTXYHw9NTWs56fg==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/browser/node_modules/@sentry/types": { "node_modules/@sentry/browser/node_modules/@sentry/types": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.93.0.tgz",
"integrity": "sha512-APmSOuZuoRGpbPpPeYIbMSplPjiWNLZRQa73QiXuTflW4Tu/ItDlU8hOa2+A6JKVkJCuD2EN6yUrxDGSMyNXeg==", "integrity": "sha512-UnzUccNakhFRA/esWBWP+0v7cjNg+RilFBQC03Mv9OEMaZaS29zSbcOGtRzuFOXXLBdbr44BWADqpz3VW0XaNw==",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/browser/node_modules/@sentry/utils": { "node_modules/@sentry/browser/node_modules/@sentry/utils": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.93.0.tgz",
"integrity": "sha512-3nEfrQ1z28b/2zgFGANPh5yMVtgwXmrasZxTvKbrAj+KWJpjrJHrIR84r9W277J44NMeZ5RhRW2uoDmuBslPnA==", "integrity": "sha512-Iovj7tUnbgSkh/WrAaMrd5UuYjW7AzyzZlFDIUrwidsyIdUficjCG2OIxYzh76H6nYIx9SxewW0R54Q6XoB4uA==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0" "@sentry/types": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -4817,13 +4817,14 @@
} }
}, },
"node_modules/@sentry/react": { "node_modules/@sentry/react": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.93.0.tgz",
"integrity": "sha512-lTvrLuvxtGEZbkW6NHru03K6eyixKyBliwiLwO+k37FK7Ha8Bwat2m77weyizWCdQ6DKlVazJNppkNeAlACIvQ==", "integrity": "sha512-B0bzziV1lEyN7xd0orUPyJdpoK6CtcyodmQkfY0WsHLm/1d9xi95M05lObHnsMWO1js6c9B9d9kO8RlKFz947A==",
"dependencies": { "dependencies": {
"@sentry/browser": "7.92.0", "@sentry/browser": "7.93.0",
"@sentry/types": "7.92.0", "@sentry/core": "7.93.0",
"@sentry/utils": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.93.0",
"hoist-non-react-statics": "^3.3.2" "hoist-non-react-statics": "^3.3.2"
}, },
"engines": { "engines": {
@@ -4833,133 +4834,145 @@
"react": "15.x || 16.x || 17.x || 18.x" "react": "15.x || 16.x || 17.x || 18.x"
} }
}, },
"node_modules/@sentry/react/node_modules/@sentry/core": {
"version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.93.0.tgz",
"integrity": "sha512-vZQSUiDn73n+yu2fEcH+Wpm4GbRmtxmnXnYCPgM6IjnXqkVm3awWAkzrheADblx3kmxrRiOlTXYHw9NTWs56fg==",
"dependencies": {
"@sentry/types": "7.93.0",
"@sentry/utils": "7.93.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/react/node_modules/@sentry/types": { "node_modules/@sentry/react/node_modules/@sentry/types": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.93.0.tgz",
"integrity": "sha512-APmSOuZuoRGpbPpPeYIbMSplPjiWNLZRQa73QiXuTflW4Tu/ItDlU8hOa2+A6JKVkJCuD2EN6yUrxDGSMyNXeg==", "integrity": "sha512-UnzUccNakhFRA/esWBWP+0v7cjNg+RilFBQC03Mv9OEMaZaS29zSbcOGtRzuFOXXLBdbr44BWADqpz3VW0XaNw==",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/react/node_modules/@sentry/utils": { "node_modules/@sentry/react/node_modules/@sentry/utils": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.93.0.tgz",
"integrity": "sha512-3nEfrQ1z28b/2zgFGANPh5yMVtgwXmrasZxTvKbrAj+KWJpjrJHrIR84r9W277J44NMeZ5RhRW2uoDmuBslPnA==", "integrity": "sha512-Iovj7tUnbgSkh/WrAaMrd5UuYjW7AzyzZlFDIUrwidsyIdUficjCG2OIxYzh76H6nYIx9SxewW0R54Q6XoB4uA==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0" "@sentry/types": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/replay": { "node_modules/@sentry/replay": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.93.0.tgz",
"integrity": "sha512-G1t9Uvc9cR8VpNkElwvHIMGzykjIKikb10n0tfVd3e+rBPMCCjCPWOduwG6jZYxcvCjTpqmJh6NSLXxL/Mt4JA==", "integrity": "sha512-dMlLU8v+OkUeGCrPvTu5NriH7BGj3el4rGHWWAYicfJ2QXqTTq50vfasQBP1JeVNcFqnf1y653TdEIvo4RH4tw==",
"dependencies": { "dependencies": {
"@sentry-internal/tracing": "7.92.0", "@sentry-internal/tracing": "7.93.0",
"@sentry/core": "7.92.0", "@sentry/core": "7.93.0",
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@sentry/replay/node_modules/@sentry-internal/tracing": { "node_modules/@sentry/replay/node_modules/@sentry-internal/tracing": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.93.0.tgz",
"integrity": "sha512-ur55vPcUUUWFUX4eVLNP71ohswK7ZZpleNZw9Y1GfLqyI+0ILQUwjtzqItJrdClvVsdRZJMRmDV40Hp9Lbb9mA==", "integrity": "sha512-DjuhmQNywPp+8fxC9dvhGrqgsUb6wI/HQp25lS2Re7VxL1swCasvpkg8EOYP4iBniVQ86QK0uITkOIRc5tdY1w==",
"dependencies": { "dependencies": {
"@sentry/core": "7.92.0", "@sentry/core": "7.93.0",
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/replay/node_modules/@sentry/core": { "node_modules/@sentry/replay/node_modules/@sentry/core": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.93.0.tgz",
"integrity": "sha512-1Tly7YB2I1byI5xb0Cwrxs56Rhww+6mQ7m9P7rTmdC3/ijOzbEoohtYIUPwcooCEarpbEJe/tAayRx6BrH2UbQ==", "integrity": "sha512-vZQSUiDn73n+yu2fEcH+Wpm4GbRmtxmnXnYCPgM6IjnXqkVm3awWAkzrheADblx3kmxrRiOlTXYHw9NTWs56fg==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/replay/node_modules/@sentry/types": { "node_modules/@sentry/replay/node_modules/@sentry/types": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.93.0.tgz",
"integrity": "sha512-APmSOuZuoRGpbPpPeYIbMSplPjiWNLZRQa73QiXuTflW4Tu/ItDlU8hOa2+A6JKVkJCuD2EN6yUrxDGSMyNXeg==", "integrity": "sha512-UnzUccNakhFRA/esWBWP+0v7cjNg+RilFBQC03Mv9OEMaZaS29zSbcOGtRzuFOXXLBdbr44BWADqpz3VW0XaNw==",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/replay/node_modules/@sentry/utils": { "node_modules/@sentry/replay/node_modules/@sentry/utils": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.93.0.tgz",
"integrity": "sha512-3nEfrQ1z28b/2zgFGANPh5yMVtgwXmrasZxTvKbrAj+KWJpjrJHrIR84r9W277J44NMeZ5RhRW2uoDmuBslPnA==", "integrity": "sha512-Iovj7tUnbgSkh/WrAaMrd5UuYjW7AzyzZlFDIUrwidsyIdUficjCG2OIxYzh76H6nYIx9SxewW0R54Q6XoB4uA==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0" "@sentry/types": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/tracing": { "node_modules/@sentry/tracing": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.93.0.tgz",
"integrity": "sha512-1+TFFPVEdax4dNi68gin6MENiyGe9mOuNXfjulrP5eCzUEByus5HAxeDI/LLQ1hArfn048AzwSwKUsS2fO5sbg==", "integrity": "sha512-n4XbAQ7e098Jzv4ZvpXAsFgM+XFfjhKci18r7s3UfDMnrB4FTCwhHZoeiygO8PZhB944mEFbNXNFhHkb8nTDbA==",
"dependencies": { "dependencies": {
"@sentry-internal/tracing": "7.92.0" "@sentry-internal/tracing": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/tracing/node_modules/@sentry-internal/tracing": { "node_modules/@sentry/tracing/node_modules/@sentry-internal/tracing": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.93.0.tgz",
"integrity": "sha512-ur55vPcUUUWFUX4eVLNP71ohswK7ZZpleNZw9Y1GfLqyI+0ILQUwjtzqItJrdClvVsdRZJMRmDV40Hp9Lbb9mA==", "integrity": "sha512-DjuhmQNywPp+8fxC9dvhGrqgsUb6wI/HQp25lS2Re7VxL1swCasvpkg8EOYP4iBniVQ86QK0uITkOIRc5tdY1w==",
"dependencies": { "dependencies": {
"@sentry/core": "7.92.0", "@sentry/core": "7.93.0",
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/tracing/node_modules/@sentry/core": { "node_modules/@sentry/tracing/node_modules/@sentry/core": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.93.0.tgz",
"integrity": "sha512-1Tly7YB2I1byI5xb0Cwrxs56Rhww+6mQ7m9P7rTmdC3/ijOzbEoohtYIUPwcooCEarpbEJe/tAayRx6BrH2UbQ==", "integrity": "sha512-vZQSUiDn73n+yu2fEcH+Wpm4GbRmtxmnXnYCPgM6IjnXqkVm3awWAkzrheADblx3kmxrRiOlTXYHw9NTWs56fg==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0", "@sentry/types": "7.93.0",
"@sentry/utils": "7.92.0" "@sentry/utils": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/tracing/node_modules/@sentry/types": { "node_modules/@sentry/tracing/node_modules/@sentry/types": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.93.0.tgz",
"integrity": "sha512-APmSOuZuoRGpbPpPeYIbMSplPjiWNLZRQa73QiXuTflW4Tu/ItDlU8hOa2+A6JKVkJCuD2EN6yUrxDGSMyNXeg==", "integrity": "sha512-UnzUccNakhFRA/esWBWP+0v7cjNg+RilFBQC03Mv9OEMaZaS29zSbcOGtRzuFOXXLBdbr44BWADqpz3VW0XaNw==",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@sentry/tracing/node_modules/@sentry/utils": { "node_modules/@sentry/tracing/node_modules/@sentry/utils": {
"version": "7.92.0", "version": "7.93.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.92.0.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.93.0.tgz",
"integrity": "sha512-3nEfrQ1z28b/2zgFGANPh5yMVtgwXmrasZxTvKbrAj+KWJpjrJHrIR84r9W277J44NMeZ5RhRW2uoDmuBslPnA==", "integrity": "sha512-Iovj7tUnbgSkh/WrAaMrd5UuYjW7AzyzZlFDIUrwidsyIdUficjCG2OIxYzh76H6nYIx9SxewW0R54Q6XoB4uA==",
"dependencies": { "dependencies": {
"@sentry/types": "7.92.0" "@sentry/types": "7.93.0"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -18327,9 +18340,9 @@
} }
}, },
"node_modules/react-icons": { "node_modules/react-icons": {
"version": "4.12.0", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
"integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", "integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==",
"peerDependencies": { "peerDependencies": {
"react": "*" "react": "*"
} }
@@ -18416,9 +18429,9 @@
} }
}, },
"node_modules/react-redux": { "node_modules/react-redux": {
"version": "9.0.4", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.0.4.tgz", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.0.tgz",
"integrity": "sha512-9J1xh8sWO0vYq2sCxK2My/QO7MzUMRi3rpiILP/+tDr8krBHixC6JMM17fMK88+Oh3e4Ae6/sHIhNBgkUivwFA==", "integrity": "sha512-6qoDzIO+gbrza8h3hjMA9aq4nwVFCKFtY2iLxCtVT38Swyy2C/dJCGBXHeHLtx6qlg/8qzc2MrhOeduf5K32wQ==",
"dependencies": { "dependencies": {
"@types/use-sync-external-store": "^0.0.3", "@types/use-sync-external-store": "^0.0.3",
"use-sync-external-store": "^1.0.0" "use-sync-external-store": "^1.0.0"
@@ -18462,11 +18475,11 @@
} }
}, },
"node_modules/react-router": { "node_modules/react-router": {
"version": "6.21.1", "version": "6.21.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.1.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.2.tgz",
"integrity": "sha512-W0l13YlMTm1YrpVIOpjCADJqEUpz1vm+CMo47RuFX4Ftegwm6KOYsL5G3eiE52jnJpKvzm6uB/vTKTPKM8dmkA==", "integrity": "sha512-jJcgiwDsnaHIeC+IN7atO0XiSRCrOsQAHHbChtJxmgqG2IaYQXSnhqGb5vk2CU/wBQA12Zt+TkbuJjIn65gzbA==",
"dependencies": { "dependencies": {
"@remix-run/router": "1.14.1" "@remix-run/router": "1.14.2"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
@@ -18476,12 +18489,12 @@
} }
}, },
"node_modules/react-router-dom": { "node_modules/react-router-dom": {
"version": "6.21.1", "version": "6.21.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.1.tgz", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.2.tgz",
"integrity": "sha512-QCNrtjtDPwHDO+AO21MJd7yIcr41UetYt5jzaB9Y1UYaPTCnVuJq6S748g1dE11OQlCFIQg+RtAA1SEZIyiBeA==", "integrity": "sha512-tE13UukgUOh2/sqYr6jPzZTzmzc70aGRP4pAjG2if0IP3aUT+sBtAKUJh0qMh0zylJHGLmzS+XWVaON4UklHeg==",
"dependencies": { "dependencies": {
"@remix-run/router": "1.14.1", "@remix-run/router": "1.14.2",
"react-router": "6.21.1" "react-router": "6.21.2"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
@@ -19793,9 +19806,9 @@
} }
}, },
"node_modules/socket.io-client": { "node_modules/socket.io-client": {
"version": "4.7.3", "version": "4.7.4",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.3.tgz", "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.4.tgz",
"integrity": "sha512-nU+ywttCyBitXIl9Xe0RSEfek4LneYkJxCeNnKCuhwoH4jGXO1ipIUw/VA/+Vvv2G1MTym11fzFC0SxkrcfXDw==", "integrity": "sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==",
"dependencies": { "dependencies": {
"@socket.io/component-emitter": "~3.1.0", "@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2", "debug": "~4.3.2",

View File

@@ -12,8 +12,8 @@
"@fingerprintjs/fingerprintjs": "^4.2.1", "@fingerprintjs/fingerprintjs": "^4.2.1",
"@jsreport/browser-client": "^3.1.0", "@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.0.1", "@reduxjs/toolkit": "^2.0.1",
"@sentry/react": "^7.92.0", "@sentry/react": "^7.93.0",
"@sentry/tracing": "^7.92.0", "@sentry/tracing": "^7.93.0",
"@splitsoftware/splitio-react": "^1.10.2", "@splitsoftware/splitio-react": "^1.10.2",
"@tanem/react-nprogress": "^5.0.51", "@tanem/react-nprogress": "^5.0.51",
"antd": "^5.12.8", "antd": "^5.12.8",
@@ -52,13 +52,13 @@
"react-grid-gallery": "^1.0.0", "react-grid-gallery": "^1.0.0",
"react-grid-layout": "^1.3.4", "react-grid-layout": "^1.3.4",
"react-i18next": "^14.0.0", "react-i18next": "^14.0.0",
"react-icons": "^4.7.1", "react-icons": "^5.0.1",
"react-image-lightbox": "^5.1.4", "react-image-lightbox": "^5.1.4",
"react-intersection-observer": "^9.5.3", "react-intersection-observer": "^9.5.3",
"react-number-format": "^5.1.4", "react-number-format": "^5.1.4",
"react-redux": "^9.0.4", "react-redux": "^9.1.0",
"react-resizable": "^3.0.5", "react-resizable": "^3.0.5",
"react-router-dom": "^6.21.1", "react-router-dom": "^6.21.2",
"react-scripts": "^5.0.1", "react-scripts": "^5.0.1",
"react-sticky": "^6.0.3", "react-sticky": "^6.0.3",
"react-sublime-video": "^0.2.5", "react-sublime-video": "^0.2.5",
@@ -70,7 +70,7 @@
"redux-state-sync": "^3.1.4", "redux-state-sync": "^3.1.4",
"reselect": "^5.1.0", "reselect": "^5.1.0",
"sass": "^1.69.7", "sass": "^1.69.7",
"socket.io-client": "^4.7.3", "socket.io-client": "^4.7.4",
"styled-components": "^6.1.8", "styled-components": "^6.1.8",
"subscriptions-transport-ws": "^0.11.0", "subscriptions-transport-ws": "^0.11.0",
"terser-webpack-plugin": "^5.3.10", "terser-webpack-plugin": "^5.3.10",

View File

@@ -190,7 +190,7 @@ This package contains the following license and notice below:
# @firebase/logger # @firebase/logger
This package serves as the base of all logging in the JS SDK. Any logging that This package serves as the base of all logging in the JS SDK. Any logging that
is intended to be visible to Firebase end developers should go through this is intended to be open to Firebase end developers should go through this
module. module.
## Basic Usage ## Basic Usage
@@ -9375,7 +9375,7 @@ parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying. a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices" An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible to the extent that it includes a convenient and prominently open
feature that (1) displays an appropriate copyright notice, and (2) feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the extent that warranties are provided), that licensees may convey the

View File

@@ -1029,7 +1029,7 @@ The following NPM packages may be included in this product:
- postcss-dir-pseudo-class@5.0.0 - postcss-dir-pseudo-class@5.0.0
- postcss-double-position-gradients@1.0.0 - postcss-double-position-gradients@1.0.0
- postcss-env-function@2.0.2 - postcss-env-function@2.0.2
- postcss-focus-visible@4.0.0 - postcss-focus-open@4.0.0
- postcss-focus-within@3.0.0 - postcss-focus-within@3.0.0
- postcss-gap-properties@2.0.0 - postcss-gap-properties@2.0.0
- postcss-image-set-function@3.0.1 - postcss-image-set-function@3.0.1
@@ -1699,7 +1699,7 @@ This package contains the following license and notice below:
# @firebase/logger # @firebase/logger
This package serves as the base of all logging in the JS SDK. Any logging that This package serves as the base of all logging in the JS SDK. Any logging that
is intended to be visible to Firebase end developers should go through this is intended to be open to Firebase end developers should go through this
module. module.
## Basic Usage ## Basic Usage
@@ -24029,7 +24029,7 @@ parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying. a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices" An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible to the extent that it includes a convenient and prominently open
feature that (1) displays an appropriate copyright notice, and (2) feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the extent that warranties are provided), that licensees may convey the

View File

@@ -1,7 +1,7 @@
import {useSplitClient} from "@splitsoftware/splitio-react"; import {useSplitClient} from "@splitsoftware/splitio-react";
import {Button, Result} from "antd"; import {Button, Result} from "antd";
import LogRocket from "logrocket"; import LogRocket from "logrocket";
import React, {lazy, Suspense, useEffect} from "react"; import React, {lazy, Suspense, useEffect, useState} from "react";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
import {connect} from "react-redux"; import {connect} from "react-redux";
import {Route, Routes} from "react-router-dom"; import {Route, Routes} from "react-router-dom";
@@ -19,6 +19,7 @@ import {checkUserSession} from "../redux/user/user.actions";
import {selectBodyshop, selectCurrentUser,} from "../redux/user/user.selectors"; import {selectBodyshop, selectCurrentUser,} from "../redux/user/user.selectors";
import PrivateRoute from "../components/PrivateRoute"; import PrivateRoute from "../components/PrivateRoute";
import "./App.styles.scss"; import "./App.styles.scss";
import handleBeta from "../utils/betaHandler";
const ResetPassword = lazy(() => const ResetPassword = lazy(() =>
import("../pages/reset-password/reset-password.component") import("../pages/reset-password/reset-password.component")
@@ -40,14 +41,16 @@ const mapDispatchToProps = (dispatch) => ({
setOnline: (isOnline) => dispatch(setOnline(isOnline)), setOnline: (isOnline) => dispatch(setOnline(isOnline)),
}); });
export function App({ export function App({bodyshop, checkUserSession, currentUser, online, setOnline}) {
bodyshop,
checkUserSession,
currentUser,
online,
setOnline,
}) {
const client = useSplitClient().client; const client = useSplitClient().client;
const [listenersAdded, setListenersAdded] = useState(false)
const {t} = useTranslation();
// Handle The Beta Switch.
useEffect(() => {
handleBeta();
}, [])
useEffect(() => { useEffect(() => {
if (!navigator.onLine) { if (!navigator.onLine) {
@@ -60,21 +63,37 @@ export function App({
//const b = Grid.useBreakpoint(); //const b = Grid.useBreakpoint();
// console.log("Breakpoints:", b); // console.log("Breakpoints:", b);
const {t} = useTranslation(); // Associate event listeners, memoize to prevent multiple listeners being added
useEffect(() => {
const offlineListener = (e) => {
setOnline(false);
}
window.addEventListener("offline", function (e) { const onlineListener = (e) => {
setOnline(false); setOnline(true);
}); }
window.addEventListener("online", function (e) { if (!listenersAdded) {
setOnline(true); console.log('Added events for offline and online');
}); window.addEventListener("offline", offlineListener);
window.addEventListener("online", onlineListener);
setListenersAdded(true);
}
return () => {
window.removeEventListener("offline", offlineListener);
window.removeEventListener("online", onlineListener);
}
}, [setOnline, listenersAdded]);
useEffect(() => { useEffect(() => {
if (currentUser.authorized && bodyshop) { if (currentUser.authorized && bodyshop) {
client.setAttribute("imexshopid", bodyshop.imexshopid); client.setAttribute("imexshopid", bodyshop.imexshopid);
if (client.getTreatment("LogRocket_Tracking") === "on") { if (
client.getTreatment("LogRocket_Tracking") === "on" ||
window.location.hostname === 'beta.imex.online'
) {
console.log("LR Start"); console.log("LR Start");
LogRocket.init("gvfvfw/bodyshopapp"); LogRocket.init("gvfvfw/bodyshopapp");
} }

View File

@@ -1,5 +1,8 @@
//Global Styles. //Global Styles.
@import "react-big-calendar/lib/sass/styles"; @import "react-big-calendar/lib/sass/styles";
.ant-menu-item-divider {
border-bottom: 1px solid #74695c !important;
}
.imex-table-header { .imex-table-header {
display: flex; display: flex;

View File

@@ -48,7 +48,7 @@ export function BillDetailEditcontainer({setPartsOrderContext, insertAuditTrail,
const {t} = useTranslation(); const {t} = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [updateLoading, setUpdateLoading] = useState(false); const [updateLoading, setUpdateLoading] = useState(false);
const [update_bill] = useMutation(UPDATE_BILL); const [update_bill] = useMutation(UPDATE_BILL);
const [insertBillLine] = useMutation(INSERT_NEW_BILL_LINES); const [insertBillLine] = useMutation(INSERT_NEW_BILL_LINES);
@@ -71,7 +71,7 @@ export function BillDetailEditcontainer({setPartsOrderContext, insertAuditTrail,
form.getFieldValue("billlines").filter((b) => b.deductedfromlbr).length > form.getFieldValue("billlines").filter((b) => b.deductedfromlbr).length >
0 0
) )
setVisible(true); setOpen(true);
else { else {
form.submit(); form.submit();
} }
@@ -154,7 +154,7 @@ export function BillDetailEditcontainer({setPartsOrderContext, insertAuditTrail,
await refetch(); await refetch();
form.setFieldsValue(transformData(data)); form.setFieldsValue(transformData(data));
form.resetFields(); form.resetFields();
setVisible(false); setOpen(false);
setUpdateLoading(false); setUpdateLoading(false);
}; };
@@ -178,9 +178,9 @@ export function BillDetailEditcontainer({setPartsOrderContext, insertAuditTrail,
<BillDetailEditReturn data={data} /> <BillDetailEditReturn data={data} />
<BillPrintButton billid={search.billid} /> <BillPrintButton billid={search.billid} />
<Popconfirm <Popconfirm
visible={visible} open={open}
onConfirm={() => form.submit()} onConfirm={() => form.submit()}
onCancel={() => setVisible(false)} onCancel={() => setOpen(false)}
okButtonProps={{ loading: updateLoading }} okButtonProps={{ loading: updateLoading }}
title={t("bills.labels.editadjwarning")} title={t("bills.labels.editadjwarning")}
> >

View File

@@ -36,7 +36,7 @@ export function BillDetailEditReturn({
const history = useNavigate(); const history = useNavigate();
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const handleFinish = ({ billlines }) => { const handleFinish = ({ billlines }) => {
const selectedLines = billlines.filter((l) => l.selected).map((l) => l.id); const selectedLines = billlines.filter((l) => l.selected).map((l) => l.id);
@@ -68,17 +68,17 @@ export function BillDetailEditReturn({
delete search.billid; delete search.billid;
history({ search: queryString.stringify(search) }); history({ search: queryString.stringify(search) });
setVisible(false); setOpen(false);
}; };
useEffect(() => { useEffect(() => {
if (visible === false) form.resetFields(); if (open === false) form.resetFields();
}, [visible, form]); }, [open, form]);
return ( return (
<> <>
<Modal <Modal
open={visible} open={open}
onCancel={() => setVisible(false)} onCancel={() => setOpen(false)}
destroyOnClose destroyOnClose
title={t("bills.actions.return")} title={t("bills.actions.return")}
onOk={() => form.submit()} onOk={() => form.submit()}
@@ -175,7 +175,7 @@ export function BillDetailEditReturn({
<Button <Button
disabled={data.bills_by_pk.is_credit_memo || disabled} disabled={data.bills_by_pk.is_credit_memo || disabled}
onClick={() => { onClick={() => {
setVisible(true); setOpen(true);
}} }}
> >
{t("bills.actions.return")} {t("bills.actions.return")}

View File

@@ -346,18 +346,18 @@ function BillEnterModalContainer({
}, [enterAgain, form]); }, [enterAgain, form]);
useEffect(() => { useEffect(() => {
if (billEnterModal.visible) { if (billEnterModal.open) {
form.setFieldsValue(formValues); form.setFieldsValue(formValues);
} else { } else {
form.resetFields(); form.resetFields();
} }
}, [billEnterModal.visible, form, formValues]); }, [billEnterModal.open, form, formValues]);
return ( return (
<Modal <Modal
title={t("bills.labels.new")} title={t("bills.labels.new")}
width={"98%"} width={"98%"}
open={billEnterModal.visible} open={billEnterModal.open}
okText={t("general.actions.save")} okText={t("general.actions.save")}
keyboard="false" keyboard="false"
onOk={() => form.submit()} onOk={() => form.submit()}

View File

@@ -25,7 +25,7 @@ export function ContractsFindModalContainer({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { visible } = caBcEtfTableModal; const { open } = caBcEtfTableModal;
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [form] = Form.useForm(); const [form] = Form.useForm();
const EtfTemplate = TemplateList("special").ca_bc_etf_table; const EtfTemplate = TemplateList("special").ca_bc_etf_table;
@@ -63,14 +63,14 @@ export function ContractsFindModalContainer({
}; };
useEffect(() => { useEffect(() => {
if (visible) { if (open) {
form.resetFields(); form.resetFields();
} }
}, [visible, form]); }, [open, form]);
return ( return (
<Modal <Modal
open={visible} open={open}
width="70%" width="70%"
title={t("payments.labels.findermodal")} title={t("payments.labels.findermodal")}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}

View File

@@ -22,7 +22,7 @@ function CardPaymentModalContainer({
toggleModalVisible, toggleModalVisible,
bodyshop, bodyshop,
}) { }) {
const { visible } = cardPaymentModal; const { open } = cardPaymentModal;
const { t } = useTranslation(); const { t } = useTranslation();
const handleCancel = () => { const handleCancel = () => {
@@ -35,7 +35,7 @@ function CardPaymentModalContainer({
return ( return (
<Modal <Modal
open={visible} open={open}
onOk={handleOK} onOk={handleOK}
onCancel={handleCancel} onCancel={handleCancel}
footer={[ footer={[

View File

@@ -4,20 +4,11 @@ import { Button, notification, Space } from "antd";
import axios from "axios"; import axios from "axios";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { messaging, requestForToken } from "../../firebase/firebase.utils"; import { messaging, requestForToken } from "../../firebase/firebase.utils";
import { selectChatVisible } from "../../redux/messaging/messaging.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import FcmHandler from "../../utils/fcm-handler"; import FcmHandler from "../../utils/fcm-handler";
import ChatPopupComponent from "../chat-popup/chat-popup.component"; import ChatPopupComponent from "../chat-popup/chat-popup.component";
import "./chat-affix.styles.scss"; import "./chat-affix.styles.scss";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
chatVisible: selectChatVisible,
});
export function ChatAffixContainer({ bodyshop, chatVisible }) { export function ChatAffixContainer({ bodyshop, chatVisible }) {
const { t } = useTranslation(); const { t } = useTranslation();
const client = useApolloClient(); const client = useApolloClient();
@@ -36,35 +27,34 @@ export function ChatAffixContainer({ bodyshop, chatVisible }) {
console.log("FCM Topic Subscription", r.data); console.log("FCM Topic Subscription", r.data);
} catch (error) { } catch (error) {
console.log( console.log(
"Error attempting to subscribe to messaging topic: ", "Error attempting to subscribe to messaging topic: ",
error error
); );
notification.open({ notification.open({
type: "warning", type: "warning",
message: t("general.errors.fcm"), message: t("general.errors.fcm"),
btn: ( btn: (
<Space> <Space>
<Button <Button
onClick={async () => { onClick={async () => {
await requestForToken(); await requestForToken();
SubscribeToTopic();
SubscribeToTopic(); }}
}} >
> {t("general.actions.tryagain")}
{t("general.actions.tryagain")} </Button>
</Button> <Button
<Button onClick={() => {
onClick={() => { const win = window.open(
const win = window.open( "https://help.imex.online/en/article/enabling-notifications-o978xi/",
"https://help.imex.online/en/article/enabling-notifications-o978xi/", "_blank"
"_blank" );
); win.focus();
win.focus(); }}
}} >
> {t("general.labels.help")}
{t("general.labels.help")} </Button>
</Button> </Space>
</Space>
), ),
}); });
} }
@@ -81,16 +71,16 @@ export function ChatAffixContainer({ bodyshop, chatVisible }) {
payload: (payload && payload.data && payload.data.data) || payload.data, payload: (payload && payload.data && payload.data.data) || payload.data,
}); });
} }
let stopMessageListenr, channel; let stopMessageListener, channel;
try { try {
stopMessageListenr = onMessage(messaging, handleMessage); stopMessageListener = onMessage(messaging, handleMessage);
channel = new BroadcastChannel("imex-sw-messages"); channel = new BroadcastChannel("imex-sw-messages");
channel.addEventListener("message", handleMessage); channel.addEventListener("message", handleMessage);
} catch (error) { } catch (error) {
console.log("Unable to set event listeners."); console.log("Unable to set event listeners.");
} }
return () => { return () => {
stopMessageListenr && stopMessageListenr(); stopMessageListener && stopMessageListener();
channel && channel.removeEventListener("message", handleMessage); channel && channel.removeEventListener("message", handleMessage);
}; };
}, [client]); }, [client]);
@@ -98,9 +88,10 @@ export function ChatAffixContainer({ bodyshop, chatVisible }) {
if (!bodyshop || !bodyshop.messagingservicesid) return <></>; if (!bodyshop || !bodyshop.messagingservicesid) return <></>;
return ( return (
<div className={`chat-affix ${chatVisible ? "chat-affix-open" : ""}`}> <div className={`chat-affix ${chatVisible ? "chat-affix-open" : ""}`}>
{bodyshop && bodyshop.messagingservicesid ? <ChatPopupComponent /> : null} {bodyshop && bodyshop.messagingservicesid ? <ChatPopupComponent /> : null}
</div> </div>
); );
} }
export default connect(mapStateToProps, null)(ChatAffixContainer);
export default ChatAffixContainer;

View File

@@ -27,7 +27,7 @@ export function ChatMediaSelector({
conversation, conversation,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const { loading, error, data } = useQuery(GET_DOCUMENTS_BY_JOB, { const { loading, error, data } = useQuery(GET_DOCUMENTS_BY_JOB, {
fetchPolicy: "network-only", fetchPolicy: "network-only",
@@ -39,13 +39,13 @@ export function ChatMediaSelector({
}, },
skip: skip:
!visible || !open ||
!conversation.job_conversations || !conversation.job_conversations ||
conversation.job_conversations.length === 0, conversation.job_conversations.length === 0,
}); });
const handleVisibleChange = (visible) => { const handleVisibleChange = (change) => {
setVisible(visible); setOpen(change);
}; };
useEffect(() => { useEffect(() => {
@@ -65,7 +65,7 @@ export function ChatMediaSelector({
externalMediaState={[selectedMedia, setSelectedMedia]} externalMediaState={[selectedMedia, setSelectedMedia]}
/> />
)} )}
{bodyshop.uselocalmediaserver && visible && ( {bodyshop.uselocalmediaserver && open && (
<JobDocumentsLocalGalleryExternal <JobDocumentsLocalGalleryExternal
externalMediaState={[selectedMedia, setSelectedMedia]} externalMediaState={[selectedMedia, setSelectedMedia]}
jobId={ jobId={
@@ -88,7 +88,7 @@ export function ChatMediaSelector({
} }
title={t("messaging.labels.selectmedia")} title={t("messaging.labels.selectmedia")}
trigger="click" trigger="click"
open={visible} open={open}
onOpenChange={handleVisibleChange} onOpenChange={handleVisibleChange}
> >
<Badge count={selectedMedia.filter((s) => s.isSelected).length}> <Badge count={selectedMedia.filter((s) => s.isSelected).length}>

View File

@@ -9,12 +9,12 @@ export default function ChatTagRoComponent({
loading, loading,
handleSearch, handleSearch,
handleInsertTag, handleInsertTag,
setVisible, setOpen,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Space flex> <Space>
<div style={{ width: "15rem" }}> <div style={{ width: "15rem" }}>
<Select <Select
showSearch showSearch
@@ -38,7 +38,7 @@ export default function ChatTagRoComponent({
{loading ? ( {loading ? (
<LoadingOutlined /> <LoadingOutlined />
) : ( ) : (
<CloseCircleOutlined onClick={() => setVisible(false)} /> <CloseCircleOutlined onClick={() => setOpen(false)} />
)} )}
</Space> </Space>
); );

View File

@@ -11,7 +11,7 @@ import ChatTagRo from "./chat-tag-ro.component";
export default function ChatTagRoContainer({ conversation }) { export default function ChatTagRoContainer({ conversation }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loadRo, { loading, data }] = useLazyQuery(SEARCH_FOR_JOBS); const [loadRo, { loading, data }] = useLazyQuery(SEARCH_FOR_JOBS);
@@ -33,7 +33,7 @@ export default function ChatTagRoContainer({ conversation }) {
const handleInsertTag = (value, option) => { const handleInsertTag = (value, option) => {
logImEXEvent("messaging_add_job_tag"); logImEXEvent("messaging_add_job_tag");
insertTag({ variables: { jobId: option.key } }); insertTag({ variables: { jobId: option.key } });
setVisible(false); setOpen(false);
}; };
const existingJobTags = const existingJobTags =
@@ -47,16 +47,16 @@ export default function ChatTagRoContainer({ conversation }) {
return ( return (
<div> <div>
{visible ? ( {open ? (
<ChatTagRo <ChatTagRo
loading={loading} loading={loading}
roOptions={roOptions} roOptions={roOptions}
handleSearch={handleSearch} handleSearch={handleSearch}
handleInsertTag={handleInsertTag} handleInsertTag={handleInsertTag}
setVisible={setVisible} setOpen={setOpen}
/> />
) : ( ) : (
<Tag onClick={() => setVisible(true)}> <Tag onClick={() => setOpen(true)}>
<PlusOutlined /> <PlusOutlined />
{t("messaging.actions.link")} {t("messaging.actions.link")}
</Tag> </Tag>

View File

@@ -38,7 +38,7 @@ export function ContractConvertToRo({
disabled, disabled,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [insertJob] = useMutation(INSERT_NEW_JOB); const [insertJob] = useMutation(INSERT_NEW_JOB);
const history = useNavigate(); const history = useNavigate();
@@ -306,7 +306,7 @@ export function ContractConvertToRo({
}); });
} }
setVisible(false); setOpen(false);
setLoading(false); setLoading(false);
}; };
@@ -380,7 +380,7 @@ export function ContractConvertToRo({
<Button type="primary" htmlType="submit" loading={loading}> <Button type="primary" htmlType="submit" loading={loading}>
{t("contracts.actions.convertoro")} {t("contracts.actions.convertoro")}
</Button> </Button>
<Button onClick={() => setVisible(false)}> <Button onClick={() => setOpen(false)}>
{t("general.actions.close")} {t("general.actions.close")}
</Button> </Button>
</Space> </Space>
@@ -390,9 +390,9 @@ export function ContractConvertToRo({
return ( return (
<div> <div>
<Popover content={popContent} open={visible}> <Popover content={popContent} open={open}>
<Button <Button
onClick={() => setVisible(true)} onClick={() => setOpen(true)}
loading={loading} loading={loading}
disabled={!contract.dailyrate || !contract.actualreturn || disabled} disabled={!contract.dailyrate || !contract.actualreturn || disabled}
> >

View File

@@ -31,7 +31,7 @@ export function ContractsFindModalContainer({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { visible } = contractFinderModal; const { open } = contractFinderModal;
const [form] = Form.useForm(); const [form] = Form.useForm();
@@ -52,14 +52,14 @@ export function ContractsFindModalContainer({
}; };
useEffect(() => { useEffect(() => {
if (visible) { if (open) {
form.resetFields(); form.resetFields();
} }
}, [visible, form]); }, [open, form]);
return ( return (
<Modal <Modal
open={visible} open={open}
width="70%" width="70%"
title={t("contracts.labels.findermodal")} title={t("contracts.labels.findermodal")}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}

View File

@@ -26,7 +26,7 @@ export function CCReturnModalContainer({
bodyshop, bodyshop,
}) { }) {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { visible, context, actions } = courtesyCarReturnModal; const { open, context, actions } = courtesyCarReturnModal;
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [updateContract] = useMutation(RETURN_CONTRACT); const [updateContract] = useMutation(RETURN_CONTRACT);
@@ -64,7 +64,7 @@ export function CCReturnModalContainer({
return ( return (
<Modal <Modal
title={t("courtesycars.labels.return")} title={t("courtesycars.labels.return")}
open={visible} open={open}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}
width={"90%"} width={"90%"}
okText={t("general.actions.save")} okText={t("general.actions.save")}

View File

@@ -6,13 +6,13 @@ export default function DataLabel({
hideIfNull, hideIfNull,
children, children,
vertical, vertical,
visible = true, open = true,
valueStyle = {}, valueStyle = {},
valueClassName, valueClassName,
onValueClick, onValueClick,
...props ...props
}) { }) {
if (!visible || (hideIfNull && !!!children)) return null; if (!open || (hideIfNull && !!!children)) return null;
return ( return (
<div {...props} style={{ display: "flex" }}> <div {...props} style={{ display: "flex" }}>

View File

@@ -18,7 +18,7 @@ const mapDispatchToProps = (dispatch) => ({
export default connect(mapStateToProps, mapDispatchToProps)(DmsCdkVehicles); export default connect(mapStateToProps, mapDispatchToProps)(DmsCdkVehicles);
export function DmsCdkVehicles({ bodyshop, form, socket, job }) { export function DmsCdkVehicles({ bodyshop, form, socket, job }) {
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [selectedModel, setSelectedModel] = useState(null); const [selectedModel, setSelectedModel] = useState(null);
const { t } = useTranslation(); const { t } = useTranslation();
@@ -51,14 +51,14 @@ export function DmsCdkVehicles({ bodyshop, form, socket, job }) {
<> <>
<Modal <Modal
width={"90%"} width={"90%"}
open={visible} open={open}
onCancel={() => setVisible(false)} onCancel={() => setOpen(false)}
onOk={() => { onOk={() => {
form.setFieldsValue({ form.setFieldsValue({
dms_make: selectedModel.makecode, dms_make: selectedModel.makecode,
dms_model: selectedModel.modelcode, dms_model: selectedModel.modelcode,
}); });
setVisible(false); setOpen(false);
}} }}
> >
{error && <AlertComponent error={error.message} />} {error && <AlertComponent error={error.message} />}
@@ -90,7 +90,7 @@ export function DmsCdkVehicles({ bodyshop, form, socket, job }) {
</Modal> </Modal>
<Button <Button
onClick={() => { onClick={() => {
setVisible(true); setOpen(true);
callSearch({ callSearch({
variables: { variables: {
search: job && job.v_model_desc && job.v_model_desc.substr(0, 3), search: job && job.v_model_desc && job.v_model_desc.substr(0, 3),

View File

@@ -21,29 +21,29 @@ export default connect(
export function DmsCustomerSelector({ bodyshop }) { export function DmsCustomerSelector({ bodyshop }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [customerList, setcustomerList] = useState([]); const [customerList, setcustomerList] = useState([]);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [selectedCustomer, setSelectedCustomer] = useState(null); const [selectedCustomer, setSelectedCustomer] = useState(null);
const [dmsType, setDmsType] = useState("cdk"); const [dmsType, setDmsType] = useState("cdk");
socket.on("cdk-select-customer", (customerList, callback) => { socket.on("cdk-select-customer", (customerList, callback) => {
setVisible(true); setOpen(true);
setDmsType("cdk"); setDmsType("cdk");
setcustomerList(customerList); setcustomerList(customerList);
}); });
socket.on("pbs-select-customer", (customerList, callback) => { socket.on("pbs-select-customer", (customerList, callback) => {
setVisible(true); setOpen(true);
setDmsType("pbs"); setDmsType("pbs");
setcustomerList(customerList); setcustomerList(customerList);
}); });
const onUseSelected = () => { const onUseSelected = () => {
setVisible(false); setOpen(false);
socket.emit(`${dmsType}-selected-customer`, selectedCustomer); socket.emit(`${dmsType}-selected-customer`, selectedCustomer);
setSelectedCustomer(null); setSelectedCustomer(null);
}; };
const onUseGeneric = () => { const onUseGeneric = () => {
setVisible(false); setOpen(false);
socket.emit( socket.emit(
`${dmsType}-selected-customer`, `${dmsType}-selected-customer`,
bodyshop.cdk_configuration.generic_customer_number bodyshop.cdk_configuration.generic_customer_number
@@ -52,7 +52,7 @@ export function DmsCustomerSelector({ bodyshop }) {
}; };
const onCreateNew = () => { const onCreateNew = () => {
setVisible(false); setOpen(false);
socket.emit(`${dmsType}-selected-customer`, null); socket.emit(`${dmsType}-selected-customer`, null);
setSelectedCustomer(null); setSelectedCustomer(null);
}; };
@@ -114,7 +114,7 @@ export function DmsCustomerSelector({ bodyshop }) {
}, },
]; ];
if (!visible) return null; if (!open) return null;
return ( return (
<Col span={24}> <Col span={24}>
<Table <Table

View File

@@ -186,7 +186,6 @@ export function EmailOverlayContainer({
okText={t("general.actions.send")} okText={t("general.actions.send")}
okButtonProps={{ okButtonProps={{
loading: sending, loading: sending,
disabled: disabled:
selectedMedia && selectedMedia &&
(selectedMedia (selectedMedia

View File

@@ -16,15 +16,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(FormDatePicker);
const dateFormat = "MM/DD/YYYY"; const dateFormat = "MM/DD/YYYY";
export function FormDatePicker({ export function FormDatePicker({bodyshop, value, onChange, onBlur, onlyFuture, isDateOnly = true, ...restProps }) {
bodyshop,
value,
onChange,
onBlur,
onlyFuture,
isDateOnly = true,
...restProps
}) {
const ref = useRef(); const ref = useRef();
const handleChange = (newDate) => { const handleChange = (newDate) => {

View File

@@ -13,6 +13,7 @@ import Icon, {
FileFilled, FileFilled,
HomeFilled, HomeFilled,
ImportOutlined, ImportOutlined,
InfoCircleOutlined,
LineChartOutlined, LineChartOutlined,
PaperClipOutlined, PaperClipOutlined,
PhoneOutlined, PhoneOutlined,
@@ -25,8 +26,8 @@ import Icon, {
UserOutlined, UserOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import {useSplitTreatments} from "@splitsoftware/splitio-react"; import {useSplitTreatments} from "@splitsoftware/splitio-react";
import {Layout, Menu} from "antd"; import {Layout, Menu, Switch, Tooltip} from "antd";
import React from "react"; import React, {useEffect, useState} from "react";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
import {BsKanban} from "react-icons/bs"; import {BsKanban} from "react-icons/bs";
import {FaCalendarAlt, FaCarCrash, FaCreditCard, FaFileInvoiceDollar,} from "react-icons/fa"; import {FaCalendarAlt, FaCarCrash, FaCreditCard, FaFileInvoiceDollar,} from "react-icons/fa";
@@ -41,6 +42,7 @@ import {setModalContext} from "../../redux/modals/modals.actions";
import {signOutStart} from "../../redux/user/user.actions"; import {signOutStart} from "../../redux/user/user.actions";
import {selectBodyshop, selectCurrentUser,} from "../../redux/user/user.selectors"; import {selectBodyshop, selectCurrentUser,} from "../../redux/user/user.selectors";
import {FiLogOut} from "react-icons/fi"; import {FiLogOut} from "react-icons/fi";
import handleBeta, {checkBeta, setBeta} from "../../utils/betaHandler";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser, currentUser: selectCurrentUser,
@@ -63,16 +65,40 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(setModalContext({context: context, modal: "cardPayment"})), dispatch(setModalContext({context: context, modal: "cardPayment"})),
}); });
function Header({handleMenuClick, currentUser, bodyshop, selectedHeader, signOutStart, setBillEnterContext, setTimeTicketContext, setPaymentContext, setReportCenterContext, recentItems, setCardPaymentContext}) { function Header({
handleMenuClick,
currentUser,
bodyshop,
selectedHeader,
signOutStart,
setBillEnterContext,
setTimeTicketContext,
setPaymentContext,
setReportCenterContext,
recentItems,
setCardPaymentContext
}) {
const {treatments: {ImEXPay, DmsAp, Simple_Inventory}} = useSplitTreatments({ const {treatments: {ImEXPay, DmsAp, Simple_Inventory}} = useSplitTreatments({
attributes: {}, attributes: {},
names: ["ImEXPay", "DmsAp", "Simple_Inventory"], names: ["ImEXPay", "DmsAp", "Simple_Inventory"],
splitKey: bodyshop && bodyshop.imexshopid, splitKey: bodyshop && bodyshop.imexshopid,
}); });
const [betaSwitch, setBetaSwitch] = useState(false);
const {t} = useTranslation(); const {t} = useTranslation();
useEffect(() => {
const isBeta = checkBeta();
setBetaSwitch(isBeta);
}, []);
const betaSwitchChange = (checked) => {
setBeta(checked);
setBetaSwitch(checked);
handleBeta();
}
const accountingChildren = [ const accountingChildren = [
{ {
key: 'bills', key: 'bills',
@@ -173,7 +199,7 @@ function Header({handleMenuClick, currentUser, bodyshop, selectedHeader, signOut
{ {
key: 'receivables', key: 'receivables',
label: (<Link to="/manage/accounting/receivables">{t("menus.header.accounting-receivables")}</Link>) label: (<Link to="/manage/accounting/receivables">{t("menus.header.accounting-receivables")}</Link>)
} },
] ]
if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber)) || DmsAp.treatment === "on") { if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber)) || DmsAp.treatment === "on") {
@@ -193,17 +219,20 @@ function Header({handleMenuClick, currentUser, bodyshop, selectedHeader, signOut
}); });
} }
accountingExportChildren.push( accountingExportChildren.push({
{ type: 'divider',
key: 'exportlogs', }, {
label: (<Link to="/manage/accounting/exportlogs">{t("menus.header.export-logs")}</Link>) key: 'exportlogs',
}, label: (<Link to="/manage/accounting/exportlogs">{t("menus.header.export-logs")}</Link>)
});
accountingChildren.push(
{ {
key: 'accountingexport', key: 'accountingexport',
icon: <ExportOutlined/>, icon: <ExportOutlined/>,
label: t("menus.header.export"), label: t("menus.header.export"),
children: accountingExportChildren children: accountingExportChildren
} },
); );
const menuItems = [ const menuItems = [
@@ -255,6 +284,9 @@ function Header({handleMenuClick, currentUser, bodyshop, selectedHeader, signOut
icon: <UnorderedListOutlined/>, icon: <UnorderedListOutlined/>,
label: (<Link to="/manage/jobs/all">{t("menus.header.alljobs")}</Link>) label: (<Link to="/manage/jobs/all">{t("menus.header.alljobs")}</Link>)
}, },
{
type: 'divider',
},
{ {
key: 'productionlist', key: 'productionlist',
icon: <ScheduleOutlined/>, icon: <ScheduleOutlined/>,
@@ -448,13 +480,28 @@ function Header({handleMenuClick, currentUser, bodyshop, selectedHeader, signOut
})), })),
} }
] ];
menuItems.push({
key: 'beta-switch',
style: {marginLeft: 'auto'},
label: (
<Tooltip title="A faster more modern ImEX Online is ready for you to try! You can switch back at any time.">
<InfoCircleOutlined/>
<span style={{marginRight: 8}}>Try the new ImEX Online</span>
<Switch
checked={betaSwitch}
onChange={betaSwitchChange}
/>
</Tooltip>
)
});
return ( return (
<Layout.Header> <Layout.Header>
<Menu <Menu
mode="horizontal" mode="horizontal"
//theme="light"
theme={"dark"} theme={"dark"}
selectedKeys={[selectedHeader]} selectedKeys={[selectedHeader]}
onClick={handleMenuClick} onClick={handleMenuClick}

View File

@@ -36,7 +36,7 @@ export function InventoryUpsertModalContainer({
const [insertInventory] = useMutation(INSERT_INVENTORY_LINE); const [insertInventory] = useMutation(INSERT_INVENTORY_LINE);
const [updateInventoryLine] = useMutation(UPDATE_INVENTORY_LINE); const [updateInventoryLine] = useMutation(UPDATE_INVENTORY_LINE);
const { visible, context, actions } = inventoryUpsertModal; const { open, context, actions } = inventoryUpsertModal;
const { existingInventory } = context; const { existingInventory } = context;
const { refetch } = actions; const { refetch } = actions;
@@ -44,12 +44,12 @@ export function InventoryUpsertModalContainer({
useEffect(() => { useEffect(() => {
//Required to prevent infinite looping. //Required to prevent infinite looping.
if (existingInventory && visible) { if (existingInventory && open) {
form.setFieldsValue(existingInventory); form.setFieldsValue(existingInventory);
} else if (!existingInventory && visible) { } else if (!existingInventory && open) {
form.resetFields(); form.resetFields();
} }
}, [existingInventory, form, visible]); }, [existingInventory, form, open]);
const handleFinish = async (formValues) => { const handleFinish = async (formValues) => {
const values = formValues; const values = formValues;
@@ -103,7 +103,7 @@ export function InventoryUpsertModalContainer({
? t("inventory.actions.edit") ? t("inventory.actions.edit")
: t("inventory.actions.new") : t("inventory.actions.new")
} }
open={visible} open={open}
okText={t("general.actions.save")} okText={t("general.actions.save")}
onOk={() => { onOk={() => {
form.submit(); form.submit();

View File

@@ -57,7 +57,7 @@ export function ScheduleEventComponent({
setScheduleContext, setScheduleContext,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const history = useNavigate(); const history = useNavigate();
const searchParams = queryString.parse(useLocation().search); const searchParams = queryString.parse(useLocation().search);
const [updateAppointment] = useMutation(UPDATE_APPOINTMENT); const [updateAppointment] = useMutation(UPDATE_APPOINTMENT);
@@ -223,7 +223,7 @@ export function ScheduleEventComponent({
time: dayjs(event.start).format("HH:mm a"), time: dayjs(event.start).format("HH:mm a"),
}) })
); );
setVisible(false); setOpen(false);
} else { } else {
notification["error"]({ notification["error"]({
message: t("messaging.error.invalidphone"), message: t("messaging.error.invalidphone"),
@@ -290,7 +290,7 @@ export function ScheduleEventComponent({
<Button <Button
disabled={event.arrived} disabled={event.arrived}
onClick={() => { onClick={() => {
setVisible(false); setOpen(false);
setScheduleContext({ setScheduleContext({
actions: { refetch: refetch }, actions: { refetch: refetch },
context: { context: {
@@ -366,8 +366,8 @@ export function ScheduleEventComponent({
return ( return (
<Popover <Popover
open={visible} open={open}
onOpenChange={(vis) => !event.vacation && setVisible(vis)} onOpenChange={(vis) => !event.vacation && setOpen(vis)}
trigger="click" trigger="click"
content={event.block ? blockContent : popoverContent} content={event.block ? blockContent : popoverContent}
style={{ style={{

View File

@@ -53,7 +53,7 @@ export function ScheduleEventNote({ event }) {
return ( return (
<DataLabel label={t("appointments.fields.note")}> <DataLabel label={t("appointments.fields.note")}>
<Space flex> <Space>
{!editing ? ( {!editing ? (
event.note || "" event.note || ""
) : ( ) : (

View File

@@ -23,23 +23,23 @@ export function JobCostingModalContainer({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [costingData, setCostingData] = useState(null); const [costingData, setCostingData] = useState(null);
const { visible, context } = jobCostingModal; const { open, context } = jobCostingModal;
const { jobId } = context; const { jobId } = context;
useEffect(() => { useEffect(() => {
async function getData() { async function getData() {
if (jobId && visible) { if (jobId && open) {
const { data } = await axios.post("/job/costing", { jobid: jobId }); const { data } = await axios.post("/job/costing", { jobid: jobId });
setCostingData(data); setCostingData(data);
} }
} }
getData(); getData();
}, [jobId, visible]); }, [jobId, open]);
return ( return (
<Modal <Modal
open={visible} open={open}
title={t("jobs.labels.jobcosting")} title={t("jobs.labels.jobcosting")}
onOk={() => { onOk={() => {
toggleModalVisible(); toggleModalVisible();

View File

@@ -17,7 +17,7 @@ export default function JobDetailCardsInsuranceComponent({ loading, data }) {
</DataLabel> </DataLabel>
<DataLabel <DataLabel
label={t("jobs.labels.cards.filehandler")} label={t("jobs.labels.cards.filehandler")}
visible={data.ins_ct_fn && data.ins_ct_ln}> open={data.ins_ct_fn && data.ins_ct_ln}>
{data.ins_ea ? ( {data.ins_ea ? (
<a href={`mailto:${data.ins_ea}`}> <a href={`mailto:${data.ins_ea}`}>
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div> <div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
@@ -28,7 +28,7 @@ export default function JobDetailCardsInsuranceComponent({ loading, data }) {
</DataLabel> </DataLabel>
<DataLabel <DataLabel
label={t("jobs.labels.cards.estimator")} label={t("jobs.labels.cards.estimator")}
visible={data.est_ct_fn && data.est_ct_ln}> open={data.est_ct_fn && data.est_ct_ln}>
{data.ins_ea ? ( {data.ins_ea ? (
<a href={`mailto:${data.est_ea}`}> <a href={`mailto:${data.est_ea}`}>
<div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div> <div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div>

View File

@@ -22,7 +22,7 @@ export default connect(
export function JobLinesUpsertModalComponent({ export function JobLinesUpsertModalComponent({
bodyshop, bodyshop,
visible, open,
jobLine, jobLine,
handleCancel, handleCancel,
handleFinish, handleFinish,
@@ -33,7 +33,7 @@ export function JobLinesUpsertModalComponent({
useEffect(() => { useEffect(() => {
form.resetFields(); form.resetFields();
}, [visible, form]); }, [open, form]);
const { treatments: {Allow_Negative_Jobline_Price, Autohouse_Detail_line} } = useSplitTreatments({ const { treatments: {Allow_Negative_Jobline_Price, Autohouse_Detail_line} } = useSplitTreatments({
@@ -50,7 +50,7 @@ export function JobLinesUpsertModalComponent({
: t("joblines.labels.new") : t("joblines.labels.new")
} }
forceRender forceRender
open={visible} open={open}
width="60%" width="60%"
okText={t("general.actions.save")} okText={t("general.actions.save")}
onOk={() => form.submit()} onOk={() => form.submit()}

View File

@@ -133,7 +133,7 @@ function JobLinesUpsertModalContainer({
return ( return (
<JobLinesUpdsertModal <JobLinesUpdsertModal
visible={jobLineEditModal.visible} open={jobLineEditModal.open}
jobLine={jobLineEditModal.context} jobLine={jobLineEditModal.context}
handleFinish={handleFinish} handleFinish={handleFinish}
handleCancel={handleCancel} handleCancel={handleCancel}

View File

@@ -24,12 +24,12 @@ function JobReconciliationModalContainer({
toggleModalVisible, toggleModalVisible,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { context, visible } = reconciliationModal; const { context, open } = reconciliationModal;
const { job } = context; const { job } = context;
const { loading, error, data } = useQuery(GET_JOB_RECONCILIATION_BY_PK, { const { loading, error, data } = useQuery(GET_JOB_RECONCILIATION_BY_PK, {
variables: { id: job && job.id }, variables: { id: job && job.id },
skip: !(job && job.id) || !visible, skip: !(job && job.id) || !open,
fetchPolicy: "network-only", fetchPolicy: "network-only",
nextFetchPolicy: "network-only", nextFetchPolicy: "network-only",
}); });
@@ -42,7 +42,7 @@ function JobReconciliationModalContainer({
<Modal <Modal
title={t("jobs.labels.reconciliationheader")} title={t("jobs.labels.reconciliationheader")}
width={"95%"} width={"95%"}
open={visible} open={open}
okText={t("general.actions.close")} okText={t("general.actions.close")}
onOk={handleCancel} onOk={handleCancel}
onCancel={handleCancel} onCancel={handleCancel}

View File

@@ -69,8 +69,9 @@ export function JobsAdminDatesChange({ insertAuditTrail, job }) {
}), }),
}); });
} }
form.resetFields(); form.resetFields();
form.resetFields();
setLoading(false); setLoading(false);
//Get the owner details, populate it all back into the job. //Get the owner details, populate it all back into the job.
}; };

View File

@@ -379,7 +379,7 @@ export function JobsAvailableContainer({bodyshop, currentUser, insertAuditTrail,
setPartsQueueToggle={setPartsQueueToggle} setPartsQueueToggle={setPartsQueueToggle}
selectedOwner={selectedOwner} selectedOwner={selectedOwner}
setSelectedOwner={setSelectedOwner} setSelectedOwner={setSelectedOwner}
visible={ownerModalVisible} open={ownerModalVisible}
onOk={onOwnerFindModalOk} onOk={onOwnerFindModalOk}
onCancel={onOwnerModalCancel} onCancel={onOwnerModalCancel}
@@ -390,7 +390,7 @@ export function JobsAvailableContainer({bodyshop, currentUser, insertAuditTrail,
selectedJob={selectedJob} selectedJob={selectedJob}
setSelectedJob={setSelectedJob} setSelectedJob={setSelectedJob}
importOptionsState={importOptionsState} importOptionsState={importOptionsState}
visible={jobModalVisible} open={jobModalVisible}
onOk={onJobFindModalOk} onOk={onJobFindModalOk}
onCancel={onJobModalCancel} onCancel={onJobModalCancel}
modalSearchState={modalSearchState} modalSearchState={modalSearchState}

View File

@@ -62,13 +62,15 @@ export function JobsCloseAutoAllocate({ bodyshop, joblines, form, disabled }) {
); );
}; };
const menu = { const menu =bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? {
items: bodyshop.md_responsibility_centers.dms_defaults.map((mapping) => ({ items: bodyshop.md_responsibility_centers.dms_defaults.map((mapping) => ({
key: mapping.name, key: mapping.name,
label: mapping.name, label: mapping.name,
disabled: disabled, disabled: disabled,
})), })),
onClick: handleMenuClick, onClick: handleMenuClick,
} : {
items: []
} }
return bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? ( return bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber ? (

View File

@@ -37,7 +37,7 @@ export function JobsConvertButton({
insertAuditTrail, insertAuditTrail,
parentFormIsFieldsTouched, parentFormIsFieldsTouched,
}) { }) {
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO); const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO);
const { t } = useTranslation(); const { t } = useTranslation();
@@ -80,7 +80,7 @@ export function JobsConvertButton({
), ),
}); });
setVisible(false); setOpen(false);
} }
setLoading(false); setLoading(false);
}; };
@@ -243,10 +243,10 @@ export function JobsConvertButton({
<Switch /> <Switch />
</Form.Item> </Form.Item>
<Space wrap> <Space wrap>
<Button type="danger" onClick={() => form.submit()} loading={loading}> <Button type="primary" danger onClick={() => form.submit()} loading={loading}>
{t("jobs.actions.convert")} {t("jobs.actions.convert")}
</Button> </Button>
<Button onClick={() => setVisible(false)}> <Button onClick={() => setOpen(false)}>
{t("general.actions.close")} {t("general.actions.close")}
</Button> </Button>
</Space> </Space>
@@ -257,15 +257,16 @@ export function JobsConvertButton({
if (job.converted) return <></>; if (job.converted) return <></>;
return ( return (
<Popover open={visible} content={popMenu}> <Popover open={open} content={popMenu}>
<Button <Button
key="convert" key="convert"
type="danger" type="primary"
danger
// style={{ display: job.converted ? "none" : "" }} // style={{ display: job.converted ? "none" : "" }}
disabled={job.converted || jobRO} disabled={job.converted || jobRO}
loading={loading} loading={loading}
onClick={() => { onClick={() => {
setVisible(true); setOpen(true);
form.setFieldsValue({ form.setFieldsValue({
driveable: true, driveable: true,
towin: false, towin: false,

View File

@@ -1,6 +1,6 @@
import {DownCircleFilled} from "@ant-design/icons"; import {DownCircleFilled} from "@ant-design/icons";
import {useApolloClient, useMutation} from "@apollo/client"; import {useApolloClient, useMutation} from "@apollo/client";
import {Button, Card, Dropdown, Form, Input, notification, Popconfirm, Popover, Select, Space,} from "antd"; import {Button, Card, Dropdown, Form, Input, Modal, notification, Popconfirm, Popover, Select, Space,} from "antd";
import React, {useMemo, useState} from "react"; import React, {useMemo, useState} from "react";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
import {connect} from "react-redux"; import {connect} from "react-redux";
@@ -77,6 +77,7 @@ export function JobsDetailHeaderActions({
const history = useNavigate(); const history = useNavigate();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isCancelScheduleModalVisible, setIsCancelScheduleModalVisible] = useState(false);
const [insertAppointment] = useMutation(INSERT_MANUAL_APPT); const [insertAppointment] = useMutation(INSERT_MANUAL_APPT);
const [deleteJob] = useMutation(DELETE_JOB); const [deleteJob] = useMutation(DELETE_JOB);
const [insertCsi] = useMutation(INSERT_CSI); const [insertCsi] = useMutation(INSERT_CSI);
@@ -106,6 +107,17 @@ export function JobsDetailHeaderActions({
); );
}, [job.status, bodyshop.md_ro_statuses.post_production_statuses]); }, [job.status, bodyshop.md_ro_statuses.post_production_statuses]);
// Function to show modal
const showCancelScheduleModal = () => {
setIsCancelScheduleModalVisible(true);
};
// Function to handle Cancel
const handleCancelScheduleModalCancel = () => {
setIsCancelScheduleModalVisible(false);
};
const handleDuplicate = () => const handleDuplicate = () =>
DuplicateJob( DuplicateJob(
client, client,
@@ -149,7 +161,6 @@ export function JobsDetailHeaderActions({
message: t("appointments.successes.created"), message: t("appointments.successes.created"),
}); });
} catch (error) { } catch (error) {
console.log(error);
} finally { } finally {
setLoading(false); setLoading(false);
setVisibility(false); setVisibility(false);
@@ -459,6 +470,13 @@ export function JobsDetailHeaderActions({
}); });
}; };
// Function to handle OK
const handleCancelScheduleOK = async () => {
await form.submit(); // Assuming 'form' is the Form instance from useForm()
setIsCancelScheduleModalVisible(false);
};
const handleLostSaleFinish = async ({lost_sale_reason}) => { const handleLostSaleFinish = async ({lost_sale_reason}) => {
const jobUpdate = await cancelAllAppointments({ const jobUpdate = await cancelAllAppointments({
variables: { variables: {
@@ -588,6 +606,7 @@ export function JobsDetailHeaderActions({
const menuItems = [ const menuItems = [
{ {
key: 'schedule',
disabled: !jobInPreProduction || !job.converted || jobRO, disabled: !jobInPreProduction || !job.converted || jobRO,
label: t("jobs.actions.schedule"), label: t("jobs.actions.schedule"),
onClick: () => { onClick: () => {
@@ -603,51 +622,18 @@ export function JobsDetailHeaderActions({
}, },
}, },
{ {
key: 'cancelallappointments',
onClick: () => {
if ( job.status !== bodyshop.md_ro_statuses.default_scheduled) {
return;
}
showCancelScheduleModal()
},
disabled: job.status !== bodyshop.md_ro_statuses.default_scheduled, disabled: job.status !== bodyshop.md_ro_statuses.default_scheduled,
label: job.status !== bodyshop.md_ro_statuses.default_scheduled ? ( label: t("menus.jobsactions.cancelallappointments")
t("menus.jobsactions.cancelallappointments")
) : (
<Popover
trigger="click"
disabled={job.status !== bodyshop.md_ro_statuses.default_scheduled}
content={
<Form
layout="vertical"
onFinish={handleLostSaleFinish}
>
<Form.Item
name="lost_sale_reason"
label={t("jobs.fields.lost_sale_reason")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
label: lsr,
value: lsr,
}))}
/>
</Form.Item>
<Button
htmlType="submit"
disabled={
job.status !== bodyshop.md_ro_statuses.default_scheduled
}
>
{t("appointments.actions.cancel")}
</Button>
</Form>
}
>
{t("menus.jobsactions.cancelallappointments")}
</Popover>
)
}, },
{ {
key: 'intake',
disabled: !!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO, disabled: !!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO,
label: !!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO ? ( label: !!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO ? (
t("jobs.actions.intake") t("jobs.actions.intake")
@@ -658,6 +644,7 @@ export function JobsDetailHeaderActions({
) )
}, },
{ {
key: 'deliver',
disabled: !jobInProduction || jobRO, disabled: !jobInProduction || jobRO,
label: !jobInProduction ? ( label: !jobInProduction ? (
t("jobs.actions.deliver") t("jobs.actions.deliver")
@@ -668,6 +655,7 @@ export function JobsDetailHeaderActions({
) )
}, },
{ {
key: 'checklist',
disabled: !job.converted, disabled: !job.converted,
label: <Link to={`/manage/jobs/${job.id}/checklist`}> label: <Link to={`/manage/jobs/${job.id}/checklist`}>
{t("jobs.actions.viewchecklist")} {t("jobs.actions.viewchecklist")}
@@ -771,6 +759,7 @@ export function JobsDetailHeaderActions({
label: t("menus.jobsactions.duplicate"), label: t("menus.jobsactions.duplicate"),
children: [ children: [
{ {
key: 'duplicate',
label: <Popconfirm label: <Popconfirm
title={t("jobs.labels.duplicateconfirm")} title={t("jobs.labels.duplicateconfirm")}
okText="Yes" okText="Yes"
@@ -783,6 +772,7 @@ export function JobsDetailHeaderActions({
</Popconfirm> </Popconfirm>
}, },
{ {
key: 'duplicatenolines',
label: <Popconfirm label: <Popconfirm
title={t("jobs.labels.duplicateconfirm")} title={t("jobs.labels.duplicateconfirm")}
okText="Yes" okText="Yes"
@@ -949,13 +939,13 @@ export function JobsDetailHeaderActions({
if (job && !job.converted) { if (job && !job.converted) {
menuItems.push( menuItems.push(
{ {
key: 'deletejob',
label: <Popconfirm label: <Popconfirm
title={t("jobs.labels.deleteconfirm")} title={t("jobs.labels.deleteconfirm")}
okText={t("general.labels.yes")} okText={t("general.labels.yes")}
cancelText={t("general.labels.no")} cancelText={t("general.labels.no")}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
onConfirm={handleDeleteJob} onConfirm={handleDeleteJob}
getPopupContainer={(trigger) => trigger.parentNode}
> >
{t("menus.jobsactions.deletejob")} {t("menus.jobsactions.deletejob")}
</Popconfirm> </Popconfirm>
@@ -965,6 +955,7 @@ export function JobsDetailHeaderActions({
menuItems.push( menuItems.push(
{ {
key: 'manualevent',
onClick: (e) => { onClick: (e) => {
setVisibility(true); setVisibility(true);
}, },
@@ -974,6 +965,7 @@ export function JobsDetailHeaderActions({
if (!jobRO && job.converted) { if (!jobRO && job.converted) {
menuItems.push({ menuItems.push({
key: 'voidjob',
label: <RbacWrapper action="jobs:void" noauth> label: <RbacWrapper action="jobs:void" noauth>
<Popconfirm <Popconfirm
title={t("jobs.labels.voidjob")} title={t("jobs.labels.voidjob")}
@@ -981,7 +973,6 @@ export function JobsDetailHeaderActions({
cancelText="No" cancelText="No"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
onConfirm={handleVoidJob} onConfirm={handleVoidJob}
getPopupContainer={(trigger) => trigger.parentNode}
> >
{t("menus.jobsactions.void")} {t("menus.jobsactions.void")}
</Popconfirm> </Popconfirm>
@@ -996,6 +987,47 @@ export function JobsDetailHeaderActions({
return ( return (
<> <>
<Modal
title={t("menus.jobsactions.cancelallappointments")}
open={isCancelScheduleModalVisible}
onOk={handleCancelScheduleOK}
onCancel={handleCancelScheduleModalCancel}
footer={[
<Button form="cancelScheduleForm" key="back" onClick={handleCancelScheduleModalCancel}>
{t("general.actions.cancel")}
</Button>,
<Button form="cancelScheduleForm" htmlType="submit" key="submit" type="primary" loading={loading} onClick={handleCancelScheduleOK}>
{t("appointments.actions.cancel")}
</Button>,
]}
>
<Form
layout="vertical"
id="cancelScheduleForm"
onFinish={s =>{
console.log(s);
handleLostSaleFinish(s);
}}
>
<Form.Item
name="lost_sale_reason"
label={t("jobs.fields.lost_sale_reason")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={bodyshop.md_lost_sale_reasons.map((lsr) => ({
label: lsr,
value: lsr,
}))}
/>
</Form.Item>
</Form>
</Modal>
<Dropdown menu={menu} trigger={["click"]} key="changestatus"> <Dropdown menu={menu} trigger={["click"]} key="changestatus">
<Button> <Button>
<span>{t("general.labels.actions")}</span> <span>{t("general.labels.actions")}</span>

View File

@@ -35,7 +35,7 @@ export function JobsDocumentsGalleryReassign({
]; ];
}, [galleryImages]); }, [galleryImages]);
const client = useApolloClient(); const client = useApolloClient();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
// const updateImage = async (i, jobid) => { // const updateImage = async (i, jobid) => {
@@ -126,7 +126,7 @@ export function JobsDocumentsGalleryReassign({
message: t("documents.successes.updated"), message: t("documents.successes.updated"),
}); });
} }
setVisible(false); setOpen(false);
setLoading(false); setLoading(false);
}; };
@@ -151,7 +151,7 @@ export function JobsDocumentsGalleryReassign({
<Button type="primary" onClick={() => form.submit()}> <Button type="primary" onClick={() => form.submit()}>
{t("general.actions.submit")} {t("general.actions.submit")}
</Button> </Button>
<Button onClick={() => setVisible(false)}> <Button onClick={() => setOpen(false)}>
{t("general.actions.cancel")} {t("general.actions.cancel")}
</Button> </Button>
</Space> </Space>
@@ -159,10 +159,10 @@ export function JobsDocumentsGalleryReassign({
); );
return ( return (
<Popover content={popContent} open={visible}> <Popover content={popContent} open={open}>
<Button <Button
disabled={selectedImages.length < 1} disabled={selectedImages.length < 1}
onClick={() => setVisible(true)} onClick={() => setOpen(true)}
loading={loading} loading={loading}
> >
{t("documents.actions.reassign")} {t("documents.actions.reassign")}

View File

@@ -32,7 +32,7 @@ export function JobsDocumentsLocalGalleryReassign({
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const handleFinish = async ({ jobid: newJobid }) => { const handleFinish = async ({ jobid: newJobid }) => {
@@ -50,7 +50,7 @@ export function JobsDocumentsLocalGalleryReassign({
); );
getJobMedia(jobid); getJobMedia(jobid);
setVisible(false); setOpen(false);
setLoading(false); setLoading(false);
}; };
@@ -75,7 +75,7 @@ export function JobsDocumentsLocalGalleryReassign({
<Button type="primary" onClick={() => form.submit()}> <Button type="primary" onClick={() => form.submit()}>
{t("general.actions.submit")} {t("general.actions.submit")}
</Button> </Button>
<Button onClick={() => setVisible(false)}> <Button onClick={() => setOpen(false)}>
{t("general.actions.cancel")} {t("general.actions.cancel")}
</Button> </Button>
</Space> </Space>
@@ -83,10 +83,10 @@ export function JobsDocumentsLocalGalleryReassign({
); );
return ( return (
<Popover content={popContent} open={visible}> <Popover content={popContent} open={open}>
<Button <Button
//disabled={selectedImages.length < 1} //disabled={selectedImages.length < 1}
onClick={() => setVisible(true)} onClick={() => setOpen(true)}
loading={loading} loading={loading}
> >
{t("documents.actions.reassign")} {t("documents.actions.reassign")}

View File

@@ -1,102 +1,90 @@
import { useQuery } from "@apollo/client"; import {useQuery} from "@apollo/client";
import { Modal } from "antd"; import {Modal} from "antd";
import React from "react"; import React 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";
import { QUERY_ALL_ACTIVE_JOBS } from "../../graphql/jobs.queries"; import {QUERY_ALL_ACTIVE_JOBS} from "../../graphql/jobs.queries";
import { selectBodyshop } from "../../redux/user/user.selectors"; import {selectBodyshop} from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import JobsFindModalComponent from "./jobs-find-modal.component"; import JobsFindModalComponent from "./jobs-find-modal.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
export default connect( export default connect(
mapStateToProps, mapStateToProps,
null null
)(function JobsFindModalContainer({ )(function JobsFindModalContainer({bodyshop, loading, error, selectedJob, setSelectedJob, importOptionsState, modalSearchState, partsQueueToggle, setPartsQueueToggle, ...modalProps }) {
bodyshop, const {t} = useTranslation();
loading,
error,
selectedJob,
setSelectedJob,
importOptionsState,
modalSearchState,
partsQueueToggle,
setPartsQueueToggle,
...modalProps
}) {
const { t } = useTranslation();
const jobsList = useQuery(QUERY_ALL_ACTIVE_JOBS, { const jobsList = useQuery(QUERY_ALL_ACTIVE_JOBS, {
variables: { variables: {
statuses: bodyshop.md_ro_statuses.active_statuses || ["Open"], statuses: bodyshop.md_ro_statuses.active_statuses || ["Open"],
}, },
skip: !modalProps.visible, skip: !modalProps.open,
fetchPolicy: "network-only", fetchPolicy: "network-only",
nextFetchPolicy: "network-only", nextFetchPolicy: "network-only",
}); });
const modalSearch = modalSearchState[0]; const modalSearch = modalSearchState[0];
const jobsData = const jobsData =
jobsList.data && jobsList.data.jobs jobsList.data && jobsList.data.jobs
? modalSearch ? modalSearch
? jobsList.data.jobs.filter( ? jobsList.data.jobs.filter(
(j) => (j) =>
(j.ro_number || "") (j.ro_number || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) || .includes(modalSearch.toLowerCase()) ||
(j.ownr_fn || "") (j.ownr_fn || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) || .includes(modalSearch.toLowerCase()) ||
(j.ownr_ln || "") (j.ownr_ln || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) || .includes(modalSearch.toLowerCase()) ||
(j.status || "") (j.status || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) || .includes(modalSearch.toLowerCase()) ||
(j.v_make_desc || "") (j.v_make_desc || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) || .includes(modalSearch.toLowerCase()) ||
(j.v_model_desc || "") (j.v_model_desc || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) || .includes(modalSearch.toLowerCase()) ||
(j.clm_no || "") (j.clm_no || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) || .includes(modalSearch.toLowerCase()) ||
(j.plate_no || "") (j.plate_no || "")
.toLowerCase() .toLowerCase()
.includes(modalSearch.toLowerCase()) .includes(modalSearch.toLowerCase())
) )
: jobsList.data.jobs : jobsList.data.jobs
: null; : null;
return ( return (
<Modal <Modal
title={t("jobs.labels.existing_jobs")} title={t("jobs.labels.existing_jobs")}
width={"80%"} width={"80%"}
destroyOnClose destroyOnClose
okButtonProps={{ disabled: selectedJob ? false : true }} okButtonProps={{disabled: selectedJob ? false : true}}
{...modalProps} {...modalProps}
> >
{loading ? <LoadingSpinner /> : null} {loading ? <LoadingSpinner/> : null}
{error ? <AlertComponent message={error.message} type="error" /> : null} {error ? <AlertComponent message={error.message} type="error"/> : null}
{true ? ( <JobsFindModalComponent
<JobsFindModalComponent selectedJob={selectedJob}
selectedJob={selectedJob} setSelectedJob={setSelectedJob}
setSelectedJob={setSelectedJob} importOptionsState={importOptionsState}
importOptionsState={importOptionsState} jobsListLoading={jobsList.loading}
jobsListLoading={jobsList.loading} jobsListRefetch={jobsList.refetch}
jobsListRefetch={jobsList.refetch} jobsList={jobsData}
jobsList={jobsData} modalSearchState={modalSearchState}
modalSearchState={modalSearchState} partsQueueToggle={partsQueueToggle}
partsQueueToggle={partsQueueToggle} setPartsQueueToggle={setPartsQueueToggle}
setPartsQueueToggle={setPartsQueueToggle} />
/> </Modal>
) : null} );
</Modal>
);
}); });

View File

@@ -37,7 +37,7 @@ export function LaborAllocationsAdjustmentEdit({
refetchQueryNames, refetchQueryNames,
}) { }) {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [updateAdjustments] = useMutation(UPDATE_JOB); const [updateAdjustments] = useMutation(UPDATE_JOB);
const [form] = Form.useForm(); const [form] = Form.useForm();
@@ -79,7 +79,7 @@ export function LaborAllocationsAdjustmentEdit({
}); });
} }
setLoading(false); setLoading(false);
setVisible(false); setOpen(false);
}; };
const overlay = ( const overlay = (
@@ -171,8 +171,8 @@ export function LaborAllocationsAdjustmentEdit({
return ( return (
<Popover <Popover
open={visible} open={open}
onOpenChange={(vis) => setVisible(vis)} onOpenChange={(vis) => setOpen(vis)}
content={overlay} content={overlay}
trigger="click" trigger="click"
> >

View File

@@ -33,7 +33,7 @@ export function NoteUpsertModalContainer({
const [insertNote] = useMutation(INSERT_NEW_NOTE); const [insertNote] = useMutation(INSERT_NEW_NOTE);
const [updateNote] = useMutation(UPDATE_NOTE); const [updateNote] = useMutation(UPDATE_NOTE);
const { visible, context, actions } = noteUpsertModal; const { open, context, actions } = noteUpsertModal;
const { jobId, existingNote, text } = context; const { jobId, existingNote, text } = context;
const { refetch } = actions; const { refetch } = actions;
@@ -41,16 +41,16 @@ export function NoteUpsertModalContainer({
useEffect(() => { useEffect(() => {
//Required to prevent infinite looping. //Required to prevent infinite looping.
if (existingNote && visible) { if (existingNote && open) {
form.setFieldsValue(existingNote); form.setFieldsValue(existingNote);
} else if (!existingNote && visible) { } else if (!existingNote && open) {
form.resetFields(); form.resetFields();
if (text) { if (text) {
form.setFieldValue("text", text); form.setFieldValue("text", text);
} }
} }
}, [existingNote, form, visible, text]); }, [existingNote, form, open, text]);
const handleFinish = async (formValues) => { const handleFinish = async (formValues) => {
const { relatedros, ...values } = formValues; const { relatedros, ...values } = formValues;
@@ -122,7 +122,7 @@ export function NoteUpsertModalContainer({
return ( return (
<Modal <Modal
title={existingNote ? t("notes.actions.edit") : t("notes.actions.new")} title={existingNote ? t("notes.actions.edit") : t("notes.actions.new")}
open={visible} open={open}
okText={t("general.actions.save")} okText={t("general.actions.save")}
onOk={() => { onOk={() => {
form.submit(); form.submit();

View File

@@ -76,7 +76,8 @@ function OwnerDetailFormContainer({ owner, refetch }) {
title={t("owners.labels.deleteconfirm")} title={t("owners.labels.deleteconfirm")}
> >
<Button <Button
type="danger" type="primary"
danger
loading={loading} loading={loading}
disabled={owner.jobs.length !== 0} disabled={owner.jobs.length !== 0}
> >

View File

@@ -32,13 +32,13 @@ export default function OwnerFindModalContainer({
); );
useEffect(() => { useEffect(() => {
if (modalProps.visible && owner) { if (modalProps.open && owner) {
const s = OwnerNameDisplayFunction(owner, true); const s = OwnerNameDisplayFunction(owner, true);
setSearchText(s.trim()); setSearchText(s.trim());
callSearchowners({ variables: { search: s.trim() } }); callSearchowners({ variables: { search: s.trim() } });
} }
}, [callSearchowners, modalProps.visible, owner]); }, [callSearchowners, modalProps.open, owner]);
return ( return (
<Modal <Modal

View File

@@ -50,7 +50,7 @@ export function PartsOrderModalContainer({partsOrderModal,toggleModalVisible,cur
splitKey: bodyshop.imexshopid, splitKey: bodyshop.imexshopid,
}); });
const {visible, context, actions} = partsOrderModal; const {open, context, actions} = partsOrderModal;
const { const {
jobId, jobId,
linesToOrder, linesToOrder,
@@ -68,7 +68,7 @@ export function PartsOrderModalContainer({partsOrderModal,toggleModalVisible,cur
const sendType = sendTypeState[0]; const sendType = sendTypeState[0];
const {loading, error, data} = useQuery(QUERY_ALL_VENDORS_FOR_ORDER, { const {loading, error, data} = useQuery(QUERY_ALL_VENDORS_FOR_ORDER, {
skip: !visible, skip: !open,
variables: {jobId: jobId}, variables: {jobId: jobId},
fetchPolicy: "network-only", fetchPolicy: "network-only",
nextFetchPolicy: "network-only", nextFetchPolicy: "network-only",
@@ -328,14 +328,14 @@ export function PartsOrderModalContainer({partsOrderModal,toggleModalVisible,cur
}; };
useEffect(() => { useEffect(() => {
if (visible && !!linesToOrder) { if (open && !!linesToOrder) {
form.resetFields(); form.resetFields();
} }
}, [visible, linesToOrder, form]); }, [open, linesToOrder, form]);
return ( return (
<Modal <Modal
open={visible} open={open}
title={ title={
isReturn isReturn
? `${t("parts_orders.labels.returnpartsorder")} ${invoiceNumber}` ? `${t("parts_orders.labels.returnpartsorder")} ${invoiceNumber}`

View File

@@ -32,7 +32,7 @@ export function PartsReceiveModalContainer({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { visible, context, actions } = partsReceiveModal; const { open, context, actions } = partsReceiveModal;
const { partsorderlines } = context; const { partsorderlines } = context;
const { refetch } = actions; const { refetch } = actions;
@@ -85,14 +85,14 @@ export function PartsReceiveModalContainer({
}; };
useEffect(() => { useEffect(() => {
if (visible && !!partsorderlines) { if (open && !!partsorderlines) {
form.resetFields(); form.resetFields();
} }
}, [visible, partsorderlines, form]); }, [open, partsorderlines, form]);
return ( return (
<Modal <Modal
open={visible} open={open}
title={t("parts_orders.labels.receive")} title={t("parts_orders.labels.receive")}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}
onOk={() => form.submit()} onOk={() => form.submit()}

View File

@@ -34,7 +34,7 @@ export function BillMarkSelectedExported({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
const [updateBill] = useMutation(gql` const [updateBill] = useMutation(gql`
mutation UPDATE_BILL($billIds: [uuid!]!) { mutation UPDATE_BILL($billIds: [uuid!]!) {
@@ -85,21 +85,21 @@ export function BillMarkSelectedExported({
completedCallback && completedCallback([]); completedCallback && completedCallback([]);
setLoading(false); setLoading(false);
refetch && refetch(); refetch && refetch();
setVisible(false); setOpen(false);
}; };
return ( return (
<Popconfirm <Popconfirm
open={visible} open={open}
title={t("general.labels.areyousure")} title={t("general.labels.areyousure")}
onCancel={() => setVisible(false)} onCancel={() => setOpen(false)}
onConfirm={handleUpdate} onConfirm={handleUpdate}
disabled={disabled} disabled={disabled}
> >
<Button <Button
loading={loading} loading={loading}
disabled={disabled} disabled={disabled}
onClick={() => setVisible(true)} onClick={() => setOpen(true)}
> >
{t("bills.labels.markexported")} {t("bills.labels.markexported")}
</Button> </Button>

View File

@@ -34,7 +34,7 @@ export function PaymentMarkSelectedExported({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
const [updatePayments] = useMutation(gql` const [updatePayments] = useMutation(gql`
@@ -88,21 +88,21 @@ export function PaymentMarkSelectedExported({
completedCallback && completedCallback([]); completedCallback && completedCallback([]);
setLoading(false); setLoading(false);
refetch && refetch(); refetch && refetch();
setVisible(false); setOpen(false);
}; };
return ( return (
<Popconfirm <Popconfirm
open={visible} open={open}
title={t("general.labels.areyousure")} title={t("general.labels.areyousure")}
onCancel={() => setVisible(false)} onCancel={() => setOpen(false)}
onConfirm={handleUpdate} onConfirm={handleUpdate}
disabled={disabled} disabled={disabled}
> >
<Button <Button
loading={loading} loading={loading}
disabled={disabled} disabled={disabled}
onClick={() => setVisible(true)} onClick={() => setOpen(true)}
> >
{t("bills.labels.markexported")} {t("bills.labels.markexported")}
</Button> </Button>

View File

@@ -46,7 +46,7 @@ function PaymentModalContainer({
const [updatePayment] = useMutation(UPDATE_PAYMENT); const [updatePayment] = useMutation(UPDATE_PAYMENT);
const { t } = useTranslation(); const { t } = useTranslation();
const { context, actions, visible } = paymentModal; const { context, actions, open } = paymentModal;
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@@ -130,12 +130,12 @@ function PaymentModalContainer({
}; };
useEffect(() => { useEffect(() => {
if (visible) { if (open) {
form.resetFields(); form.resetFields();
form.resetFields(); form.resetFields();
form.setFieldsValue(context); form.setFieldsValue(context);
} }
}, [visible, form, context]); }, [open, form, context]);
useEffect(() => { useEffect(() => {
if (enterAgain) form.submit(); if (enterAgain) form.submit();
@@ -148,7 +148,7 @@ function PaymentModalContainer({
? t("payments.labels.new") ? t("payments.labels.new")
: t("payments.labels.edit") : t("payments.labels.edit")
} }
open={visible} open={open}
destroyOnClose destroyOnClose
okText={t("general.actions.save")} okText={t("general.actions.save")}
onOk={() => form.submit()} onOk={() => form.submit()}

View File

@@ -36,7 +36,7 @@ export function PaymentsGenerateLink({
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [paymentLink, setPaymentLink] = useState(null); const [paymentLink, setPaymentLink] = useState(null);
@@ -69,7 +69,7 @@ export function PaymentsGenerateLink({
//Add in confirmation & errors. //Add in confirmation & errors.
if (callback) callback(); if (callback) callback();
// setVisible(false); // setOpen(false);
setLoading(false); setLoading(false);
}; };
@@ -137,7 +137,7 @@ export function PaymentsGenerateLink({
onClick={() => { onClick={() => {
form.resetFields(); form.resetFields();
setPaymentLink(null); setPaymentLink(null);
setVisible(false); setOpen(false);
}} }}
> >
{t("general.actions.cancel")} {t("general.actions.cancel")}
@@ -147,8 +147,8 @@ export function PaymentsGenerateLink({
); );
return ( return (
<Popover content={popContent} open={visible}> <Popover content={popContent} open={open}>
<Button onClick={() => setVisible(true)} loading={loading}> <Button onClick={() => setOpen(true)} loading={loading}>
{t("payments.actions.generatepaymentlink")} {t("payments.actions.generatepaymentlink")}
</Button> </Button>
</Popover> </Popover>

View File

@@ -65,7 +65,8 @@ export function PhonebookFormComponent({
{t("general.actions.save")} {t("general.actions.save")}
</Button> </Button>
<Button <Button
type="danger" type="primary"
danger
disabled={hasNoAccess} disabled={hasNoAccess}
onClick={handleDelete} onClick={handleDelete}
loading={formLoading} loading={formLoading}

View File

@@ -22,13 +22,13 @@ export function PrintCenterModalContainer({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { visible, context } = printCenterModal; const { open, context } = printCenterModal;
//const { type } = context; //const { type } = context;
// const { refetch } = actions; // const { refetch } = actions;
return ( return (
<Modal <Modal
open={visible} open={open}
onOk={() => toggleModalVisible()} onOk={() => toggleModalVisible()}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}
cancelButtonProps={{ style: { display: "none" } }} cancelButtonProps={{ style: { display: "none" } }}

View File

@@ -17,7 +17,7 @@ export default function ProductionBoardKanbanCardSettings({
associationSettings, associationSettings,
}) { }) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [updateKbSettings] = useMutation(UPDATE_KANBAN_SETTINGS); const [updateKbSettings] = useMutation(UPDATE_KANBAN_SETTINGS);
@@ -25,7 +25,7 @@ export default function ProductionBoardKanbanCardSettings({
form.setFieldsValue( form.setFieldsValue(
associationSettings && associationSettings.kanban_settings associationSettings && associationSettings.kanban_settings
); );
}, [form, associationSettings, visible]); }, [form, associationSettings, open]);
const { t } = useTranslation(); const { t } = useTranslation();
@@ -45,7 +45,7 @@ export default function ProductionBoardKanbanCardSettings({
}), }),
}); });
} }
setVisible(false); setOpen(false);
setLoading(false); setLoading(false);
}; };
@@ -173,8 +173,8 @@ export default function ProductionBoardKanbanCardSettings({
</div> </div>
); );
return ( return (
<Popover content={overlay} open={visible} placement="topRight"> <Popover content={overlay} open={open} placement="topRight">
<Button loading={loading} onClick={() => setVisible(true)}> <Button loading={loading} onClick={() => setOpen(true)}>
{t("production.labels.cardsettings")} {t("production.labels.cardsettings")}
</Button> </Button>
</Popover> </Popover>

View File

@@ -10,13 +10,13 @@ export default function ProductionListColumnComment({ record }) {
const [note, setNote] = useState(record.comment || ""); const [note, setNote] = useState(record.comment || "");
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [updateAlert] = useMutation(UPDATE_JOB); const [updateAlert] = useMutation(UPDATE_JOB);
const handleSaveNote = (e) => { const handleSaveNote = (e) => {
e.stopPropagation(); e.stopPropagation();
setVisible(false); setOpen(false);
updateAlert({ updateAlert({
variables: { variables: {
jobId: record.id, jobId: record.id,
@@ -34,15 +34,15 @@ export default function ProductionListColumnComment({ record }) {
setNote(e.target.value); setNote(e.target.value);
}; };
const handleVisibleChange = (flag) => { const handleOpenChange = (flag) => {
setVisible(flag); setOpen(flag);
if (flag) setNote(record.comment || ""); if (flag) setNote(record.comment || "");
}; };
return ( return (
<Popover <Popover
onOpenChange={handleVisibleChange} onOpenChange={handleOpenChange}
open={visible} open={open}
content={ content={
<div style={{ width: "30em" }}> <div style={{ width: "30em" }}>
<Input.TextArea <Input.TextArea

View File

@@ -1,102 +1,111 @@
import { useMutation } from "@apollo/client"; import {useMutation} from "@apollo/client";
import { Button, Card, Dropdown, TimePicker } from "antd"; import {Button, Card, Dropdown, TimePicker} from "antd";
import dayjs from "../../utils/day"; import dayjs from "../../utils/day";
import React, { useState } from "react"; import React, {useState} from "react";
import { useTranslation } from "react-i18next"; import {useTranslation} from "react-i18next";
import { logImEXEvent } from "../../firebase/firebase.utils"; import {logImEXEvent} from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import {UPDATE_JOB} from "../../graphql/jobs.queries";
import { DateFormatter } from "../../utils/DateFormatter"; import {DateFormatter} from "../../utils/DateFormatter";
import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component";
export default function ProductionListDate({ export default function ProductionListDate({
record, record,
field, field,
time, time,
pastIndicator, pastIndicator,
}) { }) {
const [updateAlert] = useMutation(UPDATE_JOB); const [updateAlert] = useMutation(UPDATE_JOB);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const { t } = useTranslation(); const {t} = useTranslation();
const handleChange = (date) => { const handleChange = (date) => {
logImEXEvent("product_toggle_date", { field }); logImEXEvent("product_toggle_date", {field});
// if (date.isSame(record[field] && dayjs(record[field]))) { // if (date.isSame(record[field] && dayjs(record[field]))) {
// return; // return;
// } // }
//e.stopPropagation(); //e.stopPropagation();
updateAlert({ updateAlert({
variables: { variables: {
jobId: record.id, jobId: record.id,
job: { job: {
[field]: date, [field]: date,
}, },
}, },
optimisticResponse: { optimisticResponse: {
update_jobs: { update_jobs: {
[field]: date, [field]: date,
}, },
}, },
}).then(() => { }).then(() => {
if (record.refetch) record.refetch(); if (record.refetch) record.refetch();
if (!time) { if (!time) {
setVisible(false); setOpen(false);
} }
}); });
}; };
let className = ""; let className = "";
if (pastIndicator) { if (pastIndicator) {
className = className =
!!record[field] && !!record[field] &&
((dayjs().isSameOrAfter(dayjs(record[field]), "day") && ((dayjs().isSameOrAfter(dayjs(record[field]), "day") &&
"production-completion-past") || "production-completion-past") ||
(dayjs().add(1, "day").isSame(dayjs(record[field]), "day") && (dayjs().add(1, "day").isSame(dayjs(record[field]), "day") &&
"production-completion-soon")); "production-completion-soon"));
} }
// TODO - Client Update = Why is the overlay a card? // TODO - Client Update = Why is the overlay a card?
return (
<Dropdown const overlayMenu = {
trigger={["click"]} items: [
onOpenChange={(v) => setVisible(v)} {
open={visible} key: 'overlayItem1',
style={{ label:
height: "19px", <Card style={{padding: "1rem"}} onClick={(e) => e.stopPropagation()}>
}} <FormDatePicker
overlay={ onClick={(e) => e.stopPropagation()}
<Card style={{ padding: "1rem" }} onClick={(e) => e.stopPropagation()}> value={(record[field] && dayjs(record[field])) || null}
<FormDatePicker onChange={handleChange}
onClick={(e) => e.stopPropagation()} format="MM/DD/YYYY"
value={(record[field] && dayjs(record[field])) || null} isDateOnly={!time}
onChange={handleChange} />
format="MM/DD/YYYY" {time && (
isDateOnly={!time} <TimePicker
/> onClick={(e) => e.stopPropagation()}
{time && ( value={(record[field] && dayjs(record[field])) || null}
<TimePicker onChange={handleChange}
onClick={(e) => e.stopPropagation()} minuteStep={15}
value={(record[field] && dayjs(record[field])) || null} format="hh:mm a"
onChange={handleChange} />
minuteStep={15} )}
format="hh:mm a" <Button onClick={() => setOpen(false)}>
/> {t("general.actions.close")}
)} </Button>
<Button onClick={() => setVisible(false)}> </Card>
{t("general.actions.close")} }
</Button> ]
</Card> }
}
> return (
<div <Dropdown
onClick={() => setVisible(true)} trigger={["click"]}
style={{ onOpenChange={(v) => setOpen(v)}
height: "19px", open={open}
}} style={{
className={className} height: "19px",
> }}
<DateFormatter bordered={false}>{record[field]}</DateFormatter> menu={overlayMenu}
</div> >
</Dropdown> <div
); onClick={() => setOpen(true)}
style={{
height: "19px",
}}
className={className}
>
<DateFormatter bordered={false}>{record[field]}</DateFormatter>
</div>
</Dropdown>
);
} }

View File

@@ -26,7 +26,7 @@ export default connect(
export function ProductionLastContacted({ currentUser, record }) { export function ProductionLastContacted({ currentUser, record }) {
const [updateAlert] = useMutation(UPDATE_JOB); const [updateAlert] = useMutation(UPDATE_JOB);
const [insertNote] = useMutation(INSERT_NEW_NOTE); const [insertNote] = useMutation(INSERT_NEW_NOTE);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();
const handleFinish = async ({ const handleFinish = async ({
@@ -76,63 +76,70 @@ export function ProductionLastContacted({ currentUser, record }) {
} }
if (record.refetch) record.refetch(); if (record.refetch) record.refetch();
setVisible(false); setOpen(false);
}; };
useEffect(() => { useEffect(() => {
if (visible) { if (open) {
form.setFieldsValue({ form.setFieldsValue({
note: null, note: null,
date_last_contacted: date_last_contacted:
record.date_last_contacted && dayjs(record.date_last_contacted), record.date_last_contacted && dayjs(record.date_last_contacted),
}); });
} }
}, [visible, form, record.date_last_contacted]); }, [open, form, record.date_last_contacted]);
const overlayMenu = {
items: [
{
key: 'overlay-item-1',
label:
<Card
style={{ padding: "1rem" }}
onClick={(e) => e.stopPropagation()}
>
<Form form={form} onFinish={handleFinish} layout="vertical">
<Form.Item
name="date_last_contacted"
label={t("jobs.fields.date_last_contacted")}
>
<FormDateTimePickerComponent />
</Form.Item>
<Form.Item
name="date_next_contact"
label={t("jobs.fields.date_next_contact")}
>
<FormDateTimePickerComponent />
</Form.Item>
<Form.Item label={t("notes.labels.notetoadd")} name="note">
<Input.TextArea rows={4} />
</Form.Item>
<Space>
<Button type="primary" htmlType="submit">
{t("general.actions.save")}
</Button>
<Button onClick={() => setOpen(false)}>
{t("general.actions.close")}
</Button>
</Space>
</Form>
</Card>
}
]
}
// TODO - Client Update - Why is this a card?
return ( return (
<div> <div>
<Dropdown <Dropdown
//trigger={["click"]} //trigger={["click"]}
open={visible} open={open}
style={{ style={{
height: "19px", height: "19px",
}} }}
overlay={ menu={overlayMenu}
<Card
style={{ padding: "1rem" }}
onClick={(e) => e.stopPropagation()}
>
<Form form={form} onFinish={handleFinish} layout="vertical">
<Form.Item
name="date_last_contacted"
label={t("jobs.fields.date_last_contacted")}
>
<FormDateTimePickerComponent />
</Form.Item>
<Form.Item
name="date_next_contact"
label={t("jobs.fields.date_next_contact")}
>
<FormDateTimePickerComponent />
</Form.Item>
<Form.Item label={t("notes.labels.notetoadd")} name="note">
<Input.TextArea rows={4} />
</Form.Item>
<Space>
<Button type="primary" htmlType="submit">
{t("general.actions.save")}
</Button>
<Button onClick={() => setVisible(false)}>
{t("general.actions.close")}
</Button>
</Space>
</Form>
</Card>
}
> >
<div <div
onClick={() => setVisible(true)} onClick={() => setOpen(true)}
style={{ style={{
height: "19px", height: "19px",
}} }}

View File

@@ -24,14 +24,14 @@ function ProductionListColumnProductionNote({ record, setNoteUpsertContext }) {
(record.production_vars && record.production_vars.note) || "" (record.production_vars && record.production_vars.note) || ""
); );
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [updateAlert] = useMutation(UPDATE_JOB); const [updateAlert] = useMutation(UPDATE_JOB);
const handleSaveNote = (e) => { const handleSaveNote = (e) => {
logImEXEvent("production_add_note"); logImEXEvent("production_add_note");
e.stopPropagation(); e.stopPropagation();
setVisible(false); setOpen(false);
updateAlert({ updateAlert({
variables: { variables: {
jobId: record.id, jobId: record.id,
@@ -52,16 +52,16 @@ function ProductionListColumnProductionNote({ record, setNoteUpsertContext }) {
setNote(e.target.value); setNote(e.target.value);
}; };
const handleVisibleChange = (flag) => { const handleOpenChange = (flag) => {
setVisible(flag); setOpen(flag);
if (flag) if (flag)
setNote((record.production_vars && record.production_vars.note) || ""); setNote((record.production_vars && record.production_vars.note) || "");
}; };
return ( return (
<Popover <Popover
onOpenChange={handleVisibleChange} onOpenChange={handleOpenChange}
open={visible} open={open}
content={ content={
<div style={{ width: "30em" }}> <div style={{ width: "30em" }}>
<Input.TextArea <Input.TextArea
@@ -79,7 +79,7 @@ function ProductionListColumnProductionNote({ record, setNoteUpsertContext }) {
</Button> </Button>
<Button <Button
onClick={() => { onClick={() => {
setVisible(false); setOpen(false);
setNoteUpsertContext({ setNoteUpsertContext({
context: { context: {
jobId: record.id, jobId: record.id,

View File

@@ -23,7 +23,7 @@ export function ProductionListSaveConfigButton({
}) { }) {
const [updateShop] = useMutation(UPDATE_SHOP); const [updateShop] = useMutation(UPDATE_SHOP);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [form] = Form.useForm(); const [form] = Form.useForm();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -61,7 +61,7 @@ export function ProductionListSaveConfigButton({
}); });
} }
form.resetFields(); form.resetFields();
setVisible(false); setOpen(false);
setLoading(false); setLoading(false);
}; };
const popMenu = ( const popMenu = (
@@ -76,10 +76,10 @@ export function ProductionListSaveConfigButton({
</Form.Item> </Form.Item>
<Space wrap> <Space wrap>
<Button type="danger" onClick={() => form.submit()} loading={loading}> <Button type="primary" danger onClick={() => form.submit()} loading={loading}>
{t("general.actions.save")} {t("general.actions.save")}
</Button> </Button>
<Button onClick={() => setVisible(false)}> <Button onClick={() => setOpen(false)}>
{t("general.actions.close")} {t("general.actions.close")}
</Button> </Button>
</Space> </Space>
@@ -88,8 +88,8 @@ export function ProductionListSaveConfigButton({
); );
return ( return (
<Popover open={visible} content={popMenu}> <Popover open={open} content={popMenu}>
<Button loading={loading} onClick={() => setVisible(true)}> <Button loading={loading} onClick={() => setOpen(true)}>
{t("production.actions.saveconfig")} {t("production.actions.saveconfig")}
</Button> </Button>
</Popover> </Popover>

View File

@@ -46,12 +46,12 @@ export function ReportCenterModalComponent({ reportCenterModal }) {
const ReportsList = Object.keys(Templates).map((key) => { const ReportsList = Object.keys(Templates).map((key) => {
return Templates[key]; return Templates[key];
}); });
const { visible } = reportCenterModal; const { open } = reportCenterModal;
const [callVendorQuery, { data: vendorData, called: vendorCalled }] = const [callVendorQuery, { data: vendorData, called: vendorCalled }] =
useLazyQuery(QUERY_ALL_VENDORS, { useLazyQuery(QUERY_ALL_VENDORS, {
skip: !( skip: !(
visible && open &&
Templates[form.getFieldValue("key")] && Templates[form.getFieldValue("key")] &&
Templates[form.getFieldValue("key")].idtype Templates[form.getFieldValue("key")].idtype
), ),
@@ -60,7 +60,7 @@ export function ReportCenterModalComponent({ reportCenterModal }) {
const [callEmployeeQuery, { data: employeeData, called: employeeCalled }] = const [callEmployeeQuery, { data: employeeData, called: employeeCalled }] =
useLazyQuery(QUERY_ACTIVE_EMPLOYEES, { useLazyQuery(QUERY_ACTIVE_EMPLOYEES, {
skip: !( skip: !(
visible && open &&
Templates[form.getFieldValue("key")] && Templates[form.getFieldValue("key")] &&
Templates[form.getFieldValue("key")].idtype Templates[form.getFieldValue("key")].idtype
), ),

View File

@@ -22,11 +22,11 @@ export function ReportCenterModalContainer({
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { visible } = reportCenterModal; const { open } = reportCenterModal;
return ( return (
<Modal <Modal
open={visible} open={open}
title={t("printcenter.labels.reportcentermodal")} title={t("printcenter.labels.reportcentermodal")}
onOk={() => toggleModalVisible()} onOk={() => toggleModalVisible()}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}

View File

@@ -37,6 +37,7 @@ export function ScheduleCalendarHeaderComponent({
events, events,
...otherProps ...otherProps
}) { }) {
console.log(`ScheduleCalendarHeaderComponent: ${label} Calculating: ${calculating}`)
const ATSToday = useMemo(() => { const ATSToday = useMemo(() => {
if (!events) return []; if (!events) return [];
return _.groupBy( return _.groupBy(

View File

@@ -45,7 +45,7 @@ export function ScheduleJobModalContainer({
currentUser, currentUser,
insertAuditTrail, insertAuditTrail,
}) { }) {
const { visible, context, actions } = scheduleModal; const { open, context, actions } = scheduleModal;
const { jobId, job, previousEvent } = context; const { jobId, job, previousEvent } = context;
const { refetch } = actions; const { refetch } = actions;
@@ -73,7 +73,7 @@ export function ScheduleJobModalContainer({
variables: { jobid: jobId }, variables: { jobid: jobId },
fetchPolicy: "network-only", fetchPolicy: "network-only",
nextFetchPolicy: "network-only", nextFetchPolicy: "network-only",
skip: !visible || !!!jobId, skip: !open || !!!jobId,
}); });
useEffect(() => { useEffect(() => {
@@ -129,7 +129,7 @@ export function ScheduleJobModalContainer({
jobid: jobId, jobid: jobId,
bodyshopid: bodyshop.id, bodyshopid: bodyshop.id,
start: dayjs(values.start), start: dayjs(values.start),
end: dayjs(values.start).add(bodyshop.appt_length || 60, "minutes"), end: dayjs(values.start).add(bodyshop.appt_length || 60, "minute"),
color: values.color, color: values.color,
note: values.note, note: values.note,
created_by: currentUser.email, created_by: currentUser.email,
@@ -206,7 +206,7 @@ export function ScheduleJobModalContainer({
return ( return (
<Modal <Modal
open={visible} open={open}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}
onOk={() => form.submit()} onOk={() => form.submit()}
width={"90%"} width={"90%"}

View File

@@ -6,7 +6,7 @@ import { UPDATE_SCOREBOARD_ENTRY } from "../../graphql/scoreboard.queries";
import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component";
export default function ScoreboardEntryEdit({ entry }) { export default function ScoreboardEntryEdit({ entry }) {
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { t } = useTranslation(); const { t } = useTranslation();
const [updateScoreboardentry] = useMutation(UPDATE_SCOREBOARD_ENTRY); const [updateScoreboardentry] = useMutation(UPDATE_SCOREBOARD_ENTRY);
@@ -28,7 +28,7 @@ export default function ScoreboardEntryEdit({ entry }) {
notification["success"]({ notification["success"]({
message: t("scoreboard.successes.updated"), message: t("scoreboard.successes.updated"),
}); });
setVisible(false); setOpen(false);
} }
setLoading(false); setLoading(false);
}; };
@@ -81,7 +81,7 @@ export default function ScoreboardEntryEdit({ entry }) {
<Button type="primary" loading={loading} htmlType="submit"> <Button type="primary" loading={loading} htmlType="submit">
{t("general.actions.save")} {t("general.actions.save")}
</Button> </Button>
<Button onClick={() => setVisible(false)}> <Button onClick={() => setOpen(false)}>
{t("general.actions.cancel")} {t("general.actions.cancel")}
</Button> </Button>
</Form> </Form>
@@ -92,11 +92,11 @@ export default function ScoreboardEntryEdit({ entry }) {
return ( return (
<div> <div>
<Dropdown open={visible} overlay={popContent}> <Dropdown open={open} overlay={popContent}>
<Button <Button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setVisible(true); setOpen(true);
}} }}
> >
{t("scoreboard.actions.edit")} {t("scoreboard.actions.edit")}

View File

@@ -14,7 +14,7 @@ import {pageLimit} from "../../utils/config";
export default function ScoreboardJobsList({ scoreBoardlist }) { export default function ScoreboardJobsList({ scoreBoardlist }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [state, setState] = useState({ const [state, setState] = useState({
visible: false, open: false,
search: "", search: "",
current: 1, current: 1,
pageSize: pageLimit, pageSize: pageLimit,
@@ -25,7 +25,7 @@ export default function ScoreboardJobsList({ scoreBoardlist }) {
{ {
fetchPolicy: "network-only", fetchPolicy: "network-only",
nextFetchPolicy: "network-only", nextFetchPolicy: "network-only",
skip: !state.visible, skip: !state.open,
variables: { variables: {
search: state.search !== "" ? `%${state.search}%` : null, search: state.search !== "" ? `%${state.search}%` : null,
offset: state.current ? (state.current - 1) * state.pageSize : 0, offset: state.current ? (state.current - 1) * state.pageSize : 0,
@@ -101,14 +101,14 @@ export default function ScoreboardJobsList({ scoreBoardlist }) {
return ( return (
<> <>
<Modal <Modal
open={state.visible} open={state.open}
destroyOnClose destroyOnClose
width="80%" width="80%"
cancelButtonProps={{ style: { display: "none" } }} cancelButtonProps={{ style: { display: "none" } }}
onCancel={() => onCancel={() =>
setState((state) => ({ setState((state) => ({
...state, ...state,
visible: false, open: false,
current: 1, current: 1,
search: "", search: "",
})) }))
@@ -157,7 +157,7 @@ export default function ScoreboardJobsList({ scoreBoardlist }) {
</Card> </Card>
</Modal> </Modal>
<Button <Button
onClick={() => setState((state) => ({ ...state, visible: true }))} onClick={() => setState((state) => ({ ...state, open: true }))}
> >
{t("scoreboard.labels.entries")} {t("scoreboard.labels.entries")}
</Button> </Button>

View File

@@ -20,7 +20,7 @@ export function ScoreboardLastDays({ bodyshop, sbEntriesByDate }) {
const ArrayOfDate = []; const ArrayOfDate = [];
for (var i = lastNumberWorkingDays - 1; i >= 0; i--) { for (var i = lastNumberWorkingDays - 1; i >= 0; i--) {
ArrayOfDate.push(dayjs().businessDaysSubtract(i, "day").format("yyyy-MM-DD")); ArrayOfDate.push(dayjs().businessDaysSubtract(i, "day").format("YYYY-MM-DD"));
} }
return ( return (

View File

@@ -11,8 +11,8 @@ import { TemplateList } from "../../utils/TemplateConstants";
import ShopTemplateAdd from "../shop-template-add/shop-template-add.component"; import ShopTemplateAdd from "../shop-template-add/shop-template-add.component";
import ShopTemplateDeleteComponent from "../shop-template-delete/shop-template-delete.component"; import ShopTemplateDeleteComponent from "../shop-template-delete/shop-template-delete.component";
export default function ShopTemplatesListContainer({ visibleState }) { export default function ShopTemplatesListContainer({ openState }) {
const [visible, setVisible] = visibleState; const [open, setOpen] = openState;
const { loading, error, data, refetch } = useQuery(QUERY_CUSTOM_TEMPLATES, { const { loading, error, data, refetch } = useQuery(QUERY_CUSTOM_TEMPLATES, {
fetchPolicy: "network-only", fetchPolicy: "network-only",
nextFetchPolicy: "network-only", nextFetchPolicy: "network-only",
@@ -38,8 +38,8 @@ export default function ShopTemplatesListContainer({ visibleState }) {
(<Drawer (<Drawer
placement="left" placement="left"
width="25%" width="25%"
open={visible} open={open}
onClose={() => setVisible(false)} onClose={() => setOpen(false)}
> >
<div> <div>
<div>{t("bodyshop.labels.customtemplates")}</div> <div>{t("bodyshop.labels.customtemplates")}</div>

View File

@@ -7,11 +7,11 @@ import { UPDATE_ASSOCIATION } from "../../graphql/user.queries";
export default function ShopUsersAuthEdit({ association }) { export default function ShopUsersAuthEdit({ association }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [updateAssociation] = useMutation(UPDATE_ASSOCIATION); const [updateAssociation] = useMutation(UPDATE_ASSOCIATION);
const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false);
const [value, setValue] = useState(association.authlevel); const [value, setValue] = useState(association.authlevel);
const handleSave = async () => { const handleSave = async () => {
setVisible(false); setOpen(false);
const result = await updateAssociation({ const result = await updateAssociation({
variables: { variables: {
assocId: association.id, assocId: association.id,
@@ -30,7 +30,7 @@ export default function ShopUsersAuthEdit({ association }) {
return ( return (
<div> <div>
{visible && ( {open && (
<div> <div>
<InputNumber <InputNumber
min={0} min={0}
@@ -41,10 +41,8 @@ export default function ShopUsersAuthEdit({ association }) {
/> />
</div> </div>
)} )}
{!visible && ( {!open && (
<div <div style={{ cursor: "pointer" }}>
style={{ cursor: "pointer" }} //onClick={() => setVisible(true)}
>
{association.authlevel || t("general.labels.na")} {association.authlevel || t("general.labels.na")}
</div> </div>
)} )}

View File

@@ -37,7 +37,7 @@ export function TimeTicketModalContainer({
const [updateTicket] = useMutation(UPDATE_TIME_TICKET); const [updateTicket] = useMutation(UPDATE_TIME_TICKET);
const { data: EmployeeAutoCompleteData } = useQuery(QUERY_ACTIVE_EMPLOYEES, { const { data: EmployeeAutoCompleteData } = useQuery(QUERY_ACTIVE_EMPLOYEES, {
skip: !timeTicketModal.visible, skip: !timeTicketModal.open,
fetchPolicy: "network-only", fetchPolicy: "network-only",
nextFetchPolicy: "network-only", nextFetchPolicy: "network-only",
}); });
@@ -127,8 +127,8 @@ export function TimeTicketModalContainer({
}, [enterAgain, form]); }, [enterAgain, form]);
useEffect(() => { useEffect(() => {
if (timeTicketModal.visible) form.resetFields(); if (timeTicketModal.open) form.resetFields();
}, [timeTicketModal.visible, form]); }, [timeTicketModal.open, form]);
const handleFieldsChange = (changedFields, allFields) => { const handleFieldsChange = (changedFields, allFields) => {
if (!!changedFields.employeeid && !!EmployeeAutoCompleteData) { if (!!changedFields.employeeid && !!EmployeeAutoCompleteData) {
@@ -169,7 +169,7 @@ export function TimeTicketModalContainer({
: t("timetickets.labels.new") : t("timetickets.labels.new")
} }
width={"90%"} width={"90%"}
open={timeTicketModal.visible} open={timeTicketModal.open}
forceRender forceRender
onCancel={handleCancel} onCancel={handleCancel}
afterClose={() => form.resetFields()} afterClose={() => form.resetFields()}

View File

@@ -68,13 +68,15 @@ function VehicleDetailFormContainer({ vehicle, refetch }) {
title={t("menus.header.vehicles")} title={t("menus.header.vehicles")}
extra={[ extra={[
<Popconfirm <Popconfirm
key="delete"
trigger="click" trigger="click"
onConfirm={handleDelete} onConfirm={handleDelete}
disabled={vehicle.jobs.length !== 0} disabled={vehicle.jobs.length !== 0}
title={t("vehicles.labels.deleteconfirm")} title={t("vehicles.labels.deleteconfirm")}
> >
<Button <Button
type="danger" type="primary"
danger
loading={loading} loading={loading}
disabled={vehicle.jobs.length !== 0} disabled={vehicle.jobs.length !== 0}
> >
@@ -82,6 +84,7 @@ function VehicleDetailFormContainer({ vehicle, refetch }) {
</Button> </Button>
</Popconfirm>, </Popconfirm>,
<Button <Button
key="save"
type="primary" type="primary"
loading={loading} loading={loading}
onClick={() => form.submit()} onClick={() => form.submit()}

View File

@@ -64,7 +64,8 @@ export function VendorsFormComponent({bodyshop, form, formLoading, handleDelete,
{t("general.actions.save")} {t("general.actions.save")}
</Button> </Button>
<Button <Button
type="danger" type="primary"
danger
disabled={selectedvendor === "new"} disabled={selectedvendor === "new"}
onClick={handleDelete} onClick={handleDelete}
loading={formLoading} loading={formLoading}

View File

@@ -178,7 +178,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO, insertAuditTrail, })
cancelText={t("general.labels.no")} cancelText={t("general.labels.no")}
title={t("jobs.labels.closeconfirm")} title={t("jobs.labels.closeconfirm")}
> >
<Button loading={loading} type="danger" disabled={jobRO}> <Button loading={loading} type="primary" danger disabled={jobRO}>
{t("general.actions.close")} {t("general.actions.close")}
</Button> </Button>
</Popconfirm> </Popconfirm>

View File

@@ -1,6 +1,6 @@
import {FloatButton, Layout} from "antd"; import {FloatButton, Layout} from "antd";
import preval from "preval.macro"; import preval from "preval.macro";
import React, {lazy, Suspense, useEffect} from "react"; import React, {lazy, Suspense, useEffect, useState} from "react";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
import {connect} from "react-redux"; import {connect} from "react-redux";
import {Link, Route, Routes} from "react-router-dom"; import {Link, Route, Routes} from "react-router-dom";
@@ -177,6 +177,8 @@ const mapStateToProps = createStructuredSelector({
export function Manage({conflict, bodyshop}) { export function Manage({conflict, bodyshop}) {
const {t} = useTranslation(); const {t} = useTranslation();
const [chatVisible] = useState(false);
useEffect(() => { useEffect(() => {
const widgetId = "IABVNO4scRKY11XBQkNr"; const widgetId = "IABVNO4scRKY11XBQkNr";
@@ -360,7 +362,7 @@ export function Manage({conflict, bodyshop}) {
return ( return (
<> <>
<ChatAffixContainer/> <ChatAffixContainer bodyshop={bodyshop} chatVisible={chatVisible} />
<Layout className="layout-container"> <Layout className="layout-container">
<UpdateAlert/> <UpdateAlert/>
<HeaderContainer/> <HeaderContainer/>

View File

@@ -42,7 +42,7 @@
// return ( // return (
// <RbacWrapper action="shop:templates"> // <RbacWrapper action="shop:templates">
// <div> // <div>
// <ShopTemplatesListContainer visibleState={drawerVisibility} /> // <ShopTemplatesListContainer openState={drawerVisibility} />
// <Button onClick={() => drawerVisibility[1](true)}>Show List</Button> // <Button onClick={() => drawerVisibility[1](true)}>Show List</Button>
// <ShopTemplateEditor /> // <ShopTemplateEditor />
// </div> // </div>

View File

@@ -121,7 +121,7 @@ export function* calculateScheduleLoad({ payload: end }) {
} }
const itemDate = dayjs(item.actual_in || item.scheduled_in).format( const itemDate = dayjs(item.actual_in || item.scheduled_in).format(
"yyyy-MM-DD" "YYYY-MM-DD"
); );
const AddJobForSchedulingCalc = !item.inproduction; const AddJobForSchedulingCalc = !item.inproduction;
@@ -171,7 +171,7 @@ export function* calculateScheduleLoad({ payload: end }) {
const itemDate = dayjs( const itemDate = dayjs(
item.actual_completion || item.scheduled_completion item.actual_completion || item.scheduled_completion
).format("yyyy-MM-DD"); ).format("YYYY-MM-DD");
//Skip it, it's already completed. //Skip it, it's already completed.
if (!!load[itemDate]) { if (!!load[itemDate]) {
@@ -209,10 +209,10 @@ export function* calculateScheduleLoad({ payload: end }) {
const range = Math.round(dayjs.duration(end.diff(today)).asDays()) + 1; const range = Math.round(dayjs.duration(end.diff(today)).asDays()) + 1;
for (var day = 0; day < range; day++) { for (var day = 0; day < range; day++) {
const current = dayjs(today).add(day, "day").format("yyyy-MM-DD"); const current = dayjs(today).add(day, "day").format("YYYY-MM-DD");
const prev = dayjs(today) const prev = dayjs(today)
.add(day - 1, "day") .add(day - 1, "day")
.format("yyyy-MM-DD"); .format("YYYY-MM-DD");
if (!!!load[current]) { if (!!!load[current]) {
load[current] = {}; load[current] = {};
} }

View File

@@ -10,7 +10,7 @@ const INITIAL_STATE = {
template: { name: null, variables: {} }, template: { name: null, variables: {} },
}, },
visible: false, open: false,
error: null, error: null,
}; };
@@ -19,13 +19,13 @@ const emailReducer = (state = INITIAL_STATE, action) => {
case EmailActionTypes.TOGGLE_EMAIL_OVERLAY_VISIBLE: case EmailActionTypes.TOGGLE_EMAIL_OVERLAY_VISIBLE:
return { return {
...state, ...state,
visible: !state.visible, open: !state.open,
}; };
case EmailActionTypes.SET_EMAIL_OPTIONS: case EmailActionTypes.SET_EMAIL_OPTIONS:
return { return {
...state, ...state,
emailConfig: { ...action.payload }, emailConfig: { ...action.payload },
visible: true, open: true,
}; };
default: default:
return state; return state;

View File

@@ -4,7 +4,7 @@ const selectEmail = (state) => state.email;
export const selectEmailVisible = createSelector( export const selectEmailVisible = createSelector(
[selectEmail], [selectEmail],
(email) => email.visible (email) => email.open
); );
export const selectEmailConfig = createSelector( export const selectEmailConfig = createSelector(

View File

@@ -1,7 +1,7 @@
import MessagingActionTypes from "./messaging.types"; import MessagingActionTypes from "./messaging.types";
const INITIAL_STATE = { const INITIAL_STATE = {
visible: false, open: false,
selectedConversationId: null, selectedConversationId: null,
isSending: false, isSending: false,
error: null, error: null,
@@ -16,7 +16,7 @@ const messagingReducer = (state = INITIAL_STATE, action) => {
case MessagingActionTypes.TOGGLE_CHAT_VISIBLE: case MessagingActionTypes.TOGGLE_CHAT_VISIBLE:
return { return {
...state, ...state,
visible: !state.visible, open: !state.open,
}; };
case MessagingActionTypes.OPEN_CHAT_BY_PHONE: case MessagingActionTypes.OPEN_CHAT_BY_PHONE:
return { return {
@@ -26,7 +26,7 @@ const messagingReducer = (state = INITIAL_STATE, action) => {
case MessagingActionTypes.SET_SELECTED_CONVERSATION: case MessagingActionTypes.SET_SELECTED_CONVERSATION:
return { return {
...state, ...state,
visible: true, open: true,
searchingForConversation: false, searchingForConversation: false,
selectedConversationId: action.payload, selectedConversationId: action.payload,
}; };

View File

@@ -4,7 +4,7 @@ const selectMessaging = (state) => state.messaging;
export const selectChatVisible = createSelector( export const selectChatVisible = createSelector(
[selectMessaging], [selectMessaging],
(messaging) => messaging.visible (messaging) => messaging.open
); );
export const selectIsSending = createSelector( export const selectIsSending = createSelector(

View File

@@ -1,7 +1,7 @@
import ModalsActionTypes from "./modals.types"; import ModalsActionTypes from "./modals.types";
const baseModal = { const baseModal = {
visible: false, open: false,
context: {}, context: {},
actions: { actions: {
refetch: null, refetch: null,
@@ -35,7 +35,7 @@ const modalsReducer = (state = INITIAL_STATE, action) => {
...state, ...state,
[action.payload]: { [action.payload]: {
...state[action.payload], ...state[action.payload],
visible: !state[action.payload].visible, open: !state[action.payload].open,
}, },
}; };
case ModalsActionTypes.SET_MODAL_CONTEXT: case ModalsActionTypes.SET_MODAL_CONTEXT:
@@ -44,7 +44,7 @@ const modalsReducer = (state = INITIAL_STATE, action) => {
[action.payload.modal]: { [action.payload.modal]: {
...state[action.payload.modal], ...state[action.payload.modal],
...action.payload.context, ...action.payload.context,
visible: true, open: true,
}, },
}; };
default: default:

View File

@@ -1,12 +1,6 @@
import { configureStore } from '@reduxjs/toolkit'; import { configureStore } from '@reduxjs/toolkit';
import { import {
persistStore, persistStore,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER
} from "redux-persist"; } from "redux-persist";
import { createLogger } from "redux-logger"; import { createLogger } from "redux-logger";
import createSagaMiddleware from "redux-saga"; import createSagaMiddleware from "redux-saga";
@@ -42,9 +36,7 @@ if (process.env.NODE_ENV === "development") {
export const store = configureStore({ export const store = configureStore({
reducer: rootReducer, reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware({ middleware: (getDefaultMiddleware) => getDefaultMiddleware({
serializableCheck: { serializableCheck: false,
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat(middlewares), }).concat(middlewares),
// middleware: middlewares, // middleware: middlewares,
devTools: process.env.NODE_ENV !== 'production', devTools: process.env.NODE_ENV !== 'production',

View File

@@ -0,0 +1,35 @@
export const BETA_KEY = 'betaSwitchImex';
export const checkBeta = () => {
const cookie = document.cookie.split('; ').find(row => row.startsWith(BETA_KEY));
return cookie ? cookie.split('=')[1] === 'true' : false;
}
export const setBeta = (value) => {
const domain = window.location.hostname.split('.').slice(-2).join('.');
document.cookie = `${BETA_KEY}=${value}; path=/; domain=.${domain}`;
}
export const handleBeta = () => {
// If the current host name does not start with beta or test, then we don't need to do anything.
if (window.location.hostname.startsWith('localhost')) {
console.log('Not on beta or test, so no need to handle beta.');
return;
}
const isBeta = checkBeta();
const currentHostName = window.location.hostname;
// Beta is enabled, but the current host name does start with beta.
if (isBeta && !currentHostName.startsWith('beta')) {
window.location.href = `${window.location.protocol}//beta.${currentHostName}${window.location.pathname}${window.location.search}${window.location.hash}`;
}
// Beta is not enabled, but the current host name does start with beta.
else if (!isBeta && currentHostName.startsWith('beta')) {
window.location.href = `${window.location.protocol}//${currentHostName.replace('beta.', '')}${window.location.pathname}${window.location.search}${window.location.hash}`;
}
}
export default handleBeta;

View File

@@ -1,129 +1,128 @@
import { useEffect, useCallback, useReducer } from "react"; import {useCallback, useEffect, useReducer, useState} from "react";
//Based on https://www.fullstacklabs.co/blog/keyboard-shortcuts-with-react-hooks //Based on https://www.fullstacklabs.co/blog/keyboard-shortcuts-with-react-hooks
const blacklistedTargets = []; // ["INPUT", "TEXTAREA"]; const blacklistedTargets = []; // ["INPUT", "TEXTAREA"];
export const useKeyboardSaveShortcut = (callback) => export const useKeyboardSaveShortcut = (callback) =>
useKeyboardShortcut(["Control", "S"], callback, { overrideSystem: true }); useKeyboardShortcut(["Control", "S"], callback, {overrideSystem: true});
const keysReducer = (state, action) => { const keysReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case "set-key-down": case "set-key-down":
const keydownState = { ...state, [action.key]: true }; const keydownState = {...state, [action.key]: true};
return keydownState; return keydownState;
case "set-key-up": case "set-key-up":
const keyUpState = { ...state, [action.key]: false }; const keyUpState = {...state, [action.key]: false};
return keyUpState; return keyUpState;
case "reset-keys": case "reset-keys":
const resetState = { ...action.data }; const resetState = {...action.data};
return resetState; return resetState;
default: default:
return state; return state;
} }
}; };
const useKeyboardShortcut = (shortcutKeys, callback, options) => { const useKeyboardShortcut = (shortcutKeys, callback, options) => {
if (!Array.isArray(shortcutKeys)) if (!Array.isArray(shortcutKeys))
throw new Error( throw new Error(
"The first parameter to `useKeyboardShortcut` must be an ordered array of `KeyboardEvent.key` strings." "The first parameter to `useKeyboardShortcut` must be an ordered array of `KeyboardEvent.key` strings."
);
if (!shortcutKeys.length)
throw new Error(
"The first parameter to `useKeyboardShortcut` must contain atleast one `KeyboardEvent.key` string."
);
if (!callback || typeof callback !== "function")
throw new Error(
"The second parameter to `useKeyboardShortcut` must be a function that will be envoked when the keys are pressed."
);
const {overrideSystem} = options || {};
const initalKeyMapping = shortcutKeys.reduce((currentKeys, key) => {
currentKeys[key.toLowerCase()] = false;
return currentKeys;
}, {});
const [keys, setKeys] = useReducer(keysReducer, initalKeyMapping);
const [listenersAdded, setListenersAdded] = useState(false);
const keydownListener = useCallback(
(assignedKey) => (keydownEvent) => {
const loweredKey = assignedKey.toLowerCase();
if (keydownEvent.repeat) return;
if (blacklistedTargets.includes(keydownEvent.target.tagName)) return;
if (loweredKey !== keydownEvent.key.toLowerCase()) return;
if (keys[loweredKey] === undefined) return;
if (overrideSystem) {
keydownEvent.preventDefault();
disabledEventPropagation(keydownEvent);
}
setKeys({type: "set-key-down", key: loweredKey});
return false;
},
[keys, overrideSystem]
); );
if (!shortcutKeys.length) const keyupListener = useCallback(
throw new Error( (assignedKey) => (keyupEvent) => {
"The first parameter to `useKeyboardShortcut` must contain atleast one `KeyboardEvent.key` string." const raisedKey = assignedKey.toLowerCase();
if (blacklistedTargets.includes(keyupEvent.target.tagName)) return;
if (keyupEvent.key.toLowerCase() !== raisedKey) return;
if (keys[raisedKey] === undefined) return;
if (overrideSystem) {
keyupEvent.preventDefault();
disabledEventPropagation(keyupEvent);
}
setKeys({type: "set-key-up", key: raisedKey});
return false;
},
[keys, overrideSystem]
); );
if (!callback || typeof callback !== "function") useEffect(() => {
throw new Error( if (!Object.values(keys).filter((value) => !value).length) {
"The second parameter to `useKeyboardShortcut` must be a function that will be envoked when the keys are pressed." callback(keys);
); setKeys({type: "reset-keys", data: initalKeyMapping});
} else {
setKeys({type: null});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [callback, keys]);
const { overrideSystem } = options || {}; useEffect(() => {
const initalKeyMapping = shortcutKeys.reduce((currentKeys, key) => { if (!listenersAdded) {
currentKeys[key.toLowerCase()] = false; console.log('Added events for keyup and keydown');
return currentKeys; shortcutKeys.forEach((k) => {
}, {}); window.addEventListener("keydown", keydownListener(k));
window.addEventListener("keyup", keyupListener(k))
});
}
const [keys, setKeys] = useReducer(keysReducer, initalKeyMapping); setListenersAdded(true);
const keydownListener = useCallback( return () => {
(assignedKey) => (keydownEvent) => { shortcutKeys.forEach((k) => {
const loweredKey = assignedKey.toLowerCase(); window.removeEventListener("keydown", keydownListener(k));
window.removeEventListener("keyup", keyupListener(k));
});
}
}, [listenersAdded]);
if (keydownEvent.repeat) return;
if (blacklistedTargets.includes(keydownEvent.target.tagName)) return;
if (loweredKey !== keydownEvent.key.toLowerCase()) return;
if (keys[loweredKey] === undefined) return;
if (overrideSystem) {
keydownEvent.preventDefault();
disabledEventPropagation(keydownEvent);
}
setKeys({ type: "set-key-down", key: loweredKey });
return false;
},
[keys, overrideSystem]
);
const keyupListener = useCallback(
(assignedKey) => (keyupEvent) => {
const raisedKey = assignedKey.toLowerCase();
if (blacklistedTargets.includes(keyupEvent.target.tagName)) return;
if (keyupEvent.key.toLowerCase() !== raisedKey) return;
if (keys[raisedKey] === undefined) return;
if (overrideSystem) {
keyupEvent.preventDefault();
disabledEventPropagation(keyupEvent);
}
setKeys({ type: "set-key-up", key: raisedKey });
return false;
},
[keys, overrideSystem]
);
useEffect(() => {
if (!Object.values(keys).filter((value) => !value).length) {
callback(keys);
setKeys({ type: "reset-keys", data: initalKeyMapping });
} else {
setKeys({ type: null });
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [callback, keys]);
useEffect(() => {
shortcutKeys.forEach((k) =>
window.addEventListener("keydown", keydownListener(k))
);
return () =>
shortcutKeys.forEach((k) =>
window.removeEventListener("keydown", keydownListener(k))
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
shortcutKeys.forEach((k) =>
window.addEventListener("keyup", keyupListener(k))
);
return () =>
shortcutKeys.forEach((k) =>
window.removeEventListener("keyup", keyupListener(k))
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}; };
export default useKeyboardShortcut; export default useKeyboardShortcut;
function disabledEventPropagation(e) { function disabledEventPropagation(e) {
if (e) { if (e) {
if (e.stopPropagation) { if (e.stopPropagation) {
e.stopPropagation(); e.stopPropagation();
} else if (window.event) { } else if (window.event) {
window.event.cancelBubble = true; window.event.cancelBubble = true;
}
} }
}
} }

312
package-lock.json generated
View File

@@ -9,9 +9,9 @@
"version": "0.0.1", "version": "0.0.1",
"license": "UNLICENSED", "license": "UNLICENSED",
"dependencies": { "dependencies": {
"@aws-sdk/client-secrets-manager": "^3.485.0", "@aws-sdk/client-secrets-manager": "^3.490.0",
"@aws-sdk/client-ses": "^3.485.0", "@aws-sdk/client-ses": "^3.490.0",
"@aws-sdk/credential-provider-node": "^3.485.0", "@aws-sdk/credential-provider-node": "^3.490.0",
"@opensearch-project/opensearch": "^2.5.0", "@opensearch-project/opensearch": "^2.5.0",
"aws4": "^1.12.0", "aws4": "^1.12.0",
"axios": "^1.6.5", "axios": "^1.6.5",
@@ -42,7 +42,7 @@
"nodemailer": "^6.9.8", "nodemailer": "^6.9.8",
"phone": "^3.1.42", "phone": "^3.1.42",
"soap": "^1.0.0", "soap": "^1.0.0",
"socket.io": "^4.7.3", "socket.io": "^4.7.4",
"ssh2-sftp-client": "^9.1.0", "ssh2-sftp-client": "^9.1.0",
"stripe": "^14.11.0", "stripe": "^14.11.0",
"twilio": "^4.20.0", "twilio": "^4.20.0",
@@ -151,25 +151,25 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}, },
"node_modules/@aws-sdk/client-secrets-manager": { "node_modules/@aws-sdk/client-secrets-manager": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.490.0.tgz",
"integrity": "sha512-TruRGEdTy1y/5ln1NcU5LvIZyK38O89zU9vCfNQIKwTSrpS0sDJQukjg8VfMC8gbqUUvXdiPcS61Fxr1WfWn7g==", "integrity": "sha512-wd+PBIMOfSY9CpHfAAE9ztwwde7wom3/VdSqLbBUAUAvAlArANmBS610iCZSFP3ds38v8rnliAV9fjzf7IVnxQ==",
"dependencies": { "dependencies": {
"@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0", "@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/client-sts": "3.485.0", "@aws-sdk/client-sts": "3.490.0",
"@aws-sdk/core": "3.485.0", "@aws-sdk/core": "3.490.0",
"@aws-sdk/credential-provider-node": "3.485.0", "@aws-sdk/credential-provider-node": "3.490.0",
"@aws-sdk/middleware-host-header": "3.485.0", "@aws-sdk/middleware-host-header": "3.489.0",
"@aws-sdk/middleware-logger": "3.485.0", "@aws-sdk/middleware-logger": "3.489.0",
"@aws-sdk/middleware-recursion-detection": "3.485.0", "@aws-sdk/middleware-recursion-detection": "3.489.0",
"@aws-sdk/middleware-signing": "3.485.0", "@aws-sdk/middleware-signing": "3.489.0",
"@aws-sdk/middleware-user-agent": "3.485.0", "@aws-sdk/middleware-user-agent": "3.489.0",
"@aws-sdk/region-config-resolver": "3.485.0", "@aws-sdk/region-config-resolver": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@aws-sdk/util-endpoints": "3.485.0", "@aws-sdk/util-endpoints": "3.489.0",
"@aws-sdk/util-user-agent-browser": "3.485.0", "@aws-sdk/util-user-agent-browser": "3.489.0",
"@aws-sdk/util-user-agent-node": "3.485.0", "@aws-sdk/util-user-agent-node": "3.489.0",
"@smithy/config-resolver": "^2.0.23", "@smithy/config-resolver": "^2.0.23",
"@smithy/core": "^1.2.2", "@smithy/core": "^1.2.2",
"@smithy/fetch-http-handler": "^2.3.2", "@smithy/fetch-http-handler": "^2.3.2",
@@ -210,25 +210,25 @@
} }
}, },
"node_modules/@aws-sdk/client-ses": { "node_modules/@aws-sdk/client-ses": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.490.0.tgz",
"integrity": "sha512-XXilZfQTBsp5RWl2SRNaJ7pW7Kk7x4N1N++GZPYxHoUsmfB6jdE2ilEeSdfFtKhd9QxEDinQM7yYSGouiwofvA==", "integrity": "sha512-vcU4+1DfdZ+7AcrpaSxG+xohPkA9rMA0l6Jt3zJPkLqUBhrBQfkWISaQ6CNpS6QlAfxzrSudI4t4J5T9J0xs/g==",
"dependencies": { "dependencies": {
"@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0", "@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/client-sts": "3.485.0", "@aws-sdk/client-sts": "3.490.0",
"@aws-sdk/core": "3.485.0", "@aws-sdk/core": "3.490.0",
"@aws-sdk/credential-provider-node": "3.485.0", "@aws-sdk/credential-provider-node": "3.490.0",
"@aws-sdk/middleware-host-header": "3.485.0", "@aws-sdk/middleware-host-header": "3.489.0",
"@aws-sdk/middleware-logger": "3.485.0", "@aws-sdk/middleware-logger": "3.489.0",
"@aws-sdk/middleware-recursion-detection": "3.485.0", "@aws-sdk/middleware-recursion-detection": "3.489.0",
"@aws-sdk/middleware-signing": "3.485.0", "@aws-sdk/middleware-signing": "3.489.0",
"@aws-sdk/middleware-user-agent": "3.485.0", "@aws-sdk/middleware-user-agent": "3.489.0",
"@aws-sdk/region-config-resolver": "3.485.0", "@aws-sdk/region-config-resolver": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@aws-sdk/util-endpoints": "3.485.0", "@aws-sdk/util-endpoints": "3.489.0",
"@aws-sdk/util-user-agent-browser": "3.485.0", "@aws-sdk/util-user-agent-browser": "3.489.0",
"@aws-sdk/util-user-agent-node": "3.485.0", "@aws-sdk/util-user-agent-node": "3.489.0",
"@smithy/config-resolver": "^2.0.23", "@smithy/config-resolver": "^2.0.23",
"@smithy/core": "^1.2.2", "@smithy/core": "^1.2.2",
"@smithy/fetch-http-handler": "^2.3.2", "@smithy/fetch-http-handler": "^2.3.2",
@@ -262,22 +262,22 @@
} }
}, },
"node_modules/@aws-sdk/client-sso": { "node_modules/@aws-sdk/client-sso": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.490.0.tgz",
"integrity": "sha512-apN2bEn0PZs0jD4jAfvwO3dlWqw9YIQJ6TAudM1bd3S5vzWqlBBcLfQpK6taHoQaI+WqgUWXLuOf7gRFbGXKPg==", "integrity": "sha512-yfxoHmCL1w/IKmFRfzCxdVCQrGlSQf4eei9iVEm5oi3iE8REFyPj3o/BmKQEHG3h2ITK5UbdYDb5TY4xoYHsyA==",
"dependencies": { "dependencies": {
"@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0", "@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/core": "3.485.0", "@aws-sdk/core": "3.490.0",
"@aws-sdk/middleware-host-header": "3.485.0", "@aws-sdk/middleware-host-header": "3.489.0",
"@aws-sdk/middleware-logger": "3.485.0", "@aws-sdk/middleware-logger": "3.489.0",
"@aws-sdk/middleware-recursion-detection": "3.485.0", "@aws-sdk/middleware-recursion-detection": "3.489.0",
"@aws-sdk/middleware-user-agent": "3.485.0", "@aws-sdk/middleware-user-agent": "3.489.0",
"@aws-sdk/region-config-resolver": "3.485.0", "@aws-sdk/region-config-resolver": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@aws-sdk/util-endpoints": "3.485.0", "@aws-sdk/util-endpoints": "3.489.0",
"@aws-sdk/util-user-agent-browser": "3.485.0", "@aws-sdk/util-user-agent-browser": "3.489.0",
"@aws-sdk/util-user-agent-node": "3.485.0", "@aws-sdk/util-user-agent-node": "3.489.0",
"@smithy/config-resolver": "^2.0.23", "@smithy/config-resolver": "^2.0.23",
"@smithy/core": "^1.2.2", "@smithy/core": "^1.2.2",
"@smithy/fetch-http-handler": "^2.3.2", "@smithy/fetch-http-handler": "^2.3.2",
@@ -309,23 +309,23 @@
} }
}, },
"node_modules/@aws-sdk/client-sts": { "node_modules/@aws-sdk/client-sts": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.490.0.tgz",
"integrity": "sha512-PI4q36kVF0fpIPZyeQhrwwJZ6SRkOGvU3rX5Qn4b5UY5X+Ct1aLhqSX8/OB372UZIcnh6eSvERu8POHleDO7Jw==", "integrity": "sha512-n2vQ5Qu2qi2I0XMI+IH99ElpIRHOJTa1+sqNC4juMYxKQBMvw+EnsqUtaL3QvTHoyxNB/R7mpkeBB6SzPQ1TtA==",
"dependencies": { "dependencies": {
"@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0", "@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/core": "3.485.0", "@aws-sdk/core": "3.490.0",
"@aws-sdk/credential-provider-node": "3.485.0", "@aws-sdk/credential-provider-node": "3.490.0",
"@aws-sdk/middleware-host-header": "3.485.0", "@aws-sdk/middleware-host-header": "3.489.0",
"@aws-sdk/middleware-logger": "3.485.0", "@aws-sdk/middleware-logger": "3.489.0",
"@aws-sdk/middleware-recursion-detection": "3.485.0", "@aws-sdk/middleware-recursion-detection": "3.489.0",
"@aws-sdk/middleware-user-agent": "3.485.0", "@aws-sdk/middleware-user-agent": "3.489.0",
"@aws-sdk/region-config-resolver": "3.485.0", "@aws-sdk/region-config-resolver": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@aws-sdk/util-endpoints": "3.485.0", "@aws-sdk/util-endpoints": "3.489.0",
"@aws-sdk/util-user-agent-browser": "3.485.0", "@aws-sdk/util-user-agent-browser": "3.489.0",
"@aws-sdk/util-user-agent-node": "3.485.0", "@aws-sdk/util-user-agent-node": "3.489.0",
"@smithy/config-resolver": "^2.0.23", "@smithy/config-resolver": "^2.0.23",
"@smithy/core": "^1.2.2", "@smithy/core": "^1.2.2",
"@smithy/fetch-http-handler": "^2.3.2", "@smithy/fetch-http-handler": "^2.3.2",
@@ -359,9 +359,9 @@
} }
}, },
"node_modules/@aws-sdk/core": { "node_modules/@aws-sdk/core": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.490.0.tgz",
"integrity": "sha512-Yvi80DQcbjkYCft471ClE3HuetuNVqntCs6eFOomDcrJaqdOFrXv2kJAxky84MRA/xb7bGlDGAPbTuj1ICputg==", "integrity": "sha512-TSBWkXtxMU7q1Zo6w3v5wIOr/sj7P5Jw3OyO7lJrFGsPsDC2xwpxkVqTesDxkzgMRypO52xjYEmveagn1xxBHg==",
"dependencies": { "dependencies": {
"@smithy/core": "^1.2.2", "@smithy/core": "^1.2.2",
"@smithy/protocol-http": "^3.0.12", "@smithy/protocol-http": "^3.0.12",
@@ -375,11 +375,11 @@
} }
}, },
"node_modules/@aws-sdk/credential-provider-env": { "node_modules/@aws-sdk/credential-provider-env": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.489.0.tgz",
"integrity": "sha512-3XkFgwVU1XOB33dV7t9BKJ/ptdl2iS+0dxE7ecq8aqT2/gsfKmLCae1G17P8WmdD3z0kMDTvnqM2aWgUnSOkmg==", "integrity": "sha512-5PqYsx9G5SB2tqPT9/z/u0EkF6D4wP6HTMWQs+DfMdmwXihrqQAgeYaTtV3KbXqb88p6sfacwxhUvE6+Rm494w==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/property-provider": "^2.0.0", "@smithy/property-provider": "^2.0.0",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
@@ -389,15 +389,15 @@
} }
}, },
"node_modules/@aws-sdk/credential-provider-ini": { "node_modules/@aws-sdk/credential-provider-ini": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.490.0.tgz",
"integrity": "sha512-cFYF/Bdw7EnT4viSxYpNIv3IBkri/Yb+JpQXl8uDq7bfVJfAN5qZmK07vRkg08xL6TC4F41wshhMSAucGdTwIw==", "integrity": "sha512-7m63zyCpVqj9FsoDxWMWWRvL6c7zZzOcXYkHZmHujVVlmAXH0RT/vkXFkYgt+Ku+ov+v5NQrzwO5TmVoRt6O8g==",
"dependencies": { "dependencies": {
"@aws-sdk/credential-provider-env": "3.485.0", "@aws-sdk/credential-provider-env": "3.489.0",
"@aws-sdk/credential-provider-process": "3.485.0", "@aws-sdk/credential-provider-process": "3.489.0",
"@aws-sdk/credential-provider-sso": "3.485.0", "@aws-sdk/credential-provider-sso": "3.490.0",
"@aws-sdk/credential-provider-web-identity": "3.485.0", "@aws-sdk/credential-provider-web-identity": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/credential-provider-imds": "^2.0.0", "@smithy/credential-provider-imds": "^2.0.0",
"@smithy/property-provider": "^2.0.0", "@smithy/property-provider": "^2.0.0",
"@smithy/shared-ini-file-loader": "^2.0.6", "@smithy/shared-ini-file-loader": "^2.0.6",
@@ -409,16 +409,16 @@
} }
}, },
"node_modules/@aws-sdk/credential-provider-node": { "node_modules/@aws-sdk/credential-provider-node": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.490.0.tgz",
"integrity": "sha512-2DwzO2azkSzngifKDT61W/DL0tSzewuaFHiLJWdfc8Et3mdAQJ9x3KAj8u7XFpjIcGNqk7FiKjN+zeGUuNiEhA==", "integrity": "sha512-Gh33u2O5Xbout8G3z/Z5H/CZzdG1ophxf/XS3iMFxA1cazQ7swY1UMmGvB7Lm7upvax5anXouItD1Ph3gzKc4w==",
"dependencies": { "dependencies": {
"@aws-sdk/credential-provider-env": "3.485.0", "@aws-sdk/credential-provider-env": "3.489.0",
"@aws-sdk/credential-provider-ini": "3.485.0", "@aws-sdk/credential-provider-ini": "3.490.0",
"@aws-sdk/credential-provider-process": "3.485.0", "@aws-sdk/credential-provider-process": "3.489.0",
"@aws-sdk/credential-provider-sso": "3.485.0", "@aws-sdk/credential-provider-sso": "3.490.0",
"@aws-sdk/credential-provider-web-identity": "3.485.0", "@aws-sdk/credential-provider-web-identity": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/credential-provider-imds": "^2.0.0", "@smithy/credential-provider-imds": "^2.0.0",
"@smithy/property-provider": "^2.0.0", "@smithy/property-provider": "^2.0.0",
"@smithy/shared-ini-file-loader": "^2.0.6", "@smithy/shared-ini-file-loader": "^2.0.6",
@@ -430,11 +430,11 @@
} }
}, },
"node_modules/@aws-sdk/credential-provider-process": { "node_modules/@aws-sdk/credential-provider-process": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.489.0.tgz",
"integrity": "sha512-X9qS6ZO/rDKYDgWqD1YmSX7sAUUHax9HbXlgGiTTdtfhZvQh1ZmnH6wiPu5WNliafHZFtZT2W07kgrDLPld/Ug==", "integrity": "sha512-3vKQYJZ5cZYjy0870CPmbmKRBgATw2xCygxhn4m4UDCjOXVXcGUtYD51DMWsvBo3S0W8kH+FIJV4yuEDMFqLFQ==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/property-provider": "^2.0.0", "@smithy/property-provider": "^2.0.0",
"@smithy/shared-ini-file-loader": "^2.0.6", "@smithy/shared-ini-file-loader": "^2.0.6",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
@@ -445,13 +445,13 @@
} }
}, },
"node_modules/@aws-sdk/credential-provider-sso": { "node_modules/@aws-sdk/credential-provider-sso": {
"version": "3.485.0", "version": "3.490.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.490.0.tgz",
"integrity": "sha512-l0oC8GTrWh+LFQQfSmG1Jai1PX7Mhj9arb/CaS1/tmeZE0hgIXW++tvljYs/Dds4LGXUlaWG+P7BrObf6OyIXA==", "integrity": "sha512-3UUBUoPbFvT58IhS4Vb23omYj/QPNkjgxu9p9ruQ3KSjLkanI4w8t/l/jljA65q83P7CoLnM5UKG9L7RA8/V1Q==",
"dependencies": { "dependencies": {
"@aws-sdk/client-sso": "3.485.0", "@aws-sdk/client-sso": "3.490.0",
"@aws-sdk/token-providers": "3.485.0", "@aws-sdk/token-providers": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/property-provider": "^2.0.0", "@smithy/property-provider": "^2.0.0",
"@smithy/shared-ini-file-loader": "^2.0.6", "@smithy/shared-ini-file-loader": "^2.0.6",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
@@ -462,11 +462,11 @@
} }
}, },
"node_modules/@aws-sdk/credential-provider-web-identity": { "node_modules/@aws-sdk/credential-provider-web-identity": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.489.0.tgz",
"integrity": "sha512-WpBFZFE0iXtnibH5POMEKITj/hR0YV5l2n9p8BEvKjdJ63s3Xke1RN20ZdIyKDaRDwj8adnKDgNPEnAKdS4kLw==", "integrity": "sha512-mjIuE2Wg1H/ds0nXQ/7vfusEDudmdd8YzKZI1y5O4n60iZZtyB2RNIECtvLMx1EQAKclidY7/06qQkArrGau5Q==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/property-provider": "^2.0.0", "@smithy/property-provider": "^2.0.0",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
@@ -476,11 +476,11 @@
} }
}, },
"node_modules/@aws-sdk/middleware-host-header": { "node_modules/@aws-sdk/middleware-host-header": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.489.0.tgz",
"integrity": "sha512-1mAUX9dQNGo2RIKseVj7SI/D5abQJQ/Os8hQ0NyVAyyVYF+Yjx5PphKgfhM5yoBwuwZUl6q71XPYEGNx7be6SA==", "integrity": "sha512-Cl7HJ1jhOfllwf0CRx1eB4ypRGMqdGKWpc0eSTXty7wWSvCdMZUhwfjQqu2bIOIlgYxg/gFu6TVmVZ6g4O8PlA==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/protocol-http": "^3.0.12", "@smithy/protocol-http": "^3.0.12",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
@@ -490,11 +490,11 @@
} }
}, },
"node_modules/@aws-sdk/middleware-logger": { "node_modules/@aws-sdk/middleware-logger": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.489.0.tgz",
"integrity": "sha512-O8IgJ0LHi5wTs5GlpI7nqmmSSagkVdd1shpGgQWY2h0kMSCII8CJZHBG97dlFFpGTvx5EDlhPNek7rl/6F4dRw==", "integrity": "sha512-+EVDnWese61MdImcBNAgz/AhTcIZJaska/xsU3GWU9CP905x4a4qZdB7fExFMDu1Jlz5pJqNteFYYHCFMJhHfg==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
}, },
@@ -503,11 +503,11 @@
} }
}, },
"node_modules/@aws-sdk/middleware-recursion-detection": { "node_modules/@aws-sdk/middleware-recursion-detection": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.489.0.tgz",
"integrity": "sha512-ZeVNATGNFcqkWDut3luVszROTUzkU5u+rJpB/xmeMoenlDAjPRiHt/ca3WkI5wAnIJ1VSNGpD2sOFLMCH+EWag==", "integrity": "sha512-m4rU+fTzziQcu9DKjRNZ4nQlXENEd2ZnJblJV4ONdWqqEjbmOgOj3P6aCCQlJdIbzuNvX1FBOZ5tY59ZpERo7Q==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/protocol-http": "^3.0.12", "@smithy/protocol-http": "^3.0.12",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
@@ -517,11 +517,11 @@
} }
}, },
"node_modules/@aws-sdk/middleware-signing": { "node_modules/@aws-sdk/middleware-signing": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.489.0.tgz",
"integrity": "sha512-41xzT2p1sOibhsLkdE5rwPJkNbBtKD8Gp36/ySfu0KE415wfXKacElSVxAaBw39/j7iSWDYqqybeEYbAzk+3GQ==", "integrity": "sha512-rlHcWYZn6Ym3v/u0DvKNDiD7ogIzEsHlerm0lowTiQbszkFobOiUClRTALwvsUZdAAztl706qO1OKbnGnD6Ubw==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/property-provider": "^2.0.0", "@smithy/property-provider": "^2.0.0",
"@smithy/protocol-http": "^3.0.12", "@smithy/protocol-http": "^3.0.12",
"@smithy/signature-v4": "^2.0.0", "@smithy/signature-v4": "^2.0.0",
@@ -534,12 +534,12 @@
} }
}, },
"node_modules/@aws-sdk/middleware-user-agent": { "node_modules/@aws-sdk/middleware-user-agent": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.489.0.tgz",
"integrity": "sha512-CddCVOn+OPQ0CcchketIg+WF6v+MDLAf3GOYTR2htUxxIm7HABuRd6R3kvQ5Jny9CV8gMt22G1UZITsFexSJlQ==", "integrity": "sha512-M54Cv2fAN3GGgdfUjLtZ4wFUIrfM/ivbXv4DgpcNsacEQ2g4H+weQgKp41X7XZW8MWAzl+k1zJaryK69RYNQkQ==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@aws-sdk/util-endpoints": "3.485.0", "@aws-sdk/util-endpoints": "3.489.0",
"@smithy/protocol-http": "^3.0.12", "@smithy/protocol-http": "^3.0.12",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
@@ -549,10 +549,11 @@
} }
}, },
"node_modules/@aws-sdk/region-config-resolver": { "node_modules/@aws-sdk/region-config-resolver": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.489.0.tgz",
"integrity": "sha512-2FB2EQ0sIE+YgFqGtkE1lDIMIL6nYe6MkOHBwBM7bommadKIrbbr2L22bPZGs3ReTsxiJabjzxbuCAVhrpHmhg==", "integrity": "sha512-UvrnB78XTz9ddby7mr0vuUHn2MO3VTjzaIu+GQhyedMGQU0QlIQrYOlzbbu4LC5rL1O8FxFLUxRe/AAjgwyuGw==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.489.0",
"@smithy/node-config-provider": "^2.1.9", "@smithy/node-config-provider": "^2.1.9",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"@smithy/util-config-provider": "^2.1.0", "@smithy/util-config-provider": "^2.1.0",
@@ -564,21 +565,21 @@
} }
}, },
"node_modules/@aws-sdk/token-providers": { "node_modules/@aws-sdk/token-providers": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.489.0.tgz",
"integrity": "sha512-kOXA1WKIVIFNRqHL8ynVZ3hCKLsgnEmGr2iDR6agDNw5fYIlCO/6N2xR6QdGcLTvUUbwOlz4OvKLUQnWMKAnnA==", "integrity": "sha512-hSgjB8CMQoA8EIQ0ripDjDtbBcWDSa+7vSBYPIzksyknaGERR/GUfGXLV2dpm5t17FgFG6irT5f3ZlBzarL8Dw==",
"dependencies": { "dependencies": {
"@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0", "@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/middleware-host-header": "3.485.0", "@aws-sdk/middleware-host-header": "3.489.0",
"@aws-sdk/middleware-logger": "3.485.0", "@aws-sdk/middleware-logger": "3.489.0",
"@aws-sdk/middleware-recursion-detection": "3.485.0", "@aws-sdk/middleware-recursion-detection": "3.489.0",
"@aws-sdk/middleware-user-agent": "3.485.0", "@aws-sdk/middleware-user-agent": "3.489.0",
"@aws-sdk/region-config-resolver": "3.485.0", "@aws-sdk/region-config-resolver": "3.489.0",
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@aws-sdk/util-endpoints": "3.485.0", "@aws-sdk/util-endpoints": "3.489.0",
"@aws-sdk/util-user-agent-browser": "3.485.0", "@aws-sdk/util-user-agent-browser": "3.489.0",
"@aws-sdk/util-user-agent-node": "3.485.0", "@aws-sdk/util-user-agent-node": "3.489.0",
"@smithy/config-resolver": "^2.0.23", "@smithy/config-resolver": "^2.0.23",
"@smithy/fetch-http-handler": "^2.3.2", "@smithy/fetch-http-handler": "^2.3.2",
"@smithy/hash-node": "^2.0.18", "@smithy/hash-node": "^2.0.18",
@@ -611,9 +612,9 @@
} }
}, },
"node_modules/@aws-sdk/types": { "node_modules/@aws-sdk/types": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.489.0.tgz",
"integrity": "sha512-+QW32YQdvZRDOwrAQPo/qCyXoSjgXB6RwJwCwkd8ebJXRXw6tmGKIHaZqYHt/LtBymvnaBgBBADNa4+qFvlOFw==", "integrity": "sha512-kcDtLfKog/p0tC4gAeqJqWxAiEzfe2LRPnKamvSG2Mjbthx4R/alE2dxyIq/wW+nvRv0fqR3OD5kD1+eVfdr/w==",
"dependencies": { "dependencies": {
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
@@ -623,11 +624,12 @@
} }
}, },
"node_modules/@aws-sdk/util-endpoints": { "node_modules/@aws-sdk/util-endpoints": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.489.0.tgz",
"integrity": "sha512-dTd642F7nJisApF8YjniqQ6U59CP/DCtar11fXf1nG9YNBCBsNNVw5ZfZb5nSNzaIdy27mQioWTCV18JEj1mxg==", "integrity": "sha512-uGyG1u84ATX03mf7bT4xD9XD/vlYJGD5+RxMN/UpzeTfzXfh+jvCQWbOQ44z8ttFJWYQQqrLxkfpF/JgvALzLA==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/types": "^2.8.0",
"@smithy/util-endpoints": "^1.0.8", "@smithy/util-endpoints": "^1.0.8",
"tslib": "^2.5.0" "tslib": "^2.5.0"
}, },
@@ -647,22 +649,22 @@
} }
}, },
"node_modules/@aws-sdk/util-user-agent-browser": { "node_modules/@aws-sdk/util-user-agent-browser": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.489.0.tgz",
"integrity": "sha512-QliWbjg0uOhGTcWgWTKPMY0SBi07g253DjwrCINT1auqDrdQPxa10xozpZExBYjAK2KuhYDNUzni127ae6MHOw==", "integrity": "sha512-85B9KMsuMpAZauzWQ16r52ZBAHYnznW6BVitnBglsibN7oJKn10Hggt4QGuRhvQFCxQ8YhvBl7r+vQGFO4hxIw==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"bowser": "^2.11.0", "bowser": "^2.11.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
} }
}, },
"node_modules/@aws-sdk/util-user-agent-node": { "node_modules/@aws-sdk/util-user-agent-node": {
"version": "3.485.0", "version": "3.489.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.485.0.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.489.0.tgz",
"integrity": "sha512-QF+aQ9jnDlPUlFBxBRqOylPf86xQuD3aEPpOErR+50qJawVvKa94uiAFdvtI9jv6hnRZmuFsTj2rsyytnbAYBA==", "integrity": "sha512-CYdkBHig8sFNc0dv11Ni9WXvZQHeI5+z77OrDHKkbidFx/V4BDTuwZw4K1vWg62pzFOEfzunJFiULRcDZWJR3w==",
"dependencies": { "dependencies": {
"@aws-sdk/types": "3.485.0", "@aws-sdk/types": "3.489.0",
"@smithy/node-config-provider": "^2.1.9", "@smithy/node-config-provider": "^2.1.9",
"@smithy/types": "^2.8.0", "@smithy/types": "^2.8.0",
"tslib": "^2.5.0" "tslib": "^2.5.0"
@@ -5657,9 +5659,9 @@
} }
}, },
"node_modules/socket.io": { "node_modules/socket.io": {
"version": "4.7.3", "version": "4.7.4",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.3.tgz", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz",
"integrity": "sha512-SE+UIQXBQE+GPG2oszWMlsEmWtHVqw/h1VrYJGK5/MC7CH5p58N448HwIrtREcvR4jfdOJAY4ieQfxMr55qbbw==", "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==",
"dependencies": { "dependencies": {
"accepts": "~1.3.4", "accepts": "~1.3.4",
"base64id": "~2.0.0", "base64id": "~2.0.0",

View File

@@ -17,9 +17,9 @@
"start": "node server.js" "start": "node server.js"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-secrets-manager": "^3.485.0", "@aws-sdk/client-secrets-manager": "^3.490.0",
"@aws-sdk/client-ses": "^3.485.0", "@aws-sdk/client-ses": "^3.490.0",
"@aws-sdk/credential-provider-node": "^3.485.0", "@aws-sdk/credential-provider-node": "^3.490.0",
"@opensearch-project/opensearch": "^2.5.0", "@opensearch-project/opensearch": "^2.5.0",
"aws4": "^1.12.0", "aws4": "^1.12.0",
"axios": "^1.6.5", "axios": "^1.6.5",
@@ -50,7 +50,7 @@
"nodemailer": "^6.9.8", "nodemailer": "^6.9.8",
"phone": "^3.1.42", "phone": "^3.1.42",
"soap": "^1.0.0", "soap": "^1.0.0",
"socket.io": "^4.7.3", "socket.io": "^4.7.4",
"ssh2-sftp-client": "^9.1.0", "ssh2-sftp-client": "^9.1.0",
"stripe": "^14.11.0", "stripe": "^14.11.0",
"twilio": "^4.20.0", "twilio": "^4.20.0",