Merged in test-beta (pull request #1306)

Test beta
This commit is contained in:
Dave Richer
2024-02-23 22:02:01 +00:00
25 changed files with 1939 additions and 1054 deletions

View File

@@ -3,6 +3,9 @@
This documentation details the schema required for `.filters` files on the report server. It is used to dynamically
modify the graphQL query and provide the user more power over their reports.
# Special Notes
- When passing the data to the template server, the property filters and sorters is added to the data object and will reflect the filters and sorters the user has selected
## High level Schema Overview
```javascript
@@ -36,6 +39,35 @@ const schema = {
Filters effect the where clause of the graphQL query. They are used to filter the data returned from the server.
A note on special notation used in the `name` field.
## Reflection
Filters can make use of reflection to pre-fill select boxes, the following is an example of that in the filters file.
```
{
"name": "jobs.status",
"translation": "jobs.fields.status",
"label": "Status",
"type": "string",
"reflector": {
"type": "internal",
"name": "special.job_statuses"
}
},
```
in this example, a reflector with the type 'internal' (all types at the moment require this, and it is used for future functionality), with a name of `special.job_statuses`
The following cases are available
- `special.job_statuses` - This will reflect the statuses of the jobs table `bodyshop.md_ro_statuses.statuses'`
- `special.cost_centers` - This will reflect the cost centers `bodyshop.md_responsibility_centers.costs`
- `special.categories` - This will reflect the categories `bodyshop.md_categories`
- `special.insurance_companies` - This will reflect the insurance companies `bodyshop.md_ins_cos`'
- `special.employee_teams` - This will reflect the employee teams `bodyshop.employee_teams`
- `special.employees` - This will reflect the employees `bodyshop.employees`
- `special.first_names` - This will reflect the first names `bodyshop.employees`
- `special.last_names` - This will reflect the last names `bodyshop.employees`
-
### Path without brackets, multi level
`"name": "jobs.joblines.mod_lb_hrs",`
@@ -124,3 +156,20 @@ query gendoc_hours_sold_detail_open($starttz: timestamptz!, $endtz: timestamptz!
would be added at the `joblines` level.
- Most of the reports currently do sorting on a template level, this will need to change to actually see the results
using the sorters.
### Default Sorters
- A sorter can be given a default object containing a `order` and `direction` key value. This will be used to sort the report if the user does not select any of the sorters themselves.
- The `order` key is the order in which the sorters are applied, and the `direction` key is the direction of the sort, either `asc` or `desc`.
```json
{
"name": "jobs.joblines.mod_lb_hrs",
"translation": "jobs.joblines.mod_lb_hrs_1",
"label": "mod_lb_hrs_1",
"type": "number",
"default": {
"order": 1,
"direction": "asc"
}
}
```

533
client/package-lock.json generated
View File

@@ -15,13 +15,13 @@
"@craco/craco": "^7.1.0",
"@fingerprintjs/fingerprintjs": "^4.2.2",
"@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.2.0",
"@reduxjs/toolkit": "^2.2.1",
"@sentry/cli": "^2.28.6",
"@sentry/react": "^7.101.0",
"@sentry/tracing": "^7.101.0",
"@sentry/react": "^7.102.1",
"@sentry/tracing": "^7.102.1",
"@splitsoftware/splitio-react": "^1.11.0",
"@tanem/react-nprogress": "^5.0.51",
"antd": "^5.14.1",
"antd": "^5.14.2",
"apollo-link-logger": "^2.0.1",
"apollo-link-sentry": "^3.3.0",
"axios": "^1.6.7",
@@ -29,17 +29,17 @@
"dayjs": "^1.11.10",
"dayjs-business-days2": "^1.2.2",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.4",
"dotenv": "^16.4.5",
"enquire-js": "^0.2.1",
"env-cmd": "^10.1.0",
"exifr": "^7.1.3",
"firebase": "^10.8.0",
"graphql": "^16.6.0",
"i18next": "^23.8.2",
"i18next": "^23.10.0",
"i18next-browser-languagedetector": "^7.0.2",
"jsoneditor": "^10.0.1",
"jsreport-browser-client-dist": "^1.3.0",
"libphonenumber-js": "^1.10.55",
"libphonenumber-js": "^1.10.57",
"logrocket": "^8.0.1",
"markerjs2": "^2.32.0",
"normalize-url": "^8.0.0",
@@ -50,9 +50,9 @@
"rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.7.6",
"react": "^18.2.0",
"react-big-calendar": "^1.10.1",
"react-big-calendar": "^1.10.3",
"react-color": "^2.19.3",
"react-cookie": "^7.0.2",
"react-cookie": "^7.1.0",
"react-dom": "^18.2.0",
"react-drag-listview": "^2.0.0",
"react-grid-gallery": "^1.0.0",
@@ -60,23 +60,23 @@
"react-i18next": "^14.0.5",
"react-icons": "^5.0.1",
"react-image-lightbox": "^5.1.4",
"react-intersection-observer": "^9.8.0",
"react-intersection-observer": "^9.8.1",
"react-markdown": "^9.0.1",
"react-number-format": "^5.1.4",
"react-redux": "^9.1.0",
"react-resizable": "^3.0.5",
"react-router-dom": "^6.22.0",
"react-router-dom": "^6.22.1",
"react-scripts": "^5.0.1",
"react-sticky": "^6.0.3",
"react-sublime-video": "^0.2.5",
"react-virtualized": "^9.22.5",
"recharts": "^2.12.0",
"recharts": "^2.12.1",
"redux": "^5.0.1",
"redux-persist": "^6.0.0",
"redux-saga": "^1.3.0",
"redux-state-sync": "^3.1.4",
"reselect": "^5.1.0",
"sass": "^1.70.0",
"sass": "^1.71.1",
"socket.io-client": "^4.7.4",
"styled-components": "^6.1.8",
"subscriptions-transport-ws": "^0.11.0",
@@ -88,13 +88,13 @@
"workbox-precaching": "^7.0.0",
"workbox-routing": "^7.0.0",
"workbox-strategies": "^7.0.0",
"yauzl": "^2.10.0"
"yauzl": "^3.1.0"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@sentry/webpack-plugin": "^2.14.0",
"@sentry/webpack-plugin": "^2.14.2",
"@testing-library/cypress": "^10.0.1",
"cypress": "^13.6.4",
"cypress": "^13.6.6",
"eslint-plugin-cypress": "^2.15.1",
"react-error-overlay": "6.0.11",
"redux-logger": "^3.0.6",
@@ -4200,9 +4200,9 @@
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
},
"node_modules/@rc-component/color-picker": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.1.tgz",
"integrity": "sha512-onyAFhWKXuG4P162xE+7IgaJkPkwM94XlOYnQuu69XdXWMfxpeFi6tpJBsieIMV7EnyLV5J3lDzdLiFeK0iEBA==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.2.tgz",
"integrity": "sha512-YJXujYzYFAEtlXJXy0yJUhwzUWPTcniBZto+wZ/vnACmFnUTNR7dH+NOeqSwMMsssh74e9H5Jfpr5LAH2PYqUw==",
"dependencies": {
"@babel/runtime": "^7.23.6",
"@ctrl/tinycolor": "^3.6.1",
@@ -4362,9 +4362,9 @@
"integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA=="
},
"node_modules/@reduxjs/toolkit": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.0.tgz",
"integrity": "sha512-ZvPYKfu4kDnAqPhJ1bsis8QFbiQRz3Q2HxW3tw9tVGusPzYKRG7ju1FA+34PGcwCoemjGGv+f/7fEygcRZIwmA==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.1.tgz",
"integrity": "sha512-8CREoqJovQW/5I4yvvijm/emUiCCmcs4Ev4XPWd4mizSO+dD3g5G6w34QK5AGeNrSH7qM8Fl66j4vuV7dpOdkw==",
"dependencies": {
"immer": "^10.0.3",
"redux": "^5.0.1",
@@ -4394,9 +4394,9 @@
}
},
"node_modules/@remix-run/router": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.0.tgz",
"integrity": "sha512-HOil5aFtme37dVQTB6M34G95kPM3MMuqSmIRVCC52eKV+Y/tGSqw9P3rWhlAx6A+mz+MoX+XxsGsNJbaI5qCgQ==",
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz",
"integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==",
"engines": {
"node": ">=14.0.0"
}
@@ -4500,189 +4500,173 @@
"integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA=="
},
"node_modules/@sentry-internal/feedback": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.101.0.tgz",
"integrity": "sha512-uQBMYhZp/qkBEA/GXRMm1OfSkRkZojxBrCrFmzkWhJzXT+YbL57/M1uCcwkKmorKlg393Soh7MLULInwmcwWkA==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.102.1.tgz",
"integrity": "sha512-vY4hpLLMNLjICtWiizc7KeGbWOTUMGrF7C+9dPCztZww3CLgzWy9A7DvPj5hodRiYzpdRnAMl8yQnMFbYXh7bA==",
"dependencies": {
"@sentry/core": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/core": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@sentry-internal/feedback/node_modules/@sentry/core": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.101.0.tgz",
"integrity": "sha512-dRNrNV5OLGARkOGgxJsVDhA98Pev5G1LVJcud5E83cRg49BCUx2riqEtDP6iIS1nvem6cApkSnLC1kvl/T5/Cw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.102.1.tgz",
"integrity": "sha512-QjY+LSP3du3J/C8x/FfEbRxgZgsWd0jfTJ4P7s9f219I1csK4OeBMC3UA1HwEa0pY/9OF6H/egW2CjOcMM5Pdg==",
"dependencies": {
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry-internal/feedback/node_modules/@sentry/types": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.101.0.tgz",
"integrity": "sha512-YC+ltO/AlbEyJHjCUYQ4is1HcDT2zSMuLkIAcyQmK7fUdlGT4iR5sfENriY9ZopYHgjPdJKfhI8ohScam7zp/A==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.102.1.tgz",
"integrity": "sha512-htKorf3t/D0XYtM7foTcmG+rM47rDP6XdbvCcX5gBCuCYlzpM1vqCt2rl3FLktZC6TaIpFRJw1TLfx6m+x5jdA==",
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry-internal/feedback/node_modules/@sentry/utils": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.101.0.tgz",
"integrity": "sha512-px1NUkCLsD9UKLE4W4DghpyzmAVHgYhskrjRt30ubyUKqlggtHkOXRvS8MjuWowR/i0wF0GuTCbU9StBd7JMrw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.102.1.tgz",
"integrity": "sha512-+8WcFjHVV/HROXSAwMuUzveElBFC43EiTG7SNEBNgOUeQzQVTmbUZXyTVgLrUmtoWqvnIxCacoLxtZo1o67kdg==",
"dependencies": {
"@sentry/types": "7.101.0"
"@sentry/types": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry-internal/replay-canvas": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.101.0.tgz",
"integrity": "sha512-fiz4kPpz/j6ZaD+vOcUXuO1HqD49djs4QwyTsRwCCi77EKZOGAaijpqWckDWyZs0dOOnbGGGC5x3o+CfTJcjKA==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.102.1.tgz",
"integrity": "sha512-GUX4RWI10uRjdjeyvCLtAAhWRVqnAnG6+yNxWfqUQ3qMA7B7XxG43KT2UhSnulmErNzODQ6hA68rGPwwYeRIww==",
"dependencies": {
"@sentry/core": "7.101.0",
"@sentry/replay": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/core": "7.102.1",
"@sentry/replay": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/core": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.101.0.tgz",
"integrity": "sha512-dRNrNV5OLGARkOGgxJsVDhA98Pev5G1LVJcud5E83cRg49BCUx2riqEtDP6iIS1nvem6cApkSnLC1kvl/T5/Cw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.102.1.tgz",
"integrity": "sha512-QjY+LSP3du3J/C8x/FfEbRxgZgsWd0jfTJ4P7s9f219I1csK4OeBMC3UA1HwEa0pY/9OF6H/egW2CjOcMM5Pdg==",
"dependencies": {
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/types": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.101.0.tgz",
"integrity": "sha512-YC+ltO/AlbEyJHjCUYQ4is1HcDT2zSMuLkIAcyQmK7fUdlGT4iR5sfENriY9ZopYHgjPdJKfhI8ohScam7zp/A==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.102.1.tgz",
"integrity": "sha512-htKorf3t/D0XYtM7foTcmG+rM47rDP6XdbvCcX5gBCuCYlzpM1vqCt2rl3FLktZC6TaIpFRJw1TLfx6m+x5jdA==",
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/utils": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.101.0.tgz",
"integrity": "sha512-px1NUkCLsD9UKLE4W4DghpyzmAVHgYhskrjRt30ubyUKqlggtHkOXRvS8MjuWowR/i0wF0GuTCbU9StBd7JMrw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.102.1.tgz",
"integrity": "sha512-+8WcFjHVV/HROXSAwMuUzveElBFC43EiTG7SNEBNgOUeQzQVTmbUZXyTVgLrUmtoWqvnIxCacoLxtZo1o67kdg==",
"dependencies": {
"@sentry/types": "7.101.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry-internal/tracing": {
"version": "7.100.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.100.0.tgz",
"integrity": "sha512-qf4W1STXky9WOQYoPSw2AmCBDK4FzvAyq5yeD2sLU7OCUEfbRUcN0lQljUvmWRKv/jTIAyeU5icDLJPZuR50nA==",
"dev": true,
"dependencies": {
"@sentry/core": "7.100.0",
"@sentry/types": "7.100.0",
"@sentry/utils": "7.100.0"
"@sentry/types": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/babel-plugin-component-annotate": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.14.0.tgz",
"integrity": "sha512-FWU4+Lx6fgxjAkwmc3S9j1Q/6pqKZyZzfi52B+8WMNw7a5QjGXgxc5ucBazZYgrcsJKCFBp4QG3PPxNAieFimQ==",
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.14.2.tgz",
"integrity": "sha512-mFBVnIZmdMrpxo61rG5yf0WFt5VrRpy8cpIpJtT3mYkX9vDmcUZaZaD1ctv73iZF3QwaieVdn05Na5mWzZ8h/A==",
"dev": true,
"engines": {
"node": ">= 14"
}
},
"node_modules/@sentry/browser": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.101.0.tgz",
"integrity": "sha512-wj9YLfS/caR20Yq0hdEjsZHuhnYLU7Ht0SlcJx5MNMnArtmW1k2CWZz3PCqcW/rTZe53npVTe6eMqMccB4aPrQ==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.102.1.tgz",
"integrity": "sha512-7BOfPBiM7Kp6q/iy0JIbsBTxIASV+zWXByqqjuEMWGj3X2u4oRIfm3gv4erPU/l+CORQUVQZLSPGoIoM1gbB/A==",
"dependencies": {
"@sentry-internal/feedback": "7.101.0",
"@sentry-internal/replay-canvas": "7.101.0",
"@sentry-internal/tracing": "7.101.0",
"@sentry/core": "7.101.0",
"@sentry/replay": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry-internal/feedback": "7.102.1",
"@sentry-internal/replay-canvas": "7.102.1",
"@sentry-internal/tracing": "7.102.1",
"@sentry/core": "7.102.1",
"@sentry/replay": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/browser/node_modules/@sentry-internal/tracing": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.101.0.tgz",
"integrity": "sha512-rp9oOLQs6vMuzvAnAHRRCNu5Z0o/ZVRI3WPYedxpdMWKD1Z3G9o+0joP+ZIUqHsamWWYiIgPqXgL9AK6AWjFRg==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.102.1.tgz",
"integrity": "sha512-RkFlFyAC0fQOvBbBqnq0CLmFW5m3JJz9pKbZd5vXPraWAlniKSb1bC/4DF9SlNx0FN1LWG+IU3ISdpzwwTeAGg==",
"dependencies": {
"@sentry/core": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/core": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/browser/node_modules/@sentry/core": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.101.0.tgz",
"integrity": "sha512-dRNrNV5OLGARkOGgxJsVDhA98Pev5G1LVJcud5E83cRg49BCUx2riqEtDP6iIS1nvem6cApkSnLC1kvl/T5/Cw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.102.1.tgz",
"integrity": "sha512-QjY+LSP3du3J/C8x/FfEbRxgZgsWd0jfTJ4P7s9f219I1csK4OeBMC3UA1HwEa0pY/9OF6H/egW2CjOcMM5Pdg==",
"dependencies": {
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/browser/node_modules/@sentry/types": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.101.0.tgz",
"integrity": "sha512-YC+ltO/AlbEyJHjCUYQ4is1HcDT2zSMuLkIAcyQmK7fUdlGT4iR5sfENriY9ZopYHgjPdJKfhI8ohScam7zp/A==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.102.1.tgz",
"integrity": "sha512-htKorf3t/D0XYtM7foTcmG+rM47rDP6XdbvCcX5gBCuCYlzpM1vqCt2rl3FLktZC6TaIpFRJw1TLfx6m+x5jdA==",
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/browser/node_modules/@sentry/utils": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.101.0.tgz",
"integrity": "sha512-px1NUkCLsD9UKLE4W4DghpyzmAVHgYhskrjRt30ubyUKqlggtHkOXRvS8MjuWowR/i0wF0GuTCbU9StBd7JMrw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.102.1.tgz",
"integrity": "sha512-+8WcFjHVV/HROXSAwMuUzveElBFC43EiTG7SNEBNgOUeQzQVTmbUZXyTVgLrUmtoWqvnIxCacoLxtZo1o67kdg==",
"dependencies": {
"@sentry/types": "7.101.0"
"@sentry/types": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/bundler-plugin-core": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.14.0.tgz",
"integrity": "sha512-jVM47EPs8Na2z5HOWgthLFhpHLU9hwL2wY4TzHEnS1Bj+ODgXFa8QcIxQR2SO+W+L8YhSbY7z+BpPsYTpeZWUg==",
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.14.2.tgz",
"integrity": "sha512-HgOFWYdq87lSmeVW1w8K2Vf2DGzRPvKzHTajZYLTPlrZ1jbajq9vwuqhrJ9AnDkjl0mjyzSPEy3ZTeG1Z7uRNA==",
"dev": true,
"dependencies": {
"@babel/core": "7.18.5",
"@sentry/babel-plugin-component-annotate": "2.14.0",
"@sentry/babel-plugin-component-annotate": "2.14.2",
"@sentry/cli": "^2.22.3",
"@sentry/node": "^7.60.0",
"@sentry/utils": "^7.60.0",
"dotenv": "^16.3.1",
"find-up": "5.0.0",
"glob": "9.3.2",
@@ -4874,43 +4858,15 @@
"node": ">=10"
}
},
"node_modules/@sentry/core": {
"version": "7.100.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.100.0.tgz",
"integrity": "sha512-eWRPuP0Zdj4a2F7SybqNjf13LGOVgGwvW6sojweQp9oxGAfCPp/EMDGBhlpYbMJeLbzmqzJ4ZFHIedaiEC+7kg==",
"dev": true,
"dependencies": {
"@sentry/types": "7.100.0",
"@sentry/utils": "7.100.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/node": {
"version": "7.100.0",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.100.0.tgz",
"integrity": "sha512-8cf9wFNo/9I++60MVAf6tuKn/N5JCZ/Z8NDUzutnWWdQBLSx+LhZYNPntN3WkHl6Q7PBHGw3mU1Bc+rF48MeSQ==",
"dev": true,
"dependencies": {
"@sentry-internal/tracing": "7.100.0",
"@sentry/core": "7.100.0",
"@sentry/types": "7.100.0",
"@sentry/utils": "7.100.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/react": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.101.0.tgz",
"integrity": "sha512-EjzkuUzLhE1glUsLPcLhmc8Wg7D5qfKQ08Vbcw+GsE7aLnhWrPTHexkf2NPNeTkgUxbWToJn6PWCodICo5YYbw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.102.1.tgz",
"integrity": "sha512-X4j2DgbktlEifnd21YJKCayAmff5hnaS+9MNz9OonEwD0ARi0ks7bo0wtWHMjPK20992MO+JwczVg/1BXJYDdQ==",
"dependencies": {
"@sentry/browser": "7.101.0",
"@sentry/core": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0",
"@sentry/browser": "7.102.1",
"@sentry/core": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1",
"hoist-non-react-statics": "^3.3.2"
},
"engines": {
@@ -4921,177 +4877,156 @@
}
},
"node_modules/@sentry/react/node_modules/@sentry/core": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.101.0.tgz",
"integrity": "sha512-dRNrNV5OLGARkOGgxJsVDhA98Pev5G1LVJcud5E83cRg49BCUx2riqEtDP6iIS1nvem6cApkSnLC1kvl/T5/Cw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.102.1.tgz",
"integrity": "sha512-QjY+LSP3du3J/C8x/FfEbRxgZgsWd0jfTJ4P7s9f219I1csK4OeBMC3UA1HwEa0pY/9OF6H/egW2CjOcMM5Pdg==",
"dependencies": {
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/react/node_modules/@sentry/types": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.101.0.tgz",
"integrity": "sha512-YC+ltO/AlbEyJHjCUYQ4is1HcDT2zSMuLkIAcyQmK7fUdlGT4iR5sfENriY9ZopYHgjPdJKfhI8ohScam7zp/A==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.102.1.tgz",
"integrity": "sha512-htKorf3t/D0XYtM7foTcmG+rM47rDP6XdbvCcX5gBCuCYlzpM1vqCt2rl3FLktZC6TaIpFRJw1TLfx6m+x5jdA==",
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/react/node_modules/@sentry/utils": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.101.0.tgz",
"integrity": "sha512-px1NUkCLsD9UKLE4W4DghpyzmAVHgYhskrjRt30ubyUKqlggtHkOXRvS8MjuWowR/i0wF0GuTCbU9StBd7JMrw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.102.1.tgz",
"integrity": "sha512-+8WcFjHVV/HROXSAwMuUzveElBFC43EiTG7SNEBNgOUeQzQVTmbUZXyTVgLrUmtoWqvnIxCacoLxtZo1o67kdg==",
"dependencies": {
"@sentry/types": "7.101.0"
"@sentry/types": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/replay": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.101.0.tgz",
"integrity": "sha512-DSWkGKI/QhCAY+qm4mBnPob3/YsewisskVTak7KMDotJ75H85WFJhVwOMtvaEWIzVezCOItPv7ql51jTwhR3wA==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.102.1.tgz",
"integrity": "sha512-HR/j9dGIvbrId8fh8mQlODx7JrhRmawEd9e9P3laPtogWCg/5TI+XPb2VGSaXOX9VWtb/6Z2UjHsaGjgg6YcuA==",
"dependencies": {
"@sentry-internal/tracing": "7.101.0",
"@sentry/core": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry-internal/tracing": "7.102.1",
"@sentry/core": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@sentry/replay/node_modules/@sentry-internal/tracing": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.101.0.tgz",
"integrity": "sha512-rp9oOLQs6vMuzvAnAHRRCNu5Z0o/ZVRI3WPYedxpdMWKD1Z3G9o+0joP+ZIUqHsamWWYiIgPqXgL9AK6AWjFRg==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.102.1.tgz",
"integrity": "sha512-RkFlFyAC0fQOvBbBqnq0CLmFW5m3JJz9pKbZd5vXPraWAlniKSb1bC/4DF9SlNx0FN1LWG+IU3ISdpzwwTeAGg==",
"dependencies": {
"@sentry/core": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/core": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/replay/node_modules/@sentry/core": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.101.0.tgz",
"integrity": "sha512-dRNrNV5OLGARkOGgxJsVDhA98Pev5G1LVJcud5E83cRg49BCUx2riqEtDP6iIS1nvem6cApkSnLC1kvl/T5/Cw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.102.1.tgz",
"integrity": "sha512-QjY+LSP3du3J/C8x/FfEbRxgZgsWd0jfTJ4P7s9f219I1csK4OeBMC3UA1HwEa0pY/9OF6H/egW2CjOcMM5Pdg==",
"dependencies": {
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/replay/node_modules/@sentry/types": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.101.0.tgz",
"integrity": "sha512-YC+ltO/AlbEyJHjCUYQ4is1HcDT2zSMuLkIAcyQmK7fUdlGT4iR5sfENriY9ZopYHgjPdJKfhI8ohScam7zp/A==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.102.1.tgz",
"integrity": "sha512-htKorf3t/D0XYtM7foTcmG+rM47rDP6XdbvCcX5gBCuCYlzpM1vqCt2rl3FLktZC6TaIpFRJw1TLfx6m+x5jdA==",
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/replay/node_modules/@sentry/utils": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.101.0.tgz",
"integrity": "sha512-px1NUkCLsD9UKLE4W4DghpyzmAVHgYhskrjRt30ubyUKqlggtHkOXRvS8MjuWowR/i0wF0GuTCbU9StBd7JMrw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.102.1.tgz",
"integrity": "sha512-+8WcFjHVV/HROXSAwMuUzveElBFC43EiTG7SNEBNgOUeQzQVTmbUZXyTVgLrUmtoWqvnIxCacoLxtZo1o67kdg==",
"dependencies": {
"@sentry/types": "7.101.0"
"@sentry/types": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/tracing": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.101.0.tgz",
"integrity": "sha512-/TRn3KRuRAamCstw8rRVyL5nlXlL+zf9QNN4IxGFwc7lka8c4d7i5neIWaOrUQvrAlh2gbxbHwt7POIguoed2g==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.102.1.tgz",
"integrity": "sha512-9VQEox0R7ouhhUVHtBwlGlXG5beDCM/Uo0BY+G0M1H03aFJsLAwnxPNeWnK3WvPejxf94EgdimKMjDjv9l2Sbg==",
"dependencies": {
"@sentry-internal/tracing": "7.101.0"
"@sentry-internal/tracing": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/tracing/node_modules/@sentry-internal/tracing": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.101.0.tgz",
"integrity": "sha512-rp9oOLQs6vMuzvAnAHRRCNu5Z0o/ZVRI3WPYedxpdMWKD1Z3G9o+0joP+ZIUqHsamWWYiIgPqXgL9AK6AWjFRg==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.102.1.tgz",
"integrity": "sha512-RkFlFyAC0fQOvBbBqnq0CLmFW5m3JJz9pKbZd5vXPraWAlniKSb1bC/4DF9SlNx0FN1LWG+IU3ISdpzwwTeAGg==",
"dependencies": {
"@sentry/core": "7.101.0",
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/core": "7.102.1",
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/tracing/node_modules/@sentry/core": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.101.0.tgz",
"integrity": "sha512-dRNrNV5OLGARkOGgxJsVDhA98Pev5G1LVJcud5E83cRg49BCUx2riqEtDP6iIS1nvem6cApkSnLC1kvl/T5/Cw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.102.1.tgz",
"integrity": "sha512-QjY+LSP3du3J/C8x/FfEbRxgZgsWd0jfTJ4P7s9f219I1csK4OeBMC3UA1HwEa0pY/9OF6H/egW2CjOcMM5Pdg==",
"dependencies": {
"@sentry/types": "7.101.0",
"@sentry/utils": "7.101.0"
"@sentry/types": "7.102.1",
"@sentry/utils": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/tracing/node_modules/@sentry/types": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.101.0.tgz",
"integrity": "sha512-YC+ltO/AlbEyJHjCUYQ4is1HcDT2zSMuLkIAcyQmK7fUdlGT4iR5sfENriY9ZopYHgjPdJKfhI8ohScam7zp/A==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.102.1.tgz",
"integrity": "sha512-htKorf3t/D0XYtM7foTcmG+rM47rDP6XdbvCcX5gBCuCYlzpM1vqCt2rl3FLktZC6TaIpFRJw1TLfx6m+x5jdA==",
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/tracing/node_modules/@sentry/utils": {
"version": "7.101.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.101.0.tgz",
"integrity": "sha512-px1NUkCLsD9UKLE4W4DghpyzmAVHgYhskrjRt30ubyUKqlggtHkOXRvS8MjuWowR/i0wF0GuTCbU9StBd7JMrw==",
"version": "7.102.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.102.1.tgz",
"integrity": "sha512-+8WcFjHVV/HROXSAwMuUzveElBFC43EiTG7SNEBNgOUeQzQVTmbUZXyTVgLrUmtoWqvnIxCacoLxtZo1o67kdg==",
"dependencies": {
"@sentry/types": "7.101.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/types": {
"version": "7.100.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.100.0.tgz",
"integrity": "sha512-c+RHwZwpKeBk7h8sUX4nQcelxBz8ViCojifnbEe3tcn8O15HOLvZqRKgLLOiff3MoErxiv4oxs0sPbEFRm/IvA==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/utils": {
"version": "7.100.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.100.0.tgz",
"integrity": "sha512-LAhZMEGq3C125prZN/ShqeXpRfdfgJkl9RAKjfq8cmMFsF7nsF72dEHZgIwrZ0lgNmtaWAB83AwJcyN83RwOxQ==",
"dev": true,
"dependencies": {
"@sentry/types": "7.100.0"
"@sentry/types": "7.102.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/webpack-plugin": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-2.14.0.tgz",
"integrity": "sha512-6lYxabSSkoMqz+zsACamYfu8amLSIiYFj+CQBLvWKSW7N6wJvaZKfFVHj5bGlmU7K0X0eJyQdxdk6VfLg129Jw==",
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-2.14.2.tgz",
"integrity": "sha512-BEWF5qerGG/xX0ixEOCYh9gCkc+FHDzXxRMCFkM8yQNGH361ELF578KtuoZxXDy0kWa9QGZxSoP6/HZSnJEF9A==",
"dev": true,
"dependencies": {
"@sentry/bundler-plugin-core": "2.14.0",
"@sentry/bundler-plugin-core": "2.14.2",
"unplugin": "1.0.1",
"uuid": "^9.0.0"
},
@@ -6681,16 +6616,16 @@
}
},
"node_modules/antd": {
"version": "5.14.1",
"resolved": "https://registry.npmjs.org/antd/-/antd-5.14.1.tgz",
"integrity": "sha512-P0Bwt9NKSZqnEJ0QAyAb13ay34FjOKsz+KEp/ts+feYsynhUxF7/Ay6d1jS6ZcNpcs+JWTlLKO59YFZ3tX07wQ==",
"version": "5.14.2",
"resolved": "https://registry.npmjs.org/antd/-/antd-5.14.2.tgz",
"integrity": "sha512-ur0oBI9U7hAeON4ZRs1cAF1suIpTR+uj3YliTZacWkiVxNTZYPaaTdnLuAZDRMT9P2IZ007dCQTqxn5t1Z+Dxw==",
"dependencies": {
"@ant-design/colors": "^7.0.2",
"@ant-design/cssinjs": "^1.18.4",
"@ant-design/icons": "^5.3.0",
"@ant-design/react-slick": "~1.0.2",
"@ctrl/tinycolor": "^3.6.1",
"@rc-component/color-picker": "~1.5.1",
"@rc-component/color-picker": "~1.5.2",
"@rc-component/mutate-observer": "^1.1.0",
"@rc-component/tour": "~1.12.3",
"@rc-component/trigger": "^1.18.3",
@@ -6713,7 +6648,7 @@
"rc-motion": "^2.9.0",
"rc-notification": "~5.3.0",
"rc-pagination": "~4.0.4",
"rc-picker": "~4.1.1",
"rc-picker": "~4.1.4",
"rc-progress": "~3.5.1",
"rc-rate": "~2.12.0",
"rc-resize-observer": "^1.4.0",
@@ -6729,7 +6664,7 @@
"rc-tree": "~5.8.5",
"rc-tree-select": "~5.17.0",
"rc-upload": "~4.5.2",
"rc-util": "^5.38.1",
"rc-util": "^5.38.2",
"scroll-into-view-if-needed": "^3.1.0",
"throttle-debounce": "^5.0.0"
},
@@ -8928,9 +8863,9 @@
"integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw=="
},
"node_modules/cypress": {
"version": "13.6.4",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.4.tgz",
"integrity": "sha512-pYJjCfDYB+hoOoZuhysbbYhEmNW7DEDsqn+ToCLwuVowxUXppIWRr7qk4TVRIU471ksfzyZcH+mkoF0CQUKnpw==",
"version": "13.6.6",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.6.tgz",
"integrity": "sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -8941,7 +8876,7 @@
"arch": "^2.2.0",
"blob-util": "^2.0.2",
"bluebird": "^3.7.2",
"buffer": "^5.6.0",
"buffer": "^5.7.1",
"cachedir": "^2.3.0",
"chalk": "^4.1.0",
"check-more-types": "^2.24.0",
@@ -8959,7 +8894,7 @@
"figures": "^3.2.0",
"fs-extra": "^9.1.0",
"getos": "^3.2.1",
"is-ci": "^3.0.0",
"is-ci": "^3.0.1",
"is-installed-globally": "~0.4.0",
"lazy-ass": "^1.6.0",
"listr2": "^3.8.3",
@@ -9005,6 +8940,16 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/cypress/node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"dev": true,
"dependencies": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
},
"node_modules/d3-array": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
@@ -9708,9 +9653,9 @@
}
},
"node_modules/dotenv": {
"version": "16.4.4",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz",
"integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==",
"version": "16.4.5",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
"engines": {
"node": ">=12"
},
@@ -11003,6 +10948,16 @@
"@types/yauzl": "^2.9.1"
}
},
"node_modules/extract-zip/node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"dev": true,
"dependencies": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
},
"node_modules/extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -11092,6 +11047,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"dev": true,
"dependencies": {
"pend": "~1.2.0"
}
@@ -12318,9 +12274,9 @@
}
},
"node_modules/i18next": {
"version": "23.8.2",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.8.2.tgz",
"integrity": "sha512-Z84zyEangrlERm0ZugVy4bIt485e/H8VecGUZkZWrH7BDePG6jT73QdL9EA1tRTTVVMpry/MgWIP1FjEn0DRXA==",
"version": "23.10.0",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.0.tgz",
"integrity": "sha512-/TgHOqsa7/9abUKJjdPeydoyDc0oTi/7u9F8lMSj6ufg4cbC1Oj3f/Jja7zj7WRIhEQKB7Q4eN6y68I9RDxxGQ==",
"funding": [
{
"type": "individual",
@@ -14745,9 +14701,9 @@
}
},
"node_modules/libphonenumber-js": {
"version": "1.10.55",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.55.tgz",
"integrity": "sha512-MrTg2JFLscgmTY6/oT9vopYETlgUls/FU6OaeeamGwk4LFxjIgOUML/ZSZICgR0LPYXaonVJo40lzMvaaTJlQA=="
"version": "1.10.57",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.57.tgz",
"integrity": "sha512-OjsEd9y4LgcX+Ig09SbxWqcGESxliDDFNVepFhB9KEsQZTrnk3UdEU+cO0sW1APvLprHstQpS23OQpZ3bwxy6Q=="
},
"node_modules/lilconfig": {
"version": "2.1.0",
@@ -18632,9 +18588,9 @@
}
},
"node_modules/rc-picker": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.1.1.tgz",
"integrity": "sha512-H99qaHUepHjHnAqMLiftJEATXRuHJZcUyFoRkyIqUvTHVGnx/uHxFFNm7QIu1valCpfwdsGWQxiWgn9CAxvlvA==",
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.1.4.tgz",
"integrity": "sha512-sAdgj1kW9wvuoS5p2Zw3pT52iUYxidYaqXVLooaKxTqgYbhe8cG8Ld3b8cgwYfKrIkm/j+qp9nDQlrFPSl16lQ==",
"dependencies": {
"@babel/runtime": "^7.10.1",
"@rc-component/trigger": "^1.5.0",
@@ -18959,9 +18915,9 @@
}
},
"node_modules/rc-util": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.1.tgz",
"integrity": "sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng==",
"version": "5.38.2",
"resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.2.tgz",
"integrity": "sha512-yRGRPKyi84H7NkRSP6FzEIYBdUt4ufdsmXUZ7qM2H5qoByPax70NnGPkfo36N+UKUnUBj2f2Q2eUbwYMuAsIOQ==",
"dependencies": {
"@babel/runtime": "^7.18.3",
"react-is": "^18.2.0"
@@ -19092,9 +19048,9 @@
}
},
"node_modules/react-big-calendar": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.10.1.tgz",
"integrity": "sha512-VRa6FkjGDqGrO9A9hWqwtEq1x3hL7oz1JG8NCjdV0O7TZ8lCFef/tJNUbidjlWj9FS1PxA7y94sAYDSsGUDa1w==",
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.10.3.tgz",
"integrity": "sha512-LmIWlFfGUn8yt4RxcVkGNmjM3GcWynr1bfDwKrrz4KKj517+DH3OGmQzErURN6Zb0OB88HF4oH2dvDHpBQJgIw==",
"dependencies": {
"@babel/runtime": "^7.20.7",
"clsx": "^1.2.1",
@@ -19141,9 +19097,9 @@
}
},
"node_modules/react-cookie": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-7.0.2.tgz",
"integrity": "sha512-UnW1rZw1VibRdTvV8Ksr0BKKZoajeUxYLE89sIygDeyQgtz6ik89RHOM+3kib36G9M7HxheORggPoLk5DxAK7Q==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-7.1.0.tgz",
"integrity": "sha512-n2+Gt07/xxuShXary+SImk1sw5l7a1UguQOQEN55YewEW5LoA0opbR4nbeo8sY6OYwR37iCFJtqJ0AGEywqAtg==",
"dependencies": {
"@types/hoist-non-react-statics": "^3.3.5",
"hoist-non-react-statics": "^3.3.2",
@@ -19313,9 +19269,9 @@
}
},
"node_modules/react-intersection-observer": {
"version": "9.8.0",
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.8.0.tgz",
"integrity": "sha512-wXHvMQUsTagh3X0Z6jDtGkIXc3VVCd2tjDRYR9kII3GKrZr0XF0xtpfdamo2n8BSF+zzfeeBVOTjxZWpBp9X0g==",
"version": "9.8.1",
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.8.1.tgz",
"integrity": "sha512-QzOFdROX8D8MH3wE3OVKH0f3mLjKTtEN1VX/rkNuECCff+aKky0pIjulDhr3Ewqj5el/L+MhBkM3ef0Tbt+qUQ==",
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
@@ -19457,11 +19413,11 @@
}
},
"node_modules/react-router": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.0.tgz",
"integrity": "sha512-q2yemJeg6gw/YixRlRnVx6IRJWZD6fonnfZhN1JIOhV2iJCPeRNSH3V1ISwHf+JWcESzLC3BOLD1T07tmO5dmg==",
"version": "6.22.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz",
"integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==",
"dependencies": {
"@remix-run/router": "1.15.0"
"@remix-run/router": "1.15.1"
},
"engines": {
"node": ">=14.0.0"
@@ -19471,12 +19427,12 @@
}
},
"node_modules/react-router-dom": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.0.tgz",
"integrity": "sha512-z2w+M4tH5wlcLmH3BMMOMdrtrJ9T3oJJNsAlBJbwk+8Syxd5WFJ7J5dxMEW0/GEXD1BBis4uXRrNIz3mORr0ag==",
"version": "6.22.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz",
"integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==",
"dependencies": {
"@remix-run/router": "1.15.0",
"react-router": "6.22.0"
"@remix-run/router": "1.15.1",
"react-router": "6.22.1"
},
"engines": {
"node": ">=14.0.0"
@@ -19706,13 +19662,13 @@
}
},
"node_modules/recharts": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.0.tgz",
"integrity": "sha512-rVNcdNQ5b7+40Ue7mcEKZJyEv+3SUk2bDEVvOyXPDXXVE7TU3lrvnJUgAvO36hSzhRP2DnAamKXvHLFIFOU0Ww==",
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.1.tgz",
"integrity": "sha512-35vUCEBPf+pM+iVgSgVTn86faKya5pc4JO6cYJL63qOK2zDEyzDn20Tdj+CDI/3z+VcpKyQ8ZBQ9OiQ+vuAbjg==",
"dependencies": {
"clsx": "^2.0.0",
"eventemitter3": "^4.0.1",
"lodash": "^4.17.19",
"lodash": "^4.17.21",
"react-is": "^16.10.2",
"react-smooth": "^4.0.0",
"recharts-scale": "^0.4.4",
@@ -20394,9 +20350,9 @@
"integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA=="
},
"node_modules/sass": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
"integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
"version": "1.71.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz",
"integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==",
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
@@ -24206,12 +24162,15 @@
}
},
"node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.0.tgz",
"integrity": "sha512-zbff6SaAPyewVextulqeBjJm+1ZhS69vSN7cRpqVD7jMNSE9oXEdQ1SGF+ydfB+gKE2a3GiWfXf/pnwVZ1/tOA==",
"dependencies": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
"pend": "~1.2.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/yn": {

View File

@@ -11,13 +11,13 @@
"@craco/craco": "^7.1.0",
"@fingerprintjs/fingerprintjs": "^4.2.2",
"@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.2.0",
"@reduxjs/toolkit": "^2.2.1",
"@sentry/cli": "^2.28.6",
"@sentry/react": "^7.101.0",
"@sentry/tracing": "^7.101.0",
"@sentry/react": "^7.102.1",
"@sentry/tracing": "^7.102.1",
"@splitsoftware/splitio-react": "^1.11.0",
"@tanem/react-nprogress": "^5.0.51",
"antd": "^5.14.1",
"antd": "^5.14.2",
"apollo-link-logger": "^2.0.1",
"apollo-link-sentry": "^3.3.0",
"axios": "^1.6.7",
@@ -25,17 +25,17 @@
"dayjs": "^1.11.10",
"dayjs-business-days2": "^1.2.2",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.4",
"dotenv": "^16.4.5",
"enquire-js": "^0.2.1",
"env-cmd": "^10.1.0",
"exifr": "^7.1.3",
"firebase": "^10.8.0",
"graphql": "^16.6.0",
"i18next": "^23.8.2",
"i18next": "^23.10.0",
"i18next-browser-languagedetector": "^7.0.2",
"jsoneditor": "^10.0.1",
"jsreport-browser-client-dist": "^1.3.0",
"libphonenumber-js": "^1.10.55",
"libphonenumber-js": "^1.10.57",
"logrocket": "^8.0.1",
"markerjs2": "^2.32.0",
"normalize-url": "^8.0.0",
@@ -46,9 +46,9 @@
"rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.7.6",
"react": "^18.2.0",
"react-big-calendar": "^1.10.1",
"react-big-calendar": "^1.10.3",
"react-color": "^2.19.3",
"react-cookie": "^7.0.2",
"react-cookie": "^7.1.0",
"react-dom": "^18.2.0",
"react-drag-listview": "^2.0.0",
"react-grid-gallery": "^1.0.0",
@@ -56,23 +56,23 @@
"react-i18next": "^14.0.5",
"react-icons": "^5.0.1",
"react-image-lightbox": "^5.1.4",
"react-intersection-observer": "^9.8.0",
"react-intersection-observer": "^9.8.1",
"react-markdown": "^9.0.1",
"react-number-format": "^5.1.4",
"react-redux": "^9.1.0",
"react-resizable": "^3.0.5",
"react-router-dom": "^6.22.0",
"react-router-dom": "^6.22.1",
"react-scripts": "^5.0.1",
"react-sticky": "^6.0.3",
"react-sublime-video": "^0.2.5",
"react-virtualized": "^9.22.5",
"recharts": "^2.12.0",
"recharts": "^2.12.1",
"redux": "^5.0.1",
"redux-persist": "^6.0.0",
"redux-saga": "^1.3.0",
"redux-state-sync": "^3.1.4",
"reselect": "^5.1.0",
"sass": "^1.70.0",
"sass": "^1.71.1",
"socket.io-client": "^4.7.4",
"styled-components": "^6.1.8",
"subscriptions-transport-ws": "^0.11.0",
@@ -84,7 +84,7 @@
"workbox-precaching": "^7.0.0",
"workbox-routing": "^7.0.0",
"workbox-strategies": "^7.0.0",
"yauzl": "^2.10.0"
"yauzl": "^3.1.0"
},
"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
@@ -123,9 +123,9 @@
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@sentry/webpack-plugin": "^2.14.0",
"@sentry/webpack-plugin": "^2.14.2",
"@testing-library/cypress": "^10.0.1",
"cypress": "^13.6.4",
"cypress": "^13.6.6",
"eslint-plugin-cypress": "^2.15.1",
"react-error-overlay": "6.0.11",
"redux-logger": "^3.0.6",

View File

@@ -66,7 +66,30 @@ export default function ContractFormComponent({
<FormDateTimePicker/>
</Form.Item>
)}
</LayoutFormRow>
{create && (
<Form.Item
shouldUpdate={(p, c) => p.scheduledreturn !== c.scheduledreturn}
>
{() => {
const insuranceOver =
selectedCar &&
selectedCar.insuranceexpires &&
dayjs(selectedCar.insuranceexpires)
.endOf("day")
.isBefore(dayjs(form.getFieldValue("scheduledreturn")));
if (insuranceOver)
return (
<Space direction="vertical" style={{color: "tomato"}}>
<span>
<WarningFilled style={{marginRight: ".3rem"}}/>
{t("contracts.labels.insuranceexpired")}
</span>
</Space>
);
return <></>;
}}
</Form.Item>
)}</LayoutFormRow>
<LayoutFormRow grow>
<Form.Item
label={t("contracts.fields.kmstart")}
@@ -88,16 +111,17 @@ export default function ContractFormComponent({
>
{() => {
const mileageOver =
selectedCar &&
selectedCar.nextservicekm <= form.getFieldValue("kmstart");
selectedCar && selectedCar.nextservicekm
? selectedCar.nextservicekm <= form.getFieldValue("kmstart")
: false;
const dueForService =
selectedCar &&
selectedCar.nextservicedate &&
dayjs(selectedCar.nextservicedate).isBefore(
dayjs(selectedCar.nextservicedate)
.endOf("day")
.isSameOrBefore(
dayjs(form.getFieldValue("scheduledreturn"))
);
);
if (mileageOver || dueForService)
return (
<Space direction="vertical" style={{color: "tomato"}}>

View File

@@ -64,18 +64,29 @@ export default function CourtesyCarsList({loading, courtesycars, refetch}) {
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
render: (text, record) => {
const {nextservicedate, nextservicekm, mileage} = record;
const {nextservicedate, nextservicekm, mileage, insuranceexpires} =
record;
const mileageOver = nextservicekm ? nextservicekm <= mileage : false;
const dueForService =
nextservicedate && dayjs(nextservicedate).endOf('day').isSameOrBefore(dayjs());
const insuranceOver =
insuranceexpires &&
dayjs(insuranceexpires).endOf("day").isBefore(dayjs());
return (
<Space>
{t(record.status)}
{(mileageOver || dueForService) && (
<Tooltip title={t("contracts.labels.cardueforservice")}>
{(mileageOver || dueForService || insuranceOver) && (
<Tooltip title={(mileageOver || dueForService) && insuranceOver
? t("contracts.labels.insuranceexpired") +
" / " +
t("contracts.labels.cardueforservice")
: insuranceOver
? t("contracts.labels.insuranceexpired")
: t("contracts.labels.cardueforservice")
}>
<WarningFilled style={{color: "tomato"}}/>
</Tooltip>
)}

View File

@@ -1,221 +1,469 @@
import {BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined,} from "@ant-design/icons";
import {Card, Space, Table, Tooltip} from "antd";
import dayjs from "../../../utils/day";
import React, {useState} from "react";
import {useTranslation} from "react-i18next";
import {Link} from "react-router-dom";
import {
BranchesOutlined,
ExclamationCircleFilled,
PauseCircleOutlined,
} from "@ant-design/icons";
import { Card, Space, Switch, Table, Tooltip, Typography } from "antd";
import moment from "moment";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { TimeFormatter } from "../../../utils/DateFormatter";
import { onlyUnique } from "../../../utils/arrayHelper";
import { alphaSort, dateSort } from "../../../utils/sorters";
import useLocalStorage from "../../../utils/useLocalStorage";
import ChatOpenButton from "../../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../../owner-name-display/owner-name-display.component";
import OwnerNameDisplay, {
OwnerNameDisplayFunction,
} from "../../owner-name-display/owner-name-display.component";
import DashboardRefreshRequired from "../refresh-required.component";
import {pageLimit} from "../../../utils/config";
export default function DashboardScheduledInToday({data, ...cardProps}) {
const {t} = useTranslation();
const [state, setState] = useState({
sortedInfo: {},
});
if (!data) return null;
if (!data.scheduled_in_today)
return <DashboardRefreshRequired {...cardProps} />;
export default function DashboardScheduledInToday({ data, ...cardProps }) {
const { t } = useTranslation();
const [state, setState] = useState({
sortedInfo: {},
filteredInfo: {},
});
const appt = []; // Flatten Data
data.scheduled_in_today.forEach((item) => {
if (item.job) {
var i = {
canceled: item.canceled,
id: item.id,
alt_transport: item.job.alt_transport,
clm_no: item.job.clm_no,
jobid: item.job.jobid,
ins_co_nm: item.job.ins_co_nm,
iouparent: item.job.iouparent,
ownerid: item.job.ownerid,
ownr_co_nm: item.job.ownr_co_nm,
ownr_ea: item.job.ownr_ea,
ownr_fn: item.job.ownr_fn,
ownr_ln: item.job.ownr_ln,
ownr_ph1: item.job.ownr_ph1,
ownr_ph2: item.job.ownr_ph2,
production_vars: item.job.production_vars,
ro_number: item.job.ro_number,
suspended: item.job.suspended,
v_make_desc: item.job.v_make_desc,
v_model_desc: item.job.v_model_desc,
v_model_yr: item.job.v_model_yr,
v_vin: item.job.v_vin,
vehicleid: item.job.vehicleid,
note: item.note,
start: dayjs(item.start).format("hh:mm a"),
title: item.title,
};
appt.push(i);
}
});
appt.sort(function (a, b) {
return new dayjs(a.start) - new dayjs(b.start);
});
const [isTvModeScheduledIn, setIsTvModeScheduledIn] = useLocalStorage(
"isTvModeScheduledIn",
false
);
const columns = [
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
>
<Space>
{record.ro_number || t("general.labels.na")}
{record.production_vars && record.production_vars.alert ? (
<ExclamationCircleFilled className="production-alert"/>
) : null}
{record.suspended && (
<PauseCircleOutlined style={{color: "orangered"}}/>
)}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{color: "orangered"}}/>
</Tooltip>
)}
</Space>
</Link>
),
},
{
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
responsive: ["md"],
render: (text, record) => {
return record.ownerid ? (
<Link
to={"/manage/owners/" + record.ownerid}
onClick={(e) => e.stopPropagation()}
>
<OwnerNameDisplay ownerObject={record}/>
</Link>
) : (
<span>
<OwnerNameDisplay ownerObject={record}/>
</span>
);
},
},
{
title: t("jobs.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid}/>
),
},
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid}/>
),
},
{
title: t("jobs.fields.ownr_ea"),
dataIndex: "ownr_ea",
key: "ownr_ea",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ea} jobid={record.jobid}/>
),
},
{
title: t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
onClick={(e) => e.stopPropagation()}
>
{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}
</Link>
) : (
<span>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}</span>
);
},
},
{
title: t("jobs.fields.ins_co_nm"),
dataIndex: "ins_co_nm",
key: "ins_co_nm",
ellipsis: true,
responsive: ["md"],
},
{
title: t("appointments.fields.time"),
dataIndex: "start",
key: "start",
ellipsis: true,
responsive: ["md"],
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
responsive: ["md"],
},
];
if (!data) return null;
if (!data.scheduled_in_today)
return <DashboardRefreshRequired {...cardProps} />;
const handleTableChange = (sorter) => {
setState({...state, sortedInfo: sorter});
};
const appt = []; // Flatten Data
data.scheduled_in_today.forEach((item) => {
if (item.job) {
var i = {
canceled: item.canceled,
id: item.id,
alt_transport: item.job.alt_transport,
clm_no: item.job.clm_no,
jobid: item.job.jobid,
joblines_body: item.job.joblines
.filter((l) => l.mod_lbr_ty !== "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0),
joblines_ref: item.job.joblines
.filter((l) => l.mod_lbr_ty === "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0),
ins_co_nm: item.job.ins_co_nm,
iouparent: item.job.iouparent,
ownerid: item.job.ownerid,
ownr_co_nm: item.job.ownr_co_nm,
ownr_ea: item.job.ownr_ea,
ownr_fn: item.job.ownr_fn,
ownr_ln: item.job.ownr_ln,
ownr_ph1: item.job.ownr_ph1,
ownr_ph2: item.job.ownr_ph2,
production_vars: item.job.production_vars,
ro_number: item.job.ro_number,
suspended: item.job.suspended,
v_make_desc: item.job.v_make_desc,
v_model_desc: item.job.v_model_desc,
v_model_yr: item.job.v_model_yr,
v_vin: item.job.v_vin,
vehicleid: item.job.vehicleid,
note: item.note,
start: item.start,
title: item.title,
};
appt.push(i);
}
});
appt.sort(function (a, b) {
return new moment(a.start) - new moment(b.start);
});
return (
<Card
title={t("dashboard.titles.scheduledintoday", {
date: dayjs().startOf("day").format("MM/DD/YYYY"),
})}
{...cardProps}
const tvFontSize = 16;
const tvFontWeight = "bold";
const tvColumns = [
{
title: t("appointments.fields.time"),
dataIndex: "start",
key: "start",
ellipsis: true,
sorter: (a, b) => dateSort(a.start, b.start),
sortOrder:
state.sortedInfo.columnKey === "start" && state.sortedInfo.order,
render: (text, record) => (
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
<TimeFormatter>{record.start}</TimeFormatter>
</span>
),
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
>
<div style={{height: "100%"}}>
<Table
onChange={handleTableChange}
pagination={{position: "top", defaultPageSize: pageLimit}}
columns={columns}
scroll={{x: true, y: "calc(100% - 2em)"}}
rowKey="id"
style={{height: "85%"}}
dataSource={appt}
/>
</div>
</Card>
);
<Space>
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
{record.ro_number || t("general.labels.na")}
{record.production_vars && record.production_vars.alert ? (
<ExclamationCircleFilled className="production-alert" />
) : null}
{record.suspended && (
<PauseCircleOutlined style={{ color: "orangered" }} />
)}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{ color: "orangered" }} />
</Tooltip>
)}
</span>
</Space>
</Link>
),
},
{
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
return record.ownerid ? (
<Link
to={"/manage/owners/" + record.ownerid}
onClick={(e) => e.stopPropagation()}
>
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
<OwnerNameDisplay ownerObject={record} />
</span>
</Link>
) : (
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
<OwnerNameDisplay ownerObject={record} />
</span>
);
},
},
{
title: t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
onClick={(e) => e.stopPropagation()}
>
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}
</span>
</Link>
) : (
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>{`${
record.v_model_yr || ""
} ${record.v_make_desc || ""} ${record.v_model_desc || ""}`}</span>
);
},
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(appt &&
appt
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.alt_transport),
render: (text, record) => (
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
{record.alt_transport}
</span>
),
},
{
title: t("jobs.fields.lab"),
dataIndex: "joblines_body",
key: "joblines_body",
sorter: (a, b) => a.joblines_body - b.joblines_body,
sortOrder:
state.sortedInfo.columnKey === "joblines_body" &&
state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
{record.joblines_body.toFixed(1)}
</span>
),
},
{
title: t("jobs.fields.lar"),
dataIndex: "joblines_ref",
key: "joblines_ref",
sorter: (a, b) => a.joblines_ref - b.joblines_ref,
sortOrder:
state.sortedInfo.columnKey === "joblines_ref" && state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{ fontSize: tvFontSize, fontWeight: tvFontWeight }}>
{record.joblines_ref.toFixed(1)}
</span>
),
},
];
const columns = [
{
title: t("appointments.fields.time"),
dataIndex: "start",
key: "start",
ellipsis: true,
sorter: (a, b) => dateSort(a.start, b.start),
sortOrder:
state.sortedInfo.columnKey === "start" && state.sortedInfo.order,
render: (text, record) => <TimeFormatter>{record.start}</TimeFormatter>,
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
>
<Space>
{record.ro_number || t("general.labels.na")}
{record.production_vars && record.production_vars.alert ? (
<ExclamationCircleFilled className="production-alert" />
) : null}
{record.suspended && (
<PauseCircleOutlined style={{ color: "orangered" }} />
)}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{ color: "orangered" }} />
</Tooltip>
)}
</Space>
</Link>
),
},
{
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
return record.ownerid ? (
<Link
to={"/manage/owners/" + record.ownerid}
onClick={(e) => e.stopPropagation()}
>
<OwnerNameDisplay ownerObject={record} />
</Link>
) : (
<span>
<OwnerNameDisplay ownerObject={record} />
</span>
);
},
},
{
title: t("dashboard.labels.phone"),
dataIndex: "ownr_ph",
key: "ownr_ph",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<Space size="small" wrap>
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid} />
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid} />
</Space>
),
},
{
title: t("jobs.fields.ownr_ea"),
dataIndex: "ownr_ea",
key: "ownr_ea",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<a href={`mailto:${record.ownr_ea}`}>{record.ownr_ea}</a>
),
},
{
title: t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
onClick={(e) => e.stopPropagation()}
>
{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}
</Link>
) : (
<span>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}</span>
);
},
},
{
title: t("jobs.fields.ins_co_nm"),
dataIndex: "ins_co_nm",
key: "ins_co_nm",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm),
sortOrder:
state.sortedInfo.columnKey === "ins_co_nm" && state.sortedInfo.order,
filters:
(appt &&
appt
.map((j) => j.ins_co_nm)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Ins. Co.*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.ins_co_nm),
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(appt &&
appt
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.alt_transport),
},
];
const handleTableChange = (pagination, filters, sorter) => {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
return (
<Card
title={t("dashboard.titles.scheduledindate", {
date: moment().startOf("day").format("MM/DD/YYYY"),
})}
extra={
<Space>
<Typography.Text>{t("general.labels.tvmode")}</Typography.Text>
<Switch
onClick={() => setIsTvModeScheduledIn(!isTvModeScheduledIn)}
defaultChecked={isTvModeScheduledIn}
/>
</Space>
}
{...cardProps}
>
<div style={{ height: "100%" }}>
<Table
onChange={handleTableChange}
pagination={false}
columns={isTvModeScheduledIn ? tvColumns : columns}
scroll={{ x: true, y: "calc(100% - 2em)" }}
rowKey="id"
style={{ height: "85%" }}
dataSource={appt}
size={isTvModeScheduledIn ? "small" : "middle"}
/>
</div>
</Card>
);
}
export const DashboardScheduledInTodayGql = `
scheduled_in_today: appointments(where: {start: {_gte: "${dayjs()
scheduled_in_today: appointments(where: {start: {_gte: "${moment()
.startOf("day")
.toISOString()}", _lte: "${dayjs()
.endOf("day")
.toISOString()}"}, canceled: {_eq: false}, block: {_neq: true}}) {
.toISOString()}", _lte: "${moment()
.endOf("day")
.toISOString()}"}, canceled: {_eq: false}, block: {_neq: true}}) {
canceled
id
job {
alt_transport
clm_no
jobid: id
joblines(where: {removed: {_eq: false}}) {
mod_lb_hrs
mod_lbr_ty
}
ins_co_nm
iouparent
ownerid

View File

@@ -1,37 +1,273 @@
import {BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined,} from "@ant-design/icons";
import {Card, Space, Table, Tooltip} from "antd";
import {Card, Space, Switch, Table, Tooltip, Typography} from "antd";
import dayjs from "../../../utils/day";
import React, {useState} from "react";
import {useTranslation} from "react-i18next";
import {Link} from "react-router-dom";
import {TimeFormatter} from "../../../utils/DateFormatter";
import {onlyUnique} from "../../../utils/arrayHelper";
import {alphaSort, dateSort} from "../../../utils/sorters";
import useLocalStorage from "../../../utils/useLocalStorage";
import ChatOpenButton from "../../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../../owner-name-display/owner-name-display.component";
import OwnerNameDisplay, {OwnerNameDisplayFunction,} from "../../owner-name-display/owner-name-display.component";
import DashboardRefreshRequired from "../refresh-required.component";
import {pageLimit} from "../../../utils/config";
export default function DashboardScheduledOutToday({data, ...cardProps}) {
const {t} = useTranslation();
const [state, setState] = useState({
sortedInfo: {},
});
filteredInfo: {},});
const [isTvModeScheduledOut, setIsTvModeScheduledOut] = useLocalStorage(
"isTvModeScheduledOut",
false
);
if (!data) return null;
if (!data.scheduled_out_today)
return <DashboardRefreshRequired {...cardProps} />;
const filteredScheduledOutToday = data.scheduled_out_today.map((item) => {
const scheduledOutToday = data.scheduled_out_today.map((item) => {
const joblines_body = item.joblines
? item.joblines
.filter((l) => l.mod_lbr_ty !== "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
: 0;
const joblines_ref = item.joblines
? item.joblines
.filter((l) => l.mod_lbr_ty === "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
: 0;
return {
...item,
scheduled_completion: dayjs(item.scheduled_completion).format("hh:mm a"),
timestamp: dayjs(item.scheduled_completion).valueOf(),
}
}).sort((a, b) => a.timestamp - b.timestamp);
joblines_body,
joblines_ref,
};
});
const columns = [
console.log('Scheduled Out Today')
console.dir(scheduledOutToday);
const tvFontSize = 18;
const tvFontWeight = "bold";
const tvColumns = [
{
title: t("jobs.fields.scheduled_completion"),
dataIndex: "scheduled_completion",
key: "scheduled_completion",
ellipsis: true,
sorter: (a, b) =>
dateSort(a.scheduled_completion, b.scheduled_completion),
sortOrder:
state.sortedInfo.columnKey === "scheduled_completion" &&
state.sortedInfo.order,
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<TimeFormatter>{record.scheduled_completion}</TimeFormatter>
</span>
),
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
>
<Space>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.ro_number || t("general.labels.na")}
{record.production_vars && record.production_vars.alert ? (
<ExclamationCircleFilled className="production-alert"/>
) : null}
{record.suspended && (
<PauseCircleOutlined style={{color: "orangered"}}/>
)}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{color: "orangered"}}/>
</Tooltip>
)}
</span>
</Space>
</Link>
),
},
{
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
console.log('Render record out today');
console.dir(record);
return record.ownerid ? (
<Link
to={"/manage/owners/" + record.ownerid}
onClick={(e) => e.stopPropagation()}
>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<OwnerNameDisplay ownerObject={record}/>
</span>
</Link>
) : (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<OwnerNameDisplay ownerObject={record}/>
</span>
);
},
},
{
title: t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
onClick={(e) => e.stopPropagation()}
>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}
</span>
</Link>
) : (
<span
style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>{`${
record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}</span>
);
},
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(scheduledOutToday &&
scheduledOutToday
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],onFilter: (value, record) => value.includes(record.alt_transport),
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.alt_transport}
</span>
),
},
{
title: t("jobs.fields.status"),
dataIndex: "status",
key: "status",
ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
filters:
(scheduledOutToday &&
scheduledOutToday
.map((j) => j.status)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Status*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.status),render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.status}
</span>
),
},
{
title: t("jobs.fields.lab"),
dataIndex: "joblines_body",
key: "joblines_body",
sorter: (a, b) => a.joblines_body - b.joblines_body,
sortOrder:
state.sortedInfo.columnKey === "joblines_body" &&
state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.joblines_body.toFixed(1)}
</span>
),
},
{
title: t("jobs.fields.lar"),
dataIndex: "joblines_ref",
key: "joblines_ref",
sorter: (a, b) => a.joblines_ref - b.joblines_ref,
sortOrder:
state.sortedInfo.columnKey === "joblines_ref" && state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.joblines_ref.toFixed(1)}
</span>
),
},
];
const columns = [
{
title: t("jobs.fields.scheduled_completion"),
dataIndex: "scheduled_completion",
key: "scheduled_completion",
ellipsis: true,
sorter: (a, b) =>
dateSort(a.scheduled_completion, b.scheduled_completion),
sortOrder:
state.sortedInfo.columnKey === "scheduled_completion" &&
state.sortedInfo.order,
render: (text, record) => (
<TimeFormatter>{record.scheduled_completion}</TimeFormatter>
),
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order, render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
@@ -58,7 +294,10 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
dataIndex: "owner",
key: "owner",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
return record.ownerid ? (
<Link
@@ -75,24 +314,16 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
},
},
{
title: t("jobs.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
title: t("dashboard.labels.phone"),
dataIndex: "ownr_ph",
key: "ownr_ph",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
render: (text, record) => (<Space size="small" wrap>
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid}/>
),
},
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid}/>
),
</Space>),
},
{
title: t("jobs.fields.ownr_ea"),
@@ -101,7 +332,7 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ea} jobid={record.jobid}/>
<a href={`mailto:${record.ownr_ea}`}>{record.ownr_ea}</a>
),
},
{
@@ -109,7 +340,15 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
render: (text, record) => {
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order, render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
@@ -132,43 +371,78 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
key: "ins_co_nm",
ellipsis: true,
responsive: ["md"],
},
{
title: t("jobs.fields.scheduled_completion"),
dataIndex: "scheduled_completion",
key: "scheduled_completion",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm),
sortOrder:
state.sortedInfo.columnKey === "ins_co_nm" && state.sortedInfo.order,
filters:
(scheduledOutToday &&
scheduledOutToday
.map((j) => j.ins_co_nm)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Ins. Co.*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.ins_co_nm),
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
responsive: ["md"],
},
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(scheduledOutToday &&
scheduledOutToday
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.alt_transport),},
];
const handleTableChange = (sorter) => {
setState({...state, sortedInfo: sorter});
const handleTableChange = (pagination, filters, sorter) => {
setState({...state, filteredInfo: filters, sortedInfo: sorter});
};
return (
<Card
title={t("dashboard.titles.scheduledouttoday", {
title={t("dashboard.titles.scheduledoutdate", {
date: dayjs().startOf("day").format("MM/DD/YYYY"),
})}
{...cardProps}
extra={
<Space>
<Typography.Text>{t("general.labels.tvmode")}</Typography.Text>
<Switch
onClick={() => setIsTvModeScheduledOut(!isTvModeScheduledOut)}
defaultChecked={isTvModeScheduledOut}
/>
</Space>
}{...cardProps}
>
<div style={{height: "100%"}}>
<Table
onChange={handleTableChange}
pagination={{position: "top", defaultPageSize: pageLimit}}
columns={columns}
pagination={false}
columns={isTvModeScheduledOut ? tvColumns : columns}
scroll={{x: true, y: "calc(100% - 2em)"}}
rowKey="id"
style={{height: "85%"}}
dataSource={filteredScheduledOutToday}
dataSource={scheduledOutToday}
size={isTvModeScheduledOut ? "small" : "middle"}
/>
</div>
</Card>
@@ -185,6 +459,10 @@ export const DashboardScheduledOutTodayGql = `
alt_transport
clm_no
jobid: id
joblines(where: {removed: {_eq: false}}) {
mod_lb_hrs
mod_lbr_ty
}
ins_co_nm
iouparent
ownerid
@@ -197,6 +475,7 @@ export const DashboardScheduledOutTodayGql = `
production_vars
ro_number
scheduled_completion
status
suspended
v_make_desc
v_model_desc

View File

@@ -270,26 +270,22 @@ const componentList = {
h: 2,
},
ScheduleInToday: {
label: i18next.t("dashboard.titles.scheduledintoday", {
date: dayjs().startOf("day").format("MM/DD/YYYY"),
}),
label: i18next.t("dashboard.titles.scheduledintoday"),
component: DashboardScheduledInToday,
gqlFragment: DashboardScheduledInTodayGql,
minW: 10,
minW: 6,
minH: 2,
w: 10,
h: 2,
h: 3,
},
ScheduleOutToday: {
label: i18next.t("dashboard.titles.scheduledouttoday", {
date: dayjs().startOf("day").format("MM/DD/YYYY"),
}),
label: i18next.t("dashboard.titles.scheduledouttoday"),
component: DashboardScheduledOutToday,
gqlFragment: DashboardScheduledOutTodayGql,
minW: 10,
minW: 6,
minH: 2,
w: 10,
h: 2,
h: 3,
},
};
@@ -301,8 +297,7 @@ const createDashboardQuery = (state) => {
.map((item, index) => componentList[item.i].gqlFragment || "")
.join("");
return gql`
query QUERY_DASHBOARD_DETAILS {
${componentBasedAdditions || ""}
query QUERY_DASHBOARD_DETAILS { ${componentBasedAdditions || ""}
monthly_sales: jobs(where: {_and: [
{ voided: {_eq: false}},
{date_invoiced: {_gte: "${dayjs()
@@ -312,7 +307,7 @@ const createDashboardQuery = (state) => {
.endOf("month")
.endOf("day")
.toISOString()}"}}]}) {
id
id
ro_number
date_invoiced
job_totals
@@ -376,6 +371,5 @@ const createDashboardQuery = (state) => {
}
}
}
}
`;
}`;
};

View File

@@ -145,7 +145,7 @@
width: 100%;
.ant-card-body {
height: 80%;
height: calc(100% - 2rem);
width: 100%;
// // background-color: red;
// height: 90%;

View File

@@ -119,11 +119,14 @@ export function JobsDetailHeader({job, bodyshop, disabled}) {
</DataLabel>
{job?.cccontracts?.length > 0 && (
<DataLabel label={t("jobs.labels.contracts")}>
{job.cccontracts.map((c) => (
{job.cccontracts.map((c, index) => (
<Space wrap>
<Link
key={c.id}
to={`/manage/courtesycars/contracts/${c.id}`}
>{`${c.agreementnumber} - ${c.courtesycar.fleetnumber} ${c.courtesycar.year} ${c.courtesycar.make} ${c.courtesycar.model}`}</Link>
>{`${c.agreementnumber} - ${c.courtesycar.fleetnumber} ${c.courtesycar.year} ${c.courtesycar.make} ${c.courtesycar.model}`}{index !== job.cccontracts.length - 1 ? "," : null}
</Link>
</Space>
))}
</DataLabel>
)}

View File

@@ -1,52 +1,356 @@
import {Button, Card, Checkbox, Col, Form, Input, InputNumber, Row, Select} from "antd";
import React, {useEffect, useState} from "react";
import React, {useCallback, useEffect, useMemo, useState} from "react";
import {fetchFilterData} from "../../utils/RenderTemplate";
import {DeleteFilled} from "@ant-design/icons";
import {useTranslation} from "react-i18next";
import {getOperatorsByType} from "../../utils/graphQLmodifier";
import {getOrderOperatorsByType, getWhereOperatorsByType} from "../../utils/graphQLmodifier";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
import {generateInternalReflections} from "./report-center-modal-utils";
export default function ReportCenterModalFiltersSortersComponent({form}) {
export default function ReportCenterModalFiltersSortersComponent({form, bodyshop}) {
return (
<Form.Item style={{margin: 0, padding: 0}} dependencies={["key"]}>
{() => {
const key = form.getFieldValue("key");
return <RenderFilters form={form} templateId={key}/>;
return <RenderFilters form={form} templateId={key} bodyshop={bodyshop}/>;
}}
</Form.Item>
);
}
function RenderFilters({templateId, form}) {
/**
* Filters Section
* @param filters
* @param form
* @param bodyshop
* @returns {JSX.Element}
* @constructor
*/
function FiltersSection({filters, form, bodyshop}) {
const {t} = useTranslation();
return (
<Card type='inner' title={t('reportcenter.labels.advanced_filters_filters')}
style={{marginTop: '10px'}}>
<Form.List name={["filters"]}>
{(fields, {add, remove, move}) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<Row gutter={[16, 16]}>
<Col span={10}>
<Form.Item
key={`${index}field`}
label={t('reportcenter.labels.advanced_filters_filter_field')}
name={[field.name, "field"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
getPopupContainer={trigger => trigger.parentNode}
onChange={() => {
// Clear related Fields
form.setFieldValue(['filters', field.name, 'value'], null);
form.setFieldValue(['filters', field.name, 'operator'], null);
}}
options={
filters.map((f) => {
return {
value: f.name,
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
}
})
}
/>
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
dependencies={[['filters', field.name, "field"]]}>
{
() => {
const name = form.getFieldValue(['filters', field.name, "field"]);
const type = filters.find(f => f.name === name)?.type;
return <Form.Item
key={`${index}operator`}
label={t('reportcenter.labels.advanced_filters_filter_operator')}
name={[field.name, "operator"]}
dependencies={[]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
getPopupContainer={trigger => trigger.parentNode}
options={getWhereOperatorsByType(type)}/>
</Form.Item>
}
}
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
dependencies={[['filters', field.name, "field"]]}>
{
() => {
const name = form.getFieldValue(['filters', field.name, "field"]);
const type = filters.find(f => f.name === name)?.type;
const reflector = filters.find(f => f.name === name)?.reflector;
return <Form.Item
key={`${index}value`}
label={t('reportcenter.labels.advanced_filters_filter_value')}
name={[field.name, "value"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
{
(() => {
const generateReflections = (reflector) => {
if (!reflector) return [];
const {name} = reflector;
const path = name?.split('.');
const upperPath = path?.[0];
const finalPath = path?.slice(1).join('.');
return generateInternalReflections({
bodyshop,
upperPath,
finalPath
});
};
const reflections = reflector ? generateReflections(reflector) : [];
const fieldPath = [[field.name, "value"]];
if (reflections.length > 0) {
return (
<Select
options={reflections}
getPopupContainer={trigger => trigger.parentNode}
onChange={(value) => {
form.setFieldValue(fieldPath, value);
}}
/>
);
}
if (type === "number") {
return (
<InputNumber
onChange={(value) => form.setFieldValue(fieldPath, value)}/>
);
}
return (
<Input
onChange={(e) => form.setFieldValue(fieldPath, e.target.value)}/>
);
})()
}
</Form.Item>
}
}
</Form.Item>
</Col>
<Col span={2}>
<DeleteFilled
style={{margin: "1rem", paddingTop: '23px'}}
onClick={() => {
remove(field.name);
}}
/>
</Col>
</Row>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{width: "100%"}}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</Card>
);
}
/**
* Sorters Section
* @param sorters
* @param form
* @returns {JSX.Element}
* @constructor
*/
function SortersSection({sorters, form}) {
const {t} = useTranslation();
return (
<Card type='inner' title={t('reportcenter.labels.advanced_filters_sorters')}
style={{marginTop: '10px'}}>
<Form.List name={["sorters"]}>
{(fields, {add, remove, move}) => {
return (
<div>
Sorters
{fields.map((field, index) => (
<Form.Item key={field.key}>
<Row gutter={[16, 16]}>
<Col span={11}>
<Form.Item
key={`${index}field`}
label={t('reportcenter.labels.advanced_filters_sorter_field')}
name={[field.name, "field"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={
sorters.map((f) => ({
value: f.name,
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
}))
}
getPopupContainer={trigger => trigger.parentNode}
/>
</Form.Item>
</Col>
<Col span={11}>
<Form.Item
key={`${index}direction`}
label={t('reportcenter.labels.advanced_filters_sorter_direction')}
name={[field.name, "direction"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={getOrderOperatorsByType()}
getPopupContainer={trigger => trigger.parentNode}
/>
</Form.Item>
</Col>
<Col span={2}>
<DeleteFilled
style={{margin: "1rem", paddingTop: '23px'}}
onClick={() => {
remove(field.name);
}}
/>
</Col>
</Row>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{width: "100%"}}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</Card>
);
}
/**
* Render Filters
* @param templateId
* @param form
* @param bodyshop
* @returns {JSX.Element|null}
* @constructor
*/
function RenderFilters({templateId, form, bodyshop}) {
const [state, setState] = useState(null);
const [visible, setVisible] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const {t} = useTranslation();
useEffect(() => {
const fetch = async () => {
setIsLoading(true);
const data = await fetchFilterData({name: templateId});
if (data?.success) {
setState(data.data);
} else {
setState(null);
}
setIsLoading(false);
};
const fetch = useCallback(async () => {
// Reset all the filters and Sorters.
form.resetFields(['filters']);
form.resetFields(['sorters']);
form.resetFields(['defaultSorters']);
setIsLoading(true);
const data = await fetchFilterData({name: templateId});
// We have Success
if (data?.success) {
if (data?.data?.sorters && data?.data?.sorters.length > 0) {
const defaultSorters = data?.data?.sorters.filter((sorter) => sorter.hasOwnProperty('default')).map((sorter) => {
return {
field: sorter.name,
direction: sorter.default.direction
};
}).sort((a, b) => a.default.order - b.default.order);
form.setFieldValue('defaultSorters', JSON.stringify(defaultSorters));
}
// Set the state
setState(data.data);
}
// Something went wrong fetching filter data
else {
setState(null);
}
setIsLoading(false);
}, [templateId, form]);
useEffect(() => {
if (templateId) {
fetch();
}
}, [templateId]);
}, [templateId, fetch]);
const filters = useMemo(() => state?.filters || [], [state]);
const sorters = useMemo(() => state?.sorters || [], [state]);
// Conditional display of filters and sorters
if (!templateId) return null;
if (isLoading) return <LoadingSkeleton/>;
if (!state) return null;
// Filters and Sorters data available
return (
<div style={{marginTop: '10px'}}>
<Checkbox
@@ -56,219 +360,11 @@ function RenderFilters({templateId, form}) {
/>
{visible && (
<div>
{state.filters && state.filters.length > 0 && (
<Card type='inner' title={t('reportcenter.labels.advanced_filters_filters')}
style={{marginTop: '10px'}}>
<Form.List name={["filters"]}>
{(fields, {add, remove, move}) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<Row gutter={[16, 16]}>
<Col span={10}>
<Form.Item
key={`${index}field`}
label="field"
name={[field.name, "field"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={
state.filters
? state.filters.map((f) => {
return {
value: f.name,
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
}
})
: []
}
/>
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
dependencies={[['filters', field.name, "field"]]}>
{
() => {
const name = form.getFieldValue(['filters', field.name, "field"]);
const type = state.filters.find(f => f.name === name)?.type;
return <Form.Item
key={`${index}operator`}
label="operator"
name={[field.name, "operator"]}
dependencies={[]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select options={getOperatorsByType(type)}/>
</Form.Item>
}
}
</Form.Item>
</Col>
<Col span={6}>
<Form.Item
dependencies={[['filters', field.name, "field"]]}>
{
() => {
const name = form.getFieldValue(['filters', field.name, "field"]);
const type = state.filters.find(f => f.name === name)?.type;
return <Form.Item
key={`${index}value`}
label="value"
name={[field.name, "value"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
{type === 'number' ?
<InputNumber
onChange={(value) => {
form.setFieldsValue({[field.name]: {value: parseInt(value)}});
}}
/>
:
<Input
onChange={(value) => {
form.setFieldsValue({[field.name]: {value: value.toString()}});
}}
/>
}
</Form.Item>
}
}
</Form.Item>
</Col>
<Col span={2}>
<DeleteFilled
style={{margin: "1rem"}}
onClick={() => {
remove(field.name);
}}
/>
</Col>
</Row>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{width: "100%"}}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</Card>
{filters.length > 0 && (
<FiltersSection filters={filters} form={form} bodyshop={bodyshop}/>
)}
{state.sorters && state.sorters.length > 0 && (
<Card type='inner' title={t('reportcenter.labels.advanced_filters_sorters')}
style={{marginTop: '10px'}}>
<Form.List name={["sorters"]}>
{(fields, {add, remove, move}) => {
return (
<div>
Sorters
{fields.map((field, index) => (
<Form.Item key={field.key}>
<Row gutter={[16, 16]}>
<Col span={11}>
<Form.Item
key={`${index}field`}
label="field"
name={[field.name, "field"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={
state.sorters
? state.sorters.map((f) => ({
value: f.name,
label: f?.translation ? (t(f.translation) === f.translation ? f.label : t(f.translation)) : f.label,
}))
: []
}
/>
</Form.Item>
</Col>
<Col span={11}>
<Form.Item
key={`${index}direction`}
label="direction"
name={[field.name, "direction"]}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<Select
options={[
{value: "desc", label: "Descending"},
{value: "asc", label: "Ascending"},
]}
/>
</Form.Item>
</Col>
<Col span={2}>
<DeleteFilled
style={{margin: "1rem"}}
onClick={() => {
remove(field.name);
}}
/>
</Col>
</Row>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{width: "100%"}}
>
{t("general.actions.add")}
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</Card>
{sorters.length > 0 && (
<SortersSection sorters={sorters} form={form}/>
)}
</div>
)}

View File

@@ -0,0 +1,121 @@
import {uniqBy} from "lodash";
/**
* Get value from path
* @param obj
* @param path
* @returns {*}
*/
const getValueFromPath = (obj, path) => path.split('.').reduce((prev, curr) => prev?.[curr], obj);
/**
* Valid internal reflections
* Note: This is intended for future functionality
* @type {{special: string[], bodyshop: [{name: string, type: string}]}}
*/
const VALID_INTERNAL_REFLECTIONS = {
bodyshop: [
{
name: 'md_ro_statuses.statuses',
type: 'kv-to-v'
}
],
};
/**
* Generate options
* @param bodyshop
* @param path
* @param labelPath
* @param valuePath
* @returns {{label: *, value: *}[]}
*/
const generateOptionsFromObject = (bodyshop, path, labelPath, valuePath) => {
const options = getValueFromPath(bodyshop, path);
return uniqBy(Object.values(options).map((value) => ({
label: value[labelPath],
value: value[valuePath],
})), 'value');
}
/**
* Generate special reflections
* @param bodyshop
* @param finalPath
* @returns {{label: *, value: *}[]|{label: *, value: *}[]|{label: string, value: *}[]|*[]}
*/
const generateSpecialReflections = (bodyshop, finalPath) => {
switch (finalPath) {
case 'cost_centers':
return generateOptionsFromObject(bodyshop, 'md_responsibility_centers.costs', 'name', 'name');
// Special case because Categories is an Array, not an Object.
case 'categories':
const catOptions = getValueFromPath(bodyshop, 'md_categories');
return uniqBy(catOptions.map((value) => ({
label: value,
value: value,
})), 'value');
case 'insurance_companies':
return generateOptionsFromObject(bodyshop, 'md_ins_cos', 'name', 'name');
case 'employee_teams':
return generateOptionsFromObject(bodyshop, 'employee_teams', 'name', 'id');
// Special case because Employees uses a concatenation of first_name and last_name
case 'employees':
const employeesOptions = getValueFromPath(bodyshop, 'employees');
return uniqBy(Object.values(employeesOptions).map((value) => ({
label: `${value.first_name} ${value.last_name}`,
value: value.id,
})), 'value');
case 'last_names':
return generateOptionsFromObject(bodyshop, 'employees', 'last_name', 'last_name');
case 'first_names':
return generateOptionsFromObject(bodyshop, 'employees', 'first_name', 'first_name');
case 'job_statuses':
const statusOptions = getValueFromPath(bodyshop, 'md_ro_statuses.statuses');
return Object.values(statusOptions).map((value) => ({
label: value,
value
}));
default:
console.error('Invalid Special reflection provided by Report Filters');
return [];
}
}
/**
* Generate bodyshop reflections
* @param bodyshop
* @param finalPath
* @returns {{label: *, value: *}[]|*[]}
*/
const generateBodyshopReflections = (bodyshop, finalPath) => {
const options = getValueFromPath(bodyshop, finalPath);
const reflectionRenderer = VALID_INTERNAL_REFLECTIONS.bodyshop.find(reflection => reflection.name === finalPath);
if (reflectionRenderer?.type === 'kv-to-v') {
return Object.values(options).map((value) => ({
label: value,
value
}));
}
return [];
}
/**
* Generate internal reflections based on the path and bodyshop
* @param bodyshop
* @param upperPath
* @param finalPath
* @returns {{label: *, value: *}[]|[]|{label: *, value: *}[]|{label: string, value: *}[]|{label: *, value: *}[]|*[]}
*/
const generateInternalReflections = ({bodyshop, upperPath, finalPath}) => {
switch (upperPath) {
case 'special':
return generateSpecialReflections(bodyshop, finalPath);
case 'bodyshop':
return generateBodyshopReflections(bodyshop, finalPath);
default:
return [];
}
};
export {generateInternalReflections,}

View File

@@ -16,9 +16,11 @@ import EmployeeSearchSelect from "../employee-search-select/employee-search-sele
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
import "./report-center-modal.styles.scss";
import ReportCenterModalFiltersSortersComponent from "./report-center-modal-filters-sorters-component";
import {selectBodyshop} from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
reportCenterModal: selectReportCenter,
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
@@ -28,7 +30,7 @@ export default connect(
mapDispatchToProps
)(ReportCenterModalComponent);
export function ReportCenterModalComponent({reportCenterModal}) {
export function ReportCenterModalComponent({reportCenterModal, bodyshop}) {
const [form] = Form.useForm();
const [search, setSearch] = useState("");
@@ -64,7 +66,7 @@ export function ReportCenterModalComponent({reportCenterModal}) {
const end = values.dates ? values.dates[1] : null;
const {id} = values;
await GenerateDocument(
const templateConfig =
{
name: values.key,
variables: {
@@ -81,7 +83,14 @@ export function ReportCenterModalComponent({reportCenterModal}) {
},
filters: values.filters,
sorters: values.sorters,
},
};
if (_.isString(values.defaultSorters) && !_.isEmpty(values.defaultSorters)) {
templateConfig.defaultSorters = JSON.parse(values.defaultSorters);
}
await GenerateDocument(
templateConfig,
{
to: values.to,
subject: Templates[values.key]?.subject,
@@ -119,6 +128,7 @@ export function ReportCenterModalComponent({reportCenterModal}) {
onChange={(e) => setSearch(e.target.value)}
value={search}
/>
<Form.Item name="defaultSorters" hidden/>
<Form.Item
name="key"
label={t("reportcenter.labels.key")}
@@ -183,7 +193,7 @@ export function ReportCenterModalComponent({reportCenterModal}) {
);
}}
</Form.Item>
<ReportCenterModalFiltersSortersComponent form={form}/>
<ReportCenterModalFiltersSortersComponent form={form} bodyshop={bodyshop}/>
<Form.Item style={{margin: 0, padding: 0}} dependencies={["key"]}>
{() => {
const key = form.getFieldValue("key");

View File

@@ -1,5 +1,6 @@
import {useMutation} from "@apollo/client";
import {Button, Card, Dropdown, Form, InputNumber, notification} from "antd";
import {Button, Card, Dropdown, Form, InputNumber, notification, Space,} from "antd";
import dayjs from "../../utils/day";
import React, {useState} from "react";
import {useTranslation} from "react-i18next";
import {UPDATE_SCOREBOARD_ENTRY} from "../../graphql/scoreboard.queries";
@@ -13,6 +14,7 @@ export default function ScoreboardEntryEdit({entry}) {
const handleFinish = async (values) => {
setLoading(true);
values.date = dayjs(values.date).format("YYYY-MM-DD");
const result = await updateScoreboardentry({
variables: {sbId: entry.id, sbInput: values},
});
@@ -82,13 +84,14 @@ export default function ScoreboardEntryEdit({entry}) {
>
<InputNumber precision={1}/>
</Form.Item>
<Space wrap>
<Button type="primary" loading={loading} htmlType="submit">
{t("general.actions.save")}
</Button>
<Button onClick={() => setOpen(false)}>
{t("general.actions.cancel")}
</Button>
</Space>
</Form>
</Card>
)

View File

@@ -1,3 +1,4 @@
import {SyncOutlined} from "@ant-design/icons";
import {useQuery} from "@apollo/client";
import {Button, Card, Input, Modal, Space, Table, Typography} from "antd";
import React, {useState} from "react";
@@ -5,12 +6,13 @@ import {useTranslation} from "react-i18next";
import {Link} from "react-router-dom";
import {QUERY_SCOREBOARD_PAGINATED} from "../../graphql/scoreboard.queries";
import {DateFormatter} from "../../utils/DateFormatter";
import {pageLimit} from "../../utils/config";
import {alphaSort, dateSort} from "../../utils/sorters";
import AlertComponent from "../alert/alert.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import OwnerNameDisplay, {OwnerNameDisplayFunction,} from "../owner-name-display/owner-name-display.component";
import ScoreboardEntryEdit from "../scoreboard-entry-edit/scoreboard-entry-edit.component";
import ScoreboardRemoveButton from "../scoreboard-remove-button/scorebard-remove-button.component";
import {SyncOutlined} from "@ant-design/icons";
import {pageLimit} from "../../utils/config";
export default function ScoreboardJobsList({scoreBoardlist}) {
const {t} = useTranslation();
@@ -45,7 +47,7 @@ export default function ScoreboardJobsList({scoreBoardlist}) {
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
render: (text, record) => (
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), render: (text, record) => (
<Link to={"/manage/jobs/" + record.job.id}>
{record.job.ro_number || t("general.labels.na")}
</Link>
@@ -55,8 +57,11 @@ export default function ScoreboardJobsList({scoreBoardlist}) {
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
ellipsis: true, sorter: (a, b) =>
alphaSort(
OwnerNameDisplayFunction(a.job),
OwnerNameDisplayFunction(b.job)
),
render: (text, record) => <OwnerNameDisplay ownerObject={record.job}/>,
},
{
@@ -64,7 +69,15 @@ export default function ScoreboardJobsList({scoreBoardlist}) {
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
render: (text, record) => (
sorter: (a, b) =>
alphaSort(
`${a.job.v_model_yr || ""} ${a.job.v_make_desc || ""} ${
a.job.v_model_desc || ""
}`,
`${b.job.v_model_yr || ""} ${b.job.v_make_desc || ""} ${
b.job.v_model_desc || ""
}`
), render: (text, record) => (
<span>{`${record.job.v_model_yr || ""} ${
record.job.v_make_desc || ""
} ${record.job.v_model_desc || ""}`}</span>
@@ -74,17 +87,20 @@ export default function ScoreboardJobsList({scoreBoardlist}) {
title: t("scoreboard.fields.date"),
dataIndex: "date",
key: "date",
sorter: (a, b) => dateSort(a.date, b.date),
render: (text, record) => <DateFormatter>{record.date}</DateFormatter>,
},
{
title: t("scoreboard.fields.painthrs"),
dataIndex: "painthrs",
key: "painthrs",
},
{
title: t("scoreboard.fields.bodyhrs"),
dataIndex: "bodyhrs",
key: "bodyhrs",
sorter: (a, b) => Number(a.bodyhrs) - Number(b.bodyhrs),
},
{
title: t("scoreboard.fields.painthrs"),
dataIndex: "painthrs",
key: "painthrs",
sorter: (a, b) => Number(a.painthrs) - Number(b.painthrs),
},
{
title: t("general.labels.actions"),
@@ -105,11 +121,9 @@ export default function ScoreboardJobsList({scoreBoardlist}) {
open={state.open}
destroyOnClose
width="80%"
closable={false}
cancelButtonProps={{style: {display: "none"}}}
onOk={() => {
setState((state) => ({...state, open: false}));
}}
onCancel={() =>
onOk={() =>
setState((state) => ({
...state,
open: false,
@@ -161,9 +175,7 @@ export default function ScoreboardJobsList({scoreBoardlist}) {
</Card>
</Modal>
<Button
onClick={() => {
setState((state) => ({...state, open: true}))
}}
onClick={() => setState((state) => ({...state, open: true}))}
>
{t("scoreboard.labels.entries")}
</Button>

View File

@@ -22,6 +22,7 @@ export const QUERY_AVAILABLE_CC = gql`
]
status: { _eq: "courtesycars.status.in" }
}
order_by: { fleetnumber: asc }
) {
color
dailycost
@@ -29,6 +30,7 @@ export const QUERY_AVAILABLE_CC = gql`
fleetnumber
fuel
id
insuranceexpires
make
mileage
model
@@ -57,7 +59,7 @@ export const CHECK_CC_FLEET_NUMBER = gql`
`;
export const QUERY_ALL_CC = gql`
query QUERY_ALL_CC {
courtesycars {
courtesycars(order_by: { fleetnumber: asc }) {
color
created_at
dailycost

View File

@@ -747,6 +747,7 @@
"driverinformation": "Driver's Information",
"findcontract": "Find Contract",
"findermodal": "Contract Finder",
"insuranceexpired": "The courtesy car insurance expires before the car is expected to return.",
"noteconvertedfrom": "R.O. created from converted Courtesy Car Contract {{agreementnumber}}.",
"populatefromjob": "Populate from Job",
"rates": "Contract Rates",
@@ -874,6 +875,7 @@
"labels": {
"bodyhrs": "Body Hrs",
"dollarsinproduction": "Dollars in Production",
"phone": "Phone",
"prodhrs": "Production Hrs",
"refhrs": "Refinish Hrs"
},
@@ -889,8 +891,10 @@
"productiondollars": "Total Dollars in Production",
"productionhours": "Total Hours in Production",
"projectedmonthlysales": "Projected Monthly Sales",
"scheduledintoday": "Sheduled In Today: {{date}}",
"scheduledouttoday": "Sheduled Out Today: {{date}}"
"scheduledindate": "Sheduled In Today: {{date}}",
"scheduledintoday": "Sheduled In Today",
"scheduledoutdate": "Sheduled Out Today: {{date}}",
"scheduledouttoday": "Sheduled Out Today"
}
},
"dms": {
@@ -2614,6 +2618,11 @@
"advanced_filters_hide": "Hide",
"advanced_filters_filters": "Filters",
"advanced_filters_sorters": "Sorters",
"advanced_filters_filter_field": "Field",
"advanced_filters_sorter_field": "Field",
"advanced_filters_sorter_direction": "Direction",
"advanced_filters_filter_operator": "Operator",
"advanced_filters_filter_value": "Value",
"dates": "Dates",
"employee": "Employee",
"filterson": "Filters on {{object}}: {{field}}",

View File

@@ -747,6 +747,7 @@
"driverinformation": "",
"findcontract": "",
"findermodal": "",
"insuranceexpired": "",
"noteconvertedfrom": "",
"populatefromjob": "",
"rates": "",
@@ -874,6 +875,7 @@
"labels": {
"bodyhrs": "",
"dollarsinproduction": "",
"phone": "",
"prodhrs": "",
"refhrs": ""
},
@@ -889,7 +891,9 @@
"productiondollars": "",
"productionhours": "",
"projectedmonthlysales": "",
"scheduledindate": "",
"scheduledintoday": "",
"scheduledoutdate": "",
"scheduledouttoday": ""
}
},
@@ -2614,6 +2618,11 @@
"advanced_filters_hide": "",
"advanced_filters_filters": "",
"advanced_filters_sorters": "",
"advanced_filters_filter_field": "",
"advanced_filters_sorter_field": "",
"advanced_filters_sorter_direction": "",
"advanced_filters_filter_operator": "",
"advanced_filters_filter_value": "",
"dates": "",
"employee": "",
"filterson": "",

View File

@@ -747,6 +747,7 @@
"driverinformation": "",
"findcontract": "",
"findermodal": "",
"insuranceexpired": "",
"noteconvertedfrom": "",
"populatefromjob": "",
"rates": "",
@@ -874,6 +875,7 @@
"labels": {
"bodyhrs": "",
"dollarsinproduction": "",
"phone": "",
"prodhrs": "",
"refhrs": ""
},
@@ -889,7 +891,9 @@
"productiondollars": "",
"productionhours": "",
"projectedmonthlysales": "",
"scheduledindate": "",
"scheduledintoday": "",
"scheduledoutdate": "",
"scheduledouttoday": ""
}
},
@@ -2614,6 +2618,11 @@
"advanced_filters_hide": "",
"advanced_filters_filters": "",
"advanced_filters_sorters": "",
"advanced_filters_filter_field": "",
"advanced_filters_sorter_field": "",
"advanced_filters_sorter_direction": "",
"advanced_filters_filter_operator": "",
"advanced_filters_filter_value": "",
"dates": "",
"employee": "",
"filterson": "",

View File

@@ -57,6 +57,16 @@ const range = [
label: 'Last 90 Days',
value: [dayjs().add(-90, "day"), dayjs()],
}
]
];
if (process.env.NODE_ENV === "development") {
range.push({
label: 'Last Year',
value: [
dayjs().subtract(1, "year"),
dayjs(),
]
})
}
export default range;

View File

@@ -9,7 +9,8 @@ import {store} from "../redux/store";
import client from "../utils/GraphQLClient";
import cleanAxios from "./CleanAxios";
import {TemplateList} from "./TemplateConstants";
import {applyFilters, applySorters, parseQuery, printQuery, wrapFiltersInAnd} from "./graphQLmodifier";
import {generateTemplate} from "./graphQLmodifier";
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
jsreport.serverUrl = server;
@@ -74,7 +75,10 @@ export default async function RenderTemplate(
headerpath: `/${bodyshop.imexshopid}/header.html`,
footerpath: `/${bodyshop.imexshopid}/footer.html`,
bodyshop: bodyshop,
filters: templateObject?.filters,
sorters: templateObject?.sorters,
offset: bodyshop.timezone, //dayjs().utcOffset(),
defaultSorters: templateObject?.defaultSorters,
},
};
@@ -402,9 +406,12 @@ const fetchContextData = async (templateObject, jsrAuth) => {
// console.log('Unmodified Query');
// console.dir(templateQueryToExecute);
const hasFilters = templateObject?.filters?.length > 0;
const hasSorters = templateObject?.sorters?.length > 0;
const hasDefaultSorters = templateObject?.defaultSorters?.length > 0;
// We have no template filters or sorters, so we can just execute the query and return the data
if ((!templateObject?.filters && !templateObject?.filters?.length && !templateObject?.sorters && !templateObject?.sorters?.length)) {
if (!hasFilters && !hasSorters && !hasDefaultSorters) {
let contextData = {};
if (templateQueryToExecute) {
const {data} = await client.query({
@@ -416,36 +423,11 @@ const fetchContextData = async (templateObject, jsrAuth) => {
return {contextData, useShopSpecificTemplate};
}
// Parse the query and apply the filters and sorters
const ast = parseQuery(templateQueryToExecute);
let filterFields = [];
if (templateObject?.filters && templateObject?.filters?.length) {
applyFilters(ast, templateObject.filters, filterFields);
wrapFiltersInAnd(ast, filterFields);
}
if (templateObject?.sorters && templateObject?.sorters?.length) {
applySorters(ast, templateObject.sorters);
}
const finalQuery = printQuery(ast);
// commented out for future revision debugging
// console.log('Modified Query');
// console.log(finalQuery);
let contextData = {};
if (templateQueryToExecute) {
const {data} = await client.query({
query: gql(finalQuery),
variables: {...templateObject.variables},
});
contextData = data;
}
return {contextData, useShopSpecificTemplate};
return await generateTemplate(
templateQueryToExecute,
templateObject,
useShopSpecificTemplate
);
};
//export const displayTemplateInWindow = (html) => {

View File

@@ -1,4 +1,6 @@
import {Kind, parse, print, visit} from "graphql";
import client from "./GraphQLClient";
import {gql} from "@apollo/client";
const STRING_OPERATORS = [
{value: "_eq", label: "equals"},
@@ -16,8 +18,26 @@ const NUMBER_OPERATORS = [
{value: "_gte", label: "greater than or equal"},
{value: "_lte", label: "less than or equal"}
];
const ORDER_BY_OPERATORS = [
{value: "asc", label: "ascending"},
{value: "desc", label: "descending"}
];
export function getOperatorsByType(type = 'string') {
/**
* Get the available operators for filtering
* @returns {[{label: string, value: string},{label: string, value: string}]}
*/
export function getOrderOperatorsByType() {
return ORDER_BY_OPERATORS;
}
/**
* Get the available operators for filtering
* @param type
* @returns {[{label: string, value: string},{label: string, value: string},{label: string, value: string},{label: string, value: string},{label: string, value: string},null]}
*/
export function getWhereOperatorsByType(type = 'string') {
const operators = {
string: STRING_OPERATORS,
number: NUMBER_OPERATORS
@@ -45,6 +65,51 @@ export function printQuery(query) {
return print(query);
}
/**
* Generate a template based on the query and object
* @param templateQueryToExecute
* @param templateObject
* @param useShopSpecificTemplate
* @returns {Promise<{contextData: {}, useShopSpecificTemplate}>}
*/
export async function generateTemplate(templateQueryToExecute, templateObject, useShopSpecificTemplate) {
// Advanced Filtering and Sorting modifications start here
// Parse the query and apply the filters and sorters
const ast = parseQuery(templateQueryToExecute);
let filterFields = [];
if (templateObject?.filters && templateObject?.filters?.length) {
applyFilters(ast, templateObject.filters, filterFields);
wrapFiltersInAnd(ast, filterFields);
}
if (templateObject?.sorters && templateObject?.sorters?.length) {
applySorters(ast, templateObject.sorters);
} else if (templateObject?.defaultSorters && templateObject?.defaultSorters?.length) {
applySorters(ast, templateObject.defaultSorters);
}
const finalQuery = printQuery(ast);
// commented out for future revision debugging
// console.log('Modified Query');
// console.log(finalQuery);
let contextData = {};
if (templateQueryToExecute) {
const {data} = await client.query({
query: gql(finalQuery),
variables: {...templateObject.variables},
});
contextData = data;
}
return {contextData, useShopSpecificTemplate};
}
/**
* Apply sorters to the AST
* @param ast
@@ -262,7 +327,6 @@ export function applyFilters(ast, filters) {
});
}
/**
* Get the GraphQL kind for a value
* @param value

348
package-lock.json generated
View File

@@ -9,9 +9,9 @@
"version": "0.0.1",
"license": "UNLICENSED",
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.513.0",
"@aws-sdk/client-ses": "^3.513.0",
"@aws-sdk/credential-provider-node": "^3.513.0",
"@aws-sdk/client-secrets-manager": "^3.515.0",
"@aws-sdk/client-ses": "^3.515.0",
"@aws-sdk/credential-provider-node": "^3.515.0",
"@opensearch-project/opensearch": "^2.5.0",
"aws4": "^1.12.0",
"axios": "^1.6.5",
@@ -23,7 +23,7 @@
"cors": "2.8.5",
"csrf": "^3.1.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.4",
"dotenv": "^16.4.5",
"express": "^4.18.2",
"firebase-admin": "^12.0.0",
"graphql": "^16.8.1",
@@ -31,7 +31,7 @@
"graylog2": "^0.2.1",
"inline-css": "^4.0.2",
"intuit-oauth": "^4.0.0",
"json-2-csv": "^5.0.1",
"json-2-csv": "^5.2.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
@@ -39,13 +39,13 @@
"node-mailjet": "^6.0.5",
"node-persist": "^4.0.1",
"node-quickbooks": "^2.0.43",
"nodemailer": "^6.9.9",
"nodemailer": "^6.9.10",
"phone": "^3.1.42",
"rimraf": "^5.0.5",
"soap": "^1.0.0",
"socket.io": "^4.7.4",
"ssh2-sftp-client": "^10.0.3",
"stripe": "^14.16.0",
"stripe": "^14.18.0",
"twilio": "^4.22.0",
"uuid": "^9.0.1",
"xml2js": "^0.6.2",
@@ -152,24 +152,24 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@aws-sdk/client-secrets-manager": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.513.0.tgz",
"integrity": "sha512-6ZDYjjPqiF59Tm01wz9AqOUiZxcuDKFHvW0Vs2ugx/OoffEkguXdyYKieyykuUEFFT+Qh9oP38v/mQNRhRubEA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.515.0.tgz",
"integrity": "sha512-YO7SVh0mQ55COP5LcKsXE+o6wsOBBn3beAqKDZIBdjXho5rNhTdvbtaGTiaZmv0ALtu7TxtPVixhbDE0y1QseA==",
"dependencies": {
"@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/client-sts": "3.513.0",
"@aws-sdk/client-sts": "3.515.0",
"@aws-sdk/core": "3.513.0",
"@aws-sdk/credential-provider-node": "3.513.0",
"@aws-sdk/middleware-host-header": "3.511.0",
"@aws-sdk/middleware-logger": "3.511.0",
"@aws-sdk/middleware-recursion-detection": "3.511.0",
"@aws-sdk/middleware-user-agent": "3.511.0",
"@aws-sdk/region-config-resolver": "3.511.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/util-endpoints": "3.511.0",
"@aws-sdk/util-user-agent-browser": "3.511.0",
"@aws-sdk/util-user-agent-node": "3.511.0",
"@aws-sdk/credential-provider-node": "3.515.0",
"@aws-sdk/middleware-host-header": "3.515.0",
"@aws-sdk/middleware-logger": "3.515.0",
"@aws-sdk/middleware-recursion-detection": "3.515.0",
"@aws-sdk/middleware-user-agent": "3.515.0",
"@aws-sdk/region-config-resolver": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@aws-sdk/util-endpoints": "3.515.0",
"@aws-sdk/util-user-agent-browser": "3.515.0",
"@aws-sdk/util-user-agent-node": "3.515.0",
"@smithy/config-resolver": "^2.1.1",
"@smithy/core": "^1.3.2",
"@smithy/fetch-http-handler": "^2.4.1",
@@ -196,39 +196,31 @@
"@smithy/util-retry": "^2.1.1",
"@smithy/util-utf8": "^2.1.1",
"tslib": "^2.5.0",
"uuid": "^8.3.2"
"uuid": "^9.0.1"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@aws-sdk/client-secrets-manager/node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/@aws-sdk/client-ses": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.513.0.tgz",
"integrity": "sha512-9pvzyCZGVO283OPAdUkSC4QPY7Sfk9jNqs0gzLQvqM1FggjS1jc6vbMqBcRCte87fXkSPyLo0IEX/kaMH4dEMQ==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.515.0.tgz",
"integrity": "sha512-X51TvcpqJ83ZOSUa/efWl+cj3cXBF6fCb2iNghjRD2McDvzGKoiR+Zaoy05doPdh/GZ7azTBqX0qKRIyUj//wg==",
"dependencies": {
"@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/client-sts": "3.513.0",
"@aws-sdk/client-sts": "3.515.0",
"@aws-sdk/core": "3.513.0",
"@aws-sdk/credential-provider-node": "3.513.0",
"@aws-sdk/middleware-host-header": "3.511.0",
"@aws-sdk/middleware-logger": "3.511.0",
"@aws-sdk/middleware-recursion-detection": "3.511.0",
"@aws-sdk/middleware-user-agent": "3.511.0",
"@aws-sdk/region-config-resolver": "3.511.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/util-endpoints": "3.511.0",
"@aws-sdk/util-user-agent-browser": "3.511.0",
"@aws-sdk/util-user-agent-node": "3.511.0",
"@aws-sdk/credential-provider-node": "3.515.0",
"@aws-sdk/middleware-host-header": "3.515.0",
"@aws-sdk/middleware-logger": "3.515.0",
"@aws-sdk/middleware-recursion-detection": "3.515.0",
"@aws-sdk/middleware-user-agent": "3.515.0",
"@aws-sdk/region-config-resolver": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@aws-sdk/util-endpoints": "3.515.0",
"@aws-sdk/util-user-agent-browser": "3.515.0",
"@aws-sdk/util-user-agent-node": "3.515.0",
"@smithy/config-resolver": "^2.1.1",
"@smithy/core": "^1.3.2",
"@smithy/fetch-http-handler": "^2.4.1",
@@ -263,22 +255,22 @@
}
},
"node_modules/@aws-sdk/client-sso": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.513.0.tgz",
"integrity": "sha512-621Aj/KrgvKJXXViatb3zM+TdM3n+lodmMbSm+FH37RqYoj36s5FgmXan3Ebu9WBu1lUzKm+a3ZyRWVces52uQ==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.515.0.tgz",
"integrity": "sha512-4oGBLW476zmkdN98lAns3bObRNO+DLOfg4MDUSR6l6GYBV/zGAtoy2O/FhwYKgA2L5h2ZtElGopLlk/1Q0ePLw==",
"dependencies": {
"@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/core": "3.513.0",
"@aws-sdk/middleware-host-header": "3.511.0",
"@aws-sdk/middleware-logger": "3.511.0",
"@aws-sdk/middleware-recursion-detection": "3.511.0",
"@aws-sdk/middleware-user-agent": "3.511.0",
"@aws-sdk/region-config-resolver": "3.511.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/util-endpoints": "3.511.0",
"@aws-sdk/util-user-agent-browser": "3.511.0",
"@aws-sdk/util-user-agent-node": "3.511.0",
"@aws-sdk/middleware-host-header": "3.515.0",
"@aws-sdk/middleware-logger": "3.515.0",
"@aws-sdk/middleware-recursion-detection": "3.515.0",
"@aws-sdk/middleware-user-agent": "3.515.0",
"@aws-sdk/region-config-resolver": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@aws-sdk/util-endpoints": "3.515.0",
"@aws-sdk/util-user-agent-browser": "3.515.0",
"@aws-sdk/util-user-agent-node": "3.515.0",
"@smithy/config-resolver": "^2.1.1",
"@smithy/core": "^1.3.2",
"@smithy/fetch-http-handler": "^2.4.1",
@@ -311,23 +303,23 @@
}
},
"node_modules/@aws-sdk/client-sso-oidc": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.513.0.tgz",
"integrity": "sha512-DyncBVOR5aENL6vOeHPllIAwWUaDZdj1aRKVWiNECG4LuuwwjASX0wFLxTRe/4al3Ugob0OLqsrgC2hd59BLJA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.515.0.tgz",
"integrity": "sha512-zACa8LNlPUdlNUBqQRf5a3MfouLNtcBfm84v2c8M976DwJrMGONPe1QjyLLsD38uESQiXiVQRruj/b000iMXNw==",
"dependencies": {
"@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/client-sts": "3.513.0",
"@aws-sdk/client-sts": "3.515.0",
"@aws-sdk/core": "3.513.0",
"@aws-sdk/middleware-host-header": "3.511.0",
"@aws-sdk/middleware-logger": "3.511.0",
"@aws-sdk/middleware-recursion-detection": "3.511.0",
"@aws-sdk/middleware-user-agent": "3.511.0",
"@aws-sdk/region-config-resolver": "3.511.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/util-endpoints": "3.511.0",
"@aws-sdk/util-user-agent-browser": "3.511.0",
"@aws-sdk/util-user-agent-node": "3.511.0",
"@aws-sdk/middleware-host-header": "3.515.0",
"@aws-sdk/middleware-logger": "3.515.0",
"@aws-sdk/middleware-recursion-detection": "3.515.0",
"@aws-sdk/middleware-user-agent": "3.515.0",
"@aws-sdk/region-config-resolver": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@aws-sdk/util-endpoints": "3.515.0",
"@aws-sdk/util-user-agent-browser": "3.515.0",
"@aws-sdk/util-user-agent-node": "3.515.0",
"@smithy/config-resolver": "^2.1.1",
"@smithy/core": "^1.3.2",
"@smithy/fetch-http-handler": "^2.4.1",
@@ -359,26 +351,26 @@
"node": ">=14.0.0"
},
"peerDependencies": {
"@aws-sdk/credential-provider-node": "^3.513.0"
"@aws-sdk/credential-provider-node": "^3.515.0"
}
},
"node_modules/@aws-sdk/client-sts": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.513.0.tgz",
"integrity": "sha512-reWhX5CO+XZhT8xIdDPnEws0KQNBuvcSY2W7niSPVYfq1mOLkQgYenP/sC/TyvnNuZDzgcmJQdbdAKHuZvMuUQ==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.515.0.tgz",
"integrity": "sha512-ScYuvaIDgip3atOJIA1FU2n0gJkEdveu1KrrCPathoUCV5zpK8qQmO/n+Fj/7hKFxeKdFbB+4W4CsJWYH94nlg==",
"dependencies": {
"@aws-crypto/sha256-browser": "3.0.0",
"@aws-crypto/sha256-js": "3.0.0",
"@aws-sdk/core": "3.513.0",
"@aws-sdk/middleware-host-header": "3.511.0",
"@aws-sdk/middleware-logger": "3.511.0",
"@aws-sdk/middleware-recursion-detection": "3.511.0",
"@aws-sdk/middleware-user-agent": "3.511.0",
"@aws-sdk/region-config-resolver": "3.511.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/util-endpoints": "3.511.0",
"@aws-sdk/util-user-agent-browser": "3.511.0",
"@aws-sdk/util-user-agent-node": "3.511.0",
"@aws-sdk/middleware-host-header": "3.515.0",
"@aws-sdk/middleware-logger": "3.515.0",
"@aws-sdk/middleware-recursion-detection": "3.515.0",
"@aws-sdk/middleware-user-agent": "3.515.0",
"@aws-sdk/region-config-resolver": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@aws-sdk/util-endpoints": "3.515.0",
"@aws-sdk/util-user-agent-browser": "3.515.0",
"@aws-sdk/util-user-agent-node": "3.515.0",
"@smithy/config-resolver": "^2.1.1",
"@smithy/core": "^1.3.2",
"@smithy/fetch-http-handler": "^2.4.1",
@@ -411,7 +403,7 @@
"node": ">=14.0.0"
},
"peerDependencies": {
"@aws-sdk/credential-provider-node": "^3.513.0"
"@aws-sdk/credential-provider-node": "^3.515.0"
}
},
"node_modules/@aws-sdk/core": {
@@ -431,11 +423,11 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.511.0.tgz",
"integrity": "sha512-4VUsnLRox8YzxnZwnFrfZM4bL5KKLhsjjjX7oiuLyzFkhauI4HFYt7rTB8YNGphpqAg/Wzw5DBZfO3Bw1iR1HA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.515.0.tgz",
"integrity": "sha512-45vxdyqhTAaUMERYVWOziG3K8L2TV9G4ryQS/KZ84o7NAybE9GMdoZRVmGHAO7mJJ1wQiYCM/E+i5b3NW9JfNA==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/property-provider": "^2.1.1",
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
@@ -445,11 +437,11 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.511.0.tgz",
"integrity": "sha512-y83Gt8GPpgMe/lMFxIq+0G2rbzLTC6lhrDocHUzqcApLD6wet8Esy2iYckSRlJgYY+qsVAzpLrSMtt85DwRPTw==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.515.0.tgz",
"integrity": "sha512-Ba6FXK77vU4WyheiamNjEuTFmir0eAXuJGPO27lBaA8g+V/seXGHScsbOG14aQGDOr2P02OPwKGZrWWA7BFpfQ==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/fetch-http-handler": "^2.4.1",
"@smithy/node-http-handler": "^2.3.1",
"@smithy/property-provider": "^2.1.1",
@@ -464,16 +456,16 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.513.0.tgz",
"integrity": "sha512-J9FAmTVHm9RsXxXluXCmJ+crkZPDpdNQhiVrbmPPq989lfr0u33rf1aKFMF5AyHNcNEWeAYKKBQwJJkcsxStIA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.515.0.tgz",
"integrity": "sha512-ouDlNZdv2TKeVEA/YZk2+XklTXyAAGdbWnl4IgN9ItaodWI+lZjdIoNC8BAooVH+atIV/cZgoGTGQL7j2TxJ9A==",
"dependencies": {
"@aws-sdk/client-sts": "3.513.0",
"@aws-sdk/credential-provider-env": "3.511.0",
"@aws-sdk/credential-provider-process": "3.511.0",
"@aws-sdk/credential-provider-sso": "3.513.0",
"@aws-sdk/credential-provider-web-identity": "3.513.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/client-sts": "3.515.0",
"@aws-sdk/credential-provider-env": "3.515.0",
"@aws-sdk/credential-provider-process": "3.515.0",
"@aws-sdk/credential-provider-sso": "3.515.0",
"@aws-sdk/credential-provider-web-identity": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@smithy/credential-provider-imds": "^2.2.1",
"@smithy/property-provider": "^2.1.1",
"@smithy/shared-ini-file-loader": "^2.3.1",
@@ -485,17 +477,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-node": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.513.0.tgz",
"integrity": "sha512-Cp6tYUJ+g8zJxI8vE0A9W6AxRLq3iR2zGGKsrPLNmZkUaHoVaJiNEd+2nL9RwCqDRve+N+Sh3mbZrLiqh3DO6A==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.515.0.tgz",
"integrity": "sha512-Y4kHSpbxksiCZZNcvsiKUd8Fb2XlyUuONEwqWFNL82ZH6TCCjBGS31wJQCSxBHqYcOL3tiORUEJkoO7uS30uQA==",
"dependencies": {
"@aws-sdk/credential-provider-env": "3.511.0",
"@aws-sdk/credential-provider-http": "3.511.0",
"@aws-sdk/credential-provider-ini": "3.513.0",
"@aws-sdk/credential-provider-process": "3.511.0",
"@aws-sdk/credential-provider-sso": "3.513.0",
"@aws-sdk/credential-provider-web-identity": "3.513.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/credential-provider-env": "3.515.0",
"@aws-sdk/credential-provider-http": "3.515.0",
"@aws-sdk/credential-provider-ini": "3.515.0",
"@aws-sdk/credential-provider-process": "3.515.0",
"@aws-sdk/credential-provider-sso": "3.515.0",
"@aws-sdk/credential-provider-web-identity": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@smithy/credential-provider-imds": "^2.2.1",
"@smithy/property-provider": "^2.1.1",
"@smithy/shared-ini-file-loader": "^2.3.1",
@@ -507,11 +499,11 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.511.0.tgz",
"integrity": "sha512-88hLUPqcTwjSubPS+34ZfmglnKeLny8GbmZsyllk96l26PmDTAqo5RScSA8BWxL0l5pRRWGtcrFyts+oibHIuQ==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.515.0.tgz",
"integrity": "sha512-pSjiOA2FM63LHRKNDvEpBRp80FVGT0Mw/gzgbqFXP+sewk0WVonYbEcMDTJptH3VsLPGzqH/DQ1YL/aEIBuXFQ==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/property-provider": "^2.1.1",
"@smithy/shared-ini-file-loader": "^2.3.1",
"@smithy/types": "^2.9.1",
@@ -522,13 +514,13 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.513.0.tgz",
"integrity": "sha512-q9rRwRWVut97+hnc0Yt77tGeKoPLLDpKKVpVGC6e+EQHlXM4H6oq2VGLgXYJPA9HpMJ3t5zmmgHxEafYeFZo+w==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.515.0.tgz",
"integrity": "sha512-j7vUkiSmuhpBvZYoPTRTI4ePnQbiZMFl6TNhg9b9DprC1zHkucsZnhRhqjOVlrw/H6J4jmcPGcHHTZ5WQNI5xQ==",
"dependencies": {
"@aws-sdk/client-sso": "3.513.0",
"@aws-sdk/token-providers": "3.513.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/client-sso": "3.515.0",
"@aws-sdk/token-providers": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@smithy/property-provider": "^2.1.1",
"@smithy/shared-ini-file-loader": "^2.3.1",
"@smithy/types": "^2.9.1",
@@ -539,12 +531,12 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.513.0.tgz",
"integrity": "sha512-0EZUQhbDaV3jxvIjcWEGiGmioFS0vEvUxaJrMgeRLUo9njZfLZ4VaEMsqPnZ9rMz2w9CxfpDeObEQlDzYeGRgA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.515.0.tgz",
"integrity": "sha512-66+2g4z3fWwdoGReY8aUHvm6JrKZMTRxjuizljVmMyOBttKPeBYXvUTop/g3ZGUx1f8j+C5qsGK52viYBvtjuQ==",
"dependencies": {
"@aws-sdk/client-sts": "3.513.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/client-sts": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@smithy/property-provider": "^2.1.1",
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
@@ -554,11 +546,11 @@
}
},
"node_modules/@aws-sdk/middleware-host-header": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.511.0.tgz",
"integrity": "sha512-DbBzQP/6woSHR/+g9dHN3YiYaLIqFw9u8lQFMxi3rT3hqITFVYLzzXtEaHjDD6/is56pNT84CIKbyJ6/gY5d1Q==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.515.0.tgz",
"integrity": "sha512-I1MwWPzdRKM1luvdDdjdGsDjNVPhj9zaIytEchjTY40NcKOg+p2evLD2y69ozzg8pyXK63r8DdvDGOo9QPuh0A==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/protocol-http": "^3.1.1",
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
@@ -568,11 +560,11 @@
}
},
"node_modules/@aws-sdk/middleware-logger": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.511.0.tgz",
"integrity": "sha512-EYU9dBlJXvQcCsM2Tfgi0NQoXrqovfDv/fDy8oGJgZFrgNuHDti8tdVVxeJTUJNEAF67xlDl5o+rWEkKthkYGQ==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.515.0.tgz",
"integrity": "sha512-qXomJzg2m/5seQOxHi/yOXOKfSjwrrJSmEmfwJKJyQgdMbBcjz3Cz0H/1LyC6c5hHm6a/SZgSTzDAbAoUmyL+Q==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
},
@@ -581,11 +573,11 @@
}
},
"node_modules/@aws-sdk/middleware-recursion-detection": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.511.0.tgz",
"integrity": "sha512-PlNPCV/6zpDVdNx1K69xDTh/wPNU4WyP4qa6hUo2/+4/PNG5HI9xbCWtpb4RjhdTRw6qDtkBNcPICHbtWx5aHg==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.515.0.tgz",
"integrity": "sha512-dokHLbTV3IHRIBrw9mGoxcNTnQsjlm7TpkJhPdGT9T4Mq399EyQo51u6IsVMm07RXLl2Zw7u+u9p+qWBFzmFRA==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/protocol-http": "^3.1.1",
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
@@ -595,12 +587,12 @@
}
},
"node_modules/@aws-sdk/middleware-user-agent": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.511.0.tgz",
"integrity": "sha512-eLs+CxP2QCXh3tCGYCdAml3oyWj8MSIwKbH+8rKw0k/5vmY1YJDBy526whOxx61ivhz2e0muuijN4X5EZZ2Pnw==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.515.0.tgz",
"integrity": "sha512-nOqZjGA/GkjuJ5fUshec9Fv6HFd7ovOTxMJbw3MfAhqXuVZ6dKF41lpVJ4imNsgyFt3shUg9WDY8zGFjlYMB3g==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/util-endpoints": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@aws-sdk/util-endpoints": "3.515.0",
"@smithy/protocol-http": "^3.1.1",
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
@@ -610,11 +602,11 @@
}
},
"node_modules/@aws-sdk/region-config-resolver": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.511.0.tgz",
"integrity": "sha512-RzBLSNaRd4iEkQyEGfiSNvSnWU/x23rsiFgA9tqYFA0Vqx7YmzSWC8QBUxpwybB8HkbbL9wNVKQqTbhI3mYneQ==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.515.0.tgz",
"integrity": "sha512-RIRx9loxMgEAc/r1wPfnfShOuzn4RBi8pPPv6/jhhITEeMnJe6enAh2k5y9DdiVDDgCWZgVFSv0YkAIfzAFsnQ==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/node-config-provider": "^2.2.1",
"@smithy/types": "^2.9.1",
"@smithy/util-config-provider": "^2.2.1",
@@ -626,12 +618,12 @@
}
},
"node_modules/@aws-sdk/token-providers": {
"version": "3.513.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.513.0.tgz",
"integrity": "sha512-S27iFzj3dVRw1q+xLtqTGZOfYG95OwvTN7crvS2daqSYfcWN+dhEPzQJdDvGaAnAI45bWm8rppH/EYzrlxeZoA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.515.0.tgz",
"integrity": "sha512-MQuf04rIcTXqwDzmyHSpFPF1fKEzRl64oXtCRUF3ddxTdK6wxXkePfK6wNCuL+GEbEcJAoCtIGIRpzGPJvQjHA==",
"dependencies": {
"@aws-sdk/client-sso-oidc": "3.513.0",
"@aws-sdk/types": "3.511.0",
"@aws-sdk/client-sso-oidc": "3.515.0",
"@aws-sdk/types": "3.515.0",
"@smithy/property-provider": "^2.1.1",
"@smithy/shared-ini-file-loader": "^2.3.1",
"@smithy/types": "^2.9.1",
@@ -642,9 +634,9 @@
}
},
"node_modules/@aws-sdk/types": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.511.0.tgz",
"integrity": "sha512-P03ufufxmkvd7nO46oOeEqYIMPJ8qMCKxAsfJk1JBVPQ1XctVntbail4/UFnrnzij8DTl4Mk/D62uGo7+RolXA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.515.0.tgz",
"integrity": "sha512-B3gUpiMlpT6ERaLvZZ61D0RyrQPsFYDkCncLPVkZOKkCOoFU46zi1o6T5JcYiz8vkx1q9RGloQ5exh79s5pU/w==",
"dependencies": {
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
@@ -654,11 +646,11 @@
}
},
"node_modules/@aws-sdk/util-endpoints": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.511.0.tgz",
"integrity": "sha512-J/5hsscJkg2pAOdLx1YKlyMCk5lFRxRxEtup9xipzOxVBlqOIE72Tuu31fbxSlF8XzO/AuCJcZL4m1v098K9oA==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.515.0.tgz",
"integrity": "sha512-UJi+jdwcGFV/F7d3+e2aQn5yZOVpDiAgfgNhPnEtgV0WozJ5/ZUeZBgWvSc/K415N4A4D/9cbBc7+I+35qzcDQ==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/types": "^2.9.1",
"@smithy/util-endpoints": "^1.1.1",
"tslib": "^2.5.0"
@@ -679,22 +671,22 @@
}
},
"node_modules/@aws-sdk/util-user-agent-browser": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.511.0.tgz",
"integrity": "sha512-5LuESdwtIcA10aHcX7pde7aCIijcyTPBXFuXmFlDTgm/naAayQxelQDpvgbzuzGLgePf8eTyyhDKhzwPZ2EqiQ==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.515.0.tgz",
"integrity": "sha512-pTWQb0JCafTmLHLDv3Qqs/nAAJghcPdGQIBpsCStb0YEzg3At/dOi2AIQ683yYnXmeOxLXJDzmlsovfVObJScw==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/types": "^2.9.1",
"bowser": "^2.11.0",
"tslib": "^2.5.0"
}
},
"node_modules/@aws-sdk/util-user-agent-node": {
"version": "3.511.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.511.0.tgz",
"integrity": "sha512-UopdlRvYY5mxlS4wwFv+QAWL6/T302wmoQj7i+RY+c/D3Ej3PKBb/mW3r2wEOgZLJmPpeeM1SYMk+rVmsW1rqw==",
"version": "3.515.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.515.0.tgz",
"integrity": "sha512-A/KJ+/HTohHyVXLH+t/bO0Z2mPrQgELbQO8tX+B2nElo8uklj70r5cT7F8ETsI9oOy+HDVpiL5/v45ZgpUOiPg==",
"dependencies": {
"@aws-sdk/types": "3.511.0",
"@aws-sdk/types": "3.515.0",
"@smithy/node-config-provider": "^2.2.1",
"@smithy/types": "^2.9.1",
"tslib": "^2.5.0"
@@ -3018,9 +3010,9 @@
}
},
"node_modules/dotenv": {
"version": "16.4.4",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz",
"integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==",
"version": "16.4.5",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
"engines": {
"node": ">=12"
},
@@ -4367,9 +4359,9 @@
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
},
"node_modules/json-2-csv": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-5.0.1.tgz",
"integrity": "sha512-rP9ChyMskS0angbvFdQ43SwEe72mEvqcY1/V2OeukQWxtlreUuZWhMlTdWjtd4L6kJxq+HPFTI06yqLvZiEVIA==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-5.2.0.tgz",
"integrity": "sha512-C+XmSKRCS7zSTENm7Ha/lhLkO2ZE+fcSNC2kLiWSEGKy6ZwRCG2KakMJj0bvyfy2U8oZY+KFoU8F1isCgpUBYg==",
"dependencies": {
"deeks": "3.0.2",
"doc-path": "4.0.2"
@@ -4915,9 +4907,9 @@
}
},
"node_modules/nodemailer": {
"version": "6.9.9",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.9.tgz",
"integrity": "sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==",
"version": "6.9.10",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.10.tgz",
"integrity": "sha512-qtoKfGFhvIFW5kLfrkw2R6Nm6Ur4LNUMykyqu6n9BRKJuyQrqEGwdXXUAbwWEKt33dlWUGXb7rzmJP/p4+O+CA==",
"engines": {
"node": ">=6.0.0"
}
@@ -6314,9 +6306,9 @@
}
},
"node_modules/stripe": {
"version": "14.16.0",
"resolved": "https://registry.npmjs.org/stripe/-/stripe-14.16.0.tgz",
"integrity": "sha512-1gOr2LzafWV84cPIO5Md/QPh4XVPLKULVuRpBVOV3Plq3seiHmg/eeOktX+hDl8jpNZuORHYaUJGrNqrABLwdg==",
"version": "14.18.0",
"resolved": "https://registry.npmjs.org/stripe/-/stripe-14.18.0.tgz",
"integrity": "sha512-yLqKPqYgGJbMxrQiE4+i2i00ZVA2NRIZbZ1rejzj5XR3F3Uc+1iy9QE133knZudhVGMw367b8vTpB8D9pYMETw==",
"dependencies": {
"@types/node": ">=8.1.0",
"qs": "^6.11.0"

View File

@@ -18,9 +18,9 @@
"start": "node server.js"
},
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.513.0",
"@aws-sdk/client-ses": "^3.513.0",
"@aws-sdk/credential-provider-node": "^3.513.0",
"@aws-sdk/client-secrets-manager": "^3.515.0",
"@aws-sdk/client-ses": "^3.515.0",
"@aws-sdk/credential-provider-node": "^3.515.0",
"@opensearch-project/opensearch": "^2.5.0",
"aws4": "^1.12.0",
"axios": "^1.6.5",
@@ -32,7 +32,7 @@
"cors": "2.8.5",
"csrf": "^3.1.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.4",
"dotenv": "^16.4.5",
"express": "^4.18.2",
"firebase-admin": "^12.0.0",
"graphql": "^16.8.1",
@@ -40,7 +40,7 @@
"graylog2": "^0.2.1",
"inline-css": "^4.0.2",
"intuit-oauth": "^4.0.0",
"json-2-csv": "^5.0.1",
"json-2-csv": "^5.2.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
@@ -48,13 +48,13 @@
"node-mailjet": "^6.0.5",
"node-persist": "^4.0.1",
"node-quickbooks": "^2.0.43",
"nodemailer": "^6.9.9",
"nodemailer": "^6.9.10",
"phone": "^3.1.42",
"rimraf": "^5.0.5",
"soap": "^1.0.0",
"socket.io": "^4.7.4",
"ssh2-sftp-client": "^10.0.3",
"stripe": "^14.16.0",
"stripe": "^14.18.0",
"twilio": "^4.22.0",
"uuid": "^9.0.1",
"xml2js": "^0.6.2",

View File

@@ -45,7 +45,6 @@ async function JobCostingMulti(req, res) {
logger.log("job-costing-multi-start", "DEBUG", req.user.email, jobids, null);
try {
const resp = await client
.setHeaders({Authorization: BearerToken})