diff --git a/client/package-lock.json b/client/package-lock.json
index e9c5f52b6..8ff1ef726 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -9,7 +9,7 @@
"version": "0.2.1",
"hasInstallScript": true,
"dependencies": {
- "@amplitude/analytics-browser": "^2.37.0",
+ "@amplitude/analytics-browser": "^2.38.0",
"@ant-design/pro-layout": "^7.22.6",
"@apollo/client": "^4.1.6",
"@dnd-kit/core": "^6.3.1",
@@ -25,29 +25,29 @@
"@firebase/messaging": "^0.12.25",
"@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.11.2",
- "@sentry/cli": "^3.3.3",
- "@sentry/react": "^10.45.0",
+ "@sentry/cli": "^3.3.5",
+ "@sentry/react": "^10.47.0",
"@sentry/vite-plugin": "^4.9.1",
"@splitsoftware/splitio-react": "^2.6.1",
"@tanem/react-nprogress": "^5.0.63",
- "antd": "^6.3.3",
+ "antd": "^6.3.5",
"apollo-link-logger": "^3.0.0",
"autosize": "^6.0.1",
- "axios": "^1.13.6",
+ "axios": "^1.14.0",
"classnames": "^2.5.1",
"css-box-model": "^1.2.1",
"dayjs": "^1.11.20",
- "dayjs-business-days2": "^1.3.2",
+ "dayjs-business-days2": "^1.3.3",
"dinero.js": "^1.9.1",
"dotenv": "^17.3.1",
"env-cmd": "^11.0.0",
"exifr": "^7.1.3",
- "graphql": "^16.13.1",
- "graphql-ws": "^6.0.7",
- "i18next": "^25.10.5",
+ "graphql": "^16.13.2",
+ "graphql-ws": "^6.0.8",
+ "i18next": "^25.10.10",
"i18next-browser-languagedetector": "^8.2.1",
"immutability-helper": "^3.1.1",
- "libphonenumber-js": "^1.12.40",
+ "libphonenumber-js": "^1.12.41",
"lightningcss": "^1.32.0",
"logrocket": "^12.1.0",
"markerjs2": "^2.32.7",
@@ -55,18 +55,18 @@
"normalize-url": "^8.1.1",
"object-hash": "^3.0.0",
"phone": "^3.1.71",
- "posthog-js": "^1.363.2",
+ "posthog-js": "^1.364.4",
"prop-types": "^15.8.1",
"query-string": "^9.3.1",
"raf-schd": "^4.0.3",
"react": "^19.2.4",
"react-big-calendar": "^1.19.4",
"react-color": "^2.19.3",
- "react-cookie": "^8.0.1",
+ "react-cookie": "^8.1.0",
"react-dom": "^19.2.4",
"react-grid-gallery": "^1.0.1",
- "react-grid-layout": "^2.2.2",
- "react-i18next": "^16.6.2",
+ "react-grid-layout": "^2.2.3",
+ "react-i18next": "^16.6.6",
"react-icons": "^5.6.0",
"react-image-lightbox": "^5.1.4",
"react-markdown": "^10.1.0",
@@ -78,7 +78,7 @@
"react-router-dom": "^7.13.2",
"react-sticky": "^6.0.3",
"react-virtuoso": "^4.18.3",
- "recharts": "^3.8.0",
+ "recharts": "^3.8.1",
"redux": "^5.0.1",
"redux-actions": "^3.0.3",
"redux-persist": "^6.0.0",
@@ -90,13 +90,13 @@
"socket.io-client": "^4.8.3",
"styled-components": "^6.3.12",
"vite-plugin-ejs": "^1.7.0",
- "web-vitals": "^5.1.0"
+ "web-vitals": "^5.2.0"
},
"devDependencies": {
- "@ant-design/icons": "^6.1.0",
+ "@ant-design/icons": "^6.1.1",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-react": "^7.28.5",
- "@dotenvx/dotenvx": "^1.57.2",
+ "@dotenvx/dotenvx": "^1.59.1",
"@emotion/babel-plugin": "^11.13.5",
"@emotion/react": "^11.14.0",
"@eslint/js": "^9.39.2",
@@ -106,7 +106,7 @@
"@testing-library/react": "^16.3.2",
"@vitejs/plugin-react": "^5.1.4",
"babel-plugin-react-compiler": "^1.0.0",
- "browserslist": "^4.28.1",
+ "browserslist": "^4.28.2",
"browserslist-to-esbuild": "^2.1.1",
"chalk": "^5.6.2",
"eslint": "^9.39.2",
@@ -123,10 +123,10 @@
"vite": "^7.3.1",
"vite-plugin-babel": "^1.6.0",
"vite-plugin-eslint": "^1.8.1",
- "vite-plugin-node-polyfills": "^0.25.0",
+ "vite-plugin-node-polyfills": "^0.26.0",
"vite-plugin-pwa": "^1.2.0",
"vite-plugin-style-import": "^2.0.0",
- "vitest": "^4.1.0",
+ "vitest": "^4.1.2",
"workbox-window": "^7.4.0"
},
"engines": {
@@ -151,18 +151,18 @@
"license": "MIT"
},
"node_modules/@amplitude/analytics-browser": {
- "version": "2.37.0",
- "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.37.0.tgz",
- "integrity": "sha512-/BWDneHRfq6+9bcPQC09Ep79SEj7aRJLZ1jJrPHtxA9KZJUz2au2COlJc1ReCaNzCcrA1xXv/MQ0Fv7TwoBglg==",
+ "version": "2.38.0",
+ "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.38.0.tgz",
+ "integrity": "sha512-MhqyEkr1gGAR4s4GSSflDhFVheIx9Nv3FfElQu9NlNrXB2Hh3BEOyVgdK7hgfi6NJwFyfw30+t5lym+njtA8hA==",
"license": "MIT",
"dependencies": {
- "@amplitude/analytics-core": "2.43.0",
- "@amplitude/plugin-autocapture-browser": "1.24.1",
- "@amplitude/plugin-custom-enrichment-browser": "0.1.0",
- "@amplitude/plugin-network-capture-browser": "1.9.9",
- "@amplitude/plugin-page-url-enrichment-browser": "0.7.0",
- "@amplitude/plugin-page-view-tracking-browser": "2.9.1",
- "@amplitude/plugin-web-vitals-browser": "1.1.24",
+ "@amplitude/analytics-core": "2.44.0",
+ "@amplitude/plugin-autocapture-browser": "1.25.0",
+ "@amplitude/plugin-custom-enrichment-browser": "0.1.2",
+ "@amplitude/plugin-network-capture-browser": "1.9.11",
+ "@amplitude/plugin-page-url-enrichment-browser": "0.7.3",
+ "@amplitude/plugin-page-view-tracking-browser": "2.9.4",
+ "@amplitude/plugin-web-vitals-browser": "1.1.26",
"tslib": "^2.4.1"
}
},
@@ -173,9 +173,9 @@
"license": "MIT"
},
"node_modules/@amplitude/analytics-core": {
- "version": "2.43.0",
- "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.43.0.tgz",
- "integrity": "sha512-rcDqi4cmI9Ro7hN5wjAuTm92IdN2i0lhIDAj+JOd9BP3SRMrhhiw2lzcScj3owig8CiV9X7EHPTuZe6XCTfIgQ==",
+ "version": "2.44.0",
+ "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.44.0.tgz",
+ "integrity": "sha512-z9QuTxLqEQ8KIeAT6Vmy6K48rP9TUmjnb4GwUMYoV/fxu3B9ClTaN18zqXQMmDw9HwUiIreHiVbwTb7OQRN5aA==",
"license": "MIT",
"dependencies": {
"@amplitude/analytics-connector": "^1.6.4",
@@ -186,66 +186,72 @@
}
},
"node_modules/@amplitude/plugin-autocapture-browser": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@amplitude/plugin-autocapture-browser/-/plugin-autocapture-browser-1.24.1.tgz",
- "integrity": "sha512-cvjOFew2MFNBDTbk3+H7WNi3D0Jdp476m6faCaVhY99M5zqRCHDMRS7dC4HczvL9zYXlAcW9jAWucwES2m3TiQ==",
+ "version": "1.25.0",
+ "resolved": "https://registry.npmjs.org/@amplitude/plugin-autocapture-browser/-/plugin-autocapture-browser-1.25.0.tgz",
+ "integrity": "sha512-YuWsz8XmJuKu3NlMxkvlhLey/5tGCeOwwfsROHficR0yDWO9gNG0WtHl7A0Pw1PUc9iaXjqfG2AjYumAtiq16Q==",
"license": "MIT",
"dependencies": {
- "@amplitude/analytics-core": "2.43.0",
+ "@amplitude/analytics-core": "2.44.0",
"tslib": "^2.4.1"
}
},
"node_modules/@amplitude/plugin-custom-enrichment-browser": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/@amplitude/plugin-custom-enrichment-browser/-/plugin-custom-enrichment-browser-0.1.0.tgz",
- "integrity": "sha512-y3VmqZvCP1Z3jNgo/mtKVHON9L0P2SyqkMmUsbbFuLu1+TKIkicotnVq/lzlLU1TrW68mkInOM+We8JngasZBA==",
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@amplitude/plugin-custom-enrichment-browser/-/plugin-custom-enrichment-browser-0.1.2.tgz",
+ "integrity": "sha512-ZX9BKqs1E1OI7l7QCGu9JnB/1kqLN+zqIePgM2tuEhZNFQJaw4NhAMUaMRqvNnaCkHlmpVRISzSj/4D3tWMRtA==",
"license": "MIT",
"dependencies": {
- "@amplitude/analytics-core": "2.43.0",
+ "@amplitude/analytics-core": "2.44.0",
"tslib": "^2.4.1"
}
},
"node_modules/@amplitude/plugin-network-capture-browser": {
- "version": "1.9.9",
- "resolved": "https://registry.npmjs.org/@amplitude/plugin-network-capture-browser/-/plugin-network-capture-browser-1.9.9.tgz",
- "integrity": "sha512-SJIOQN04Mk9vCsnVd9QRcIvkMV7XSGZIKfbaKNQY5O3ueV33Kc8opm7YjPg2sWcxdzTcJijbCkOI0wCwOaRolg==",
+ "version": "1.9.11",
+ "resolved": "https://registry.npmjs.org/@amplitude/plugin-network-capture-browser/-/plugin-network-capture-browser-1.9.11.tgz",
+ "integrity": "sha512-49o3zYnKUmRdrxgAEcr1iHnXR1um40e1icO0hzugSq04k19hs27zcl3zpEk9geO+nNKwO744ryE1q93gqVbHrQ==",
"license": "MIT",
"dependencies": {
- "@amplitude/analytics-core": "2.43.0",
+ "@amplitude/analytics-core": "2.44.0",
"tslib": "^2.4.1"
}
},
"node_modules/@amplitude/plugin-page-url-enrichment-browser": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-url-enrichment-browser/-/plugin-page-url-enrichment-browser-0.7.0.tgz",
- "integrity": "sha512-MkM7TDq24k7ilUDNZISqjDSkVfmDJxWcnUagwYEXjLILhno5hGm7wdgFvVXXzKlZQHEogBxkbnq7wZXS9/YsMw==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-url-enrichment-browser/-/plugin-page-url-enrichment-browser-0.7.3.tgz",
+ "integrity": "sha512-3UZq/zKg4lcsRgziWAPSEeaUsNsbyjjxmsAE9kSDi/hIj5RaWnwWhY6TGhv45UAReugTA4vVZyFRg9btf3c/Fg==",
"license": "MIT",
"dependencies": {
- "@amplitude/analytics-core": "2.43.0",
+ "@amplitude/analytics-core": "2.44.0",
"tslib": "^2.4.1"
}
},
"node_modules/@amplitude/plugin-page-view-tracking-browser": {
- "version": "2.9.1",
- "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.9.1.tgz",
- "integrity": "sha512-jkxz2lkJDAfsjj7mpbPUZx9N3qJssC3uYyv8Nk73z+p+v0wjBikWdOoKuNQkcuP09701zRdXp9ziU8+qwkGusw==",
+ "version": "2.9.4",
+ "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.9.4.tgz",
+ "integrity": "sha512-J16zmEadnzNpkHSmzpTiQN2q9pGJ/4SkHONA9O8KxUsMU/MYTDgof3rAYY/w5B5rmvdxfMRCjqWtvnkizzgZ6w==",
"license": "MIT",
"dependencies": {
- "@amplitude/analytics-core": "2.43.0",
+ "@amplitude/analytics-core": "2.44.0",
"tslib": "^2.4.1"
}
},
"node_modules/@amplitude/plugin-web-vitals-browser": {
- "version": "1.1.24",
- "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-vitals-browser/-/plugin-web-vitals-browser-1.1.24.tgz",
- "integrity": "sha512-7AaytUK78RKdyDsblYJCKYan1lQi3Qzsp1WHItHJ+RSXPccmi4mCcvNtx0e8T9LmNJlUnsmYeEGR/6FaWvyvFg==",
+ "version": "1.1.26",
+ "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-vitals-browser/-/plugin-web-vitals-browser-1.1.26.tgz",
+ "integrity": "sha512-wiD4vy+f2fepr+8Lnn26TYYjDEnWsmlGhJog99x+xfbZ/D+stGdaCIOz5AOjU1TpTRvxvamEu2XuOh+8EZOCSA==",
"license": "MIT",
"dependencies": {
- "@amplitude/analytics-core": "2.43.0",
+ "@amplitude/analytics-core": "2.44.0",
"tslib": "^2.4.1",
"web-vitals": "5.1.0"
}
},
+ "node_modules/@amplitude/plugin-web-vitals-browser/node_modules/web-vitals": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-5.1.0.tgz",
+ "integrity": "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg==",
+ "license": "Apache-2.0"
+ },
"node_modules/@ant-design/colors": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.1.tgz",
@@ -327,9 +333,9 @@
}
},
"node_modules/@ant-design/icons": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-6.1.0.tgz",
- "integrity": "sha512-KrWMu1fIg3w/1F2zfn+JlfNDU8dDqILfA5Tg85iqs1lf8ooyGlbkA+TkwfOKKgqpUmAiRY1PTFpuOU2DAIgSUg==",
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-6.1.1.tgz",
+ "integrity": "sha512-AMT4N2y++TZETNHiM77fs4a0uPVCJGuL5MTonk13Pvv7UN7sID1cNEZOc1qNqx6zLKAOilTEFAdAoAFKa0U//Q==",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^8.0.0",
@@ -2588,9 +2594,9 @@
}
},
"node_modules/@dotenvx/dotenvx": {
- "version": "1.57.2",
- "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.57.2.tgz",
- "integrity": "sha512-lv9+UZPnl/KOvShepevLWm3+/wc1It5kgO5Q580evnvOFMZcgKVEYFwxlL7Ohl9my1yjTsWo28N3PJYUEO8wFQ==",
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.59.1.tgz",
+ "integrity": "sha512-Qg+meC+XFxliuVSDlEPkKnaUjdaJKK6FNx/Wwl2UxhQR8pyPIuLhMavsF7ePdB9qFZUWV1jEK3ckbJir/WmF4w==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -4864,18 +4870,18 @@
}
},
"node_modules/@posthog/core": {
- "version": "1.24.1",
- "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.24.1.tgz",
- "integrity": "sha512-e8AciAnc6MRFws89ux8lJKFAaI03yEon0ASDoUO7yS91FVqbUGXYekObUUR3LHplcg+pmyiJBI0jolY0SFbGRA==",
+ "version": "1.24.4",
+ "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.24.4.tgz",
+ "integrity": "sha512-S+TolwBHSSJz7WWtgaELQWQqXviSm3uf1e+qorWUts0bZcgPwWzhnmhCUZAhvn0NVpTQHDJ3epv+hHbPLl5dHg==",
"license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.6"
}
},
"node_modules/@posthog/types": {
- "version": "1.363.2",
- "resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.363.2.tgz",
- "integrity": "sha512-UcUwHEd2LXxWq4bW/I4TbwYcA+BHO/cSuHcNpGXjRCp76eJk1eOuQnm/a3MrfHtbt2X11CQu+eWpqiSgcv+X6A==",
+ "version": "1.364.4",
+ "resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.364.4.tgz",
+ "integrity": "sha512-U7NpIy9XWrzz1q/66xyDu8Wm12a7avNRKRn5ISPT5kuCJQRaeAaHuf+dpgrFnuqjCCgxg+oIY/ReJdlZ+8/z4Q==",
"license": "MIT"
},
"node_modules/@protobufjs/aspromise": {
@@ -5139,9 +5145,9 @@
}
},
"node_modules/@rc-component/form": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/@rc-component/form/-/form-1.7.2.tgz",
- "integrity": "sha512-5C90rXH7aZvvvxB4M5ew+QxROvimdL/lqhSshR8NsyiR7HKOoGQYSitxdfENnH6/0KNFxEy2ranVe2LrTnHZIw==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/form/-/form-1.8.0.tgz",
+ "integrity": "sha512-eUD5KKYnIZWmJwRA0vnyO/ovYUfHGU1svydY1OrqU5fw8Oz9Tdqvxvrlh0wl6xI/EW69dT7II49xpgOWzK3T5A==",
"license": "MIT",
"dependencies": {
"@rc-component/async-validator": "^5.1.0",
@@ -5166,14 +5172,14 @@
}
},
"node_modules/@rc-component/image": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@rc-component/image/-/image-1.6.0.tgz",
- "integrity": "sha512-tSfn2ZE/oP082g4QIOxeehkmgnXB7R+5AFj/lIFr4k7pEuxHBdyGIq9axoCY9qea8NN0DY6p4IB/F07tLqaT5A==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/image/-/image-1.8.0.tgz",
+ "integrity": "sha512-Dr41bFevLB5NgVaJhEUmNvbEf+ynAhim6W98ZW2xvCsdFISc2TYP4ZvCVdie3eaZdum2kieVcvpNHu+UrzAAHA==",
"license": "MIT",
"dependencies": {
"@rc-component/motion": "^1.0.0",
"@rc-component/portal": "^2.1.2",
- "@rc-component/util": "^1.3.0",
+ "@rc-component/util": "^1.10.0",
"clsx": "^2.1.1"
},
"peerDependencies": {
@@ -5303,9 +5309,9 @@
}
},
"node_modules/@rc-component/motion": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@rc-component/motion/-/motion-1.3.1.tgz",
- "integrity": "sha512-Wo1mkd0tCcHtvYvpPOmlYJz546z16qlsiwaygmW7NPJpOZOF9GBjhGzdzZSsC2lEJ1IUkWLF4gMHlRA1aSA+Yw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/motion/-/motion-1.3.2.tgz",
+ "integrity": "sha512-itfd+GztzJYAb04Z4RkEub1TbJAfZc2Iuy8p44U44xD1F5+fNYFKI3897ijlbIyfvXkTmMm+KGcjkQQGMHywEQ==",
"license": "MIT",
"dependencies": {
"@rc-component/util": "^1.2.0",
@@ -5555,9 +5561,9 @@
}
},
"node_modules/@rc-component/resize-observer": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@rc-component/resize-observer/-/resize-observer-1.1.1.tgz",
- "integrity": "sha512-NfXXMmiR+SmUuKE1NwJESzEUYUFWIDUn2uXpxCTOLwiRUUakd62DRNFjRJArgzyFW8S5rsL4aX5XlyIXyC/vRA==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@rc-component/resize-observer/-/resize-observer-1.1.2.tgz",
+ "integrity": "sha512-t/Bb0W8uvL4PYKAB3YcChC+DlHh0Wt5kM7q/J+0qpVEUMLe7Hk5zuvc9km0hMnTFPSx5Z7Wu/fzCLN6erVLE8Q==",
"license": "MIT",
"dependencies": {
"@rc-component/util": "^1.2.0"
@@ -5938,9 +5944,9 @@
}
},
"node_modules/@rc-component/util": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.9.0.tgz",
- "integrity": "sha512-5uW6AfhIigCWeEQDthTozlxiT4Prn6xYQWeO0xokjcaa186OtwPRHBZJ2o0T0FhbjGhZ3vXdbkv0sx3gAYW7Vg==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.10.0.tgz",
+ "integrity": "sha512-aY9GLBuiUdpyfIUpAWSYer4Tu3mVaZCo5A0q9NtXcazT3MRiI3/WNHCR+DUn5VAtR6iRRf0ynCqQUcHli5UdYw==",
"license": "MIT",
"dependencies": {
"is-mobile": "^5.0.0",
@@ -6712,50 +6718,50 @@
]
},
"node_modules/@sentry-internal/browser-utils": {
- "version": "10.45.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.45.0.tgz",
- "integrity": "sha512-ZPZpeIarXKScvquGx2AfNKcYiVNDA4wegMmjyGVsTA2JPmP0TrJoO3UybJS6KGDeee8V3I3EfD/ruauMm7jOFQ==",
+ "version": "10.47.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.47.0.tgz",
+ "integrity": "sha512-bVFRAeJWMBcBCvJKIFCMJ1/yQToL4vPGqfmlnDZeypcxkqUDKQ/Y3ziLHXoDL2sx0lagcgU2vH1QhCQ67Aujjw==",
"license": "MIT",
"dependencies": {
- "@sentry/core": "10.45.0"
+ "@sentry/core": "10.47.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/feedback": {
- "version": "10.45.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.45.0.tgz",
- "integrity": "sha512-vCSurazFVq7RUeYiM5X326jA5gOVrWYD6lYX2fbjBOMcyCEhDnveNxMT62zKkZDyNT/jyD194nz/cjntBUkyWA==",
+ "version": "10.47.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.47.0.tgz",
+ "integrity": "sha512-pdvMmi4dQpX5S/vAAzrhHPIw3T3HjUgDNgUiCBrlp7N9/6zGO2gNPhUnNekP+CjgI/z0rvf49RLqlDenpNrMOg==",
"license": "MIT",
"dependencies": {
- "@sentry/core": "10.45.0"
+ "@sentry/core": "10.47.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay": {
- "version": "10.45.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.45.0.tgz",
- "integrity": "sha512-vjosRoGA1bzhVAEO1oce+CsRdd70quzBeo7WvYqpcUnoLe/Rv8qpOMqWX3j26z7XfFHMExWQNQeLxmtYOArvlw==",
+ "version": "10.47.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.47.0.tgz",
+ "integrity": "sha512-ScdovxP7hJxgMt70+7hFvwT02GIaIUAxdEM/YPsayZBeCoAukPW8WiwztJfoKtsfPyKJ5A6f0H3PIxTPcA9Row==",
"license": "MIT",
"dependencies": {
- "@sentry-internal/browser-utils": "10.45.0",
- "@sentry/core": "10.45.0"
+ "@sentry-internal/browser-utils": "10.47.0",
+ "@sentry/core": "10.47.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
- "version": "10.45.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.45.0.tgz",
- "integrity": "sha512-nvq/AocdZTuD7y0KSiWi3gVaY0s5HOFy86mC/v1kDZmT/jsBAzN5LDkk/f1FvsWma1peqQmpUqxvhC+YIW294Q==",
+ "version": "10.47.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.47.0.tgz",
+ "integrity": "sha512-A5OY8friSe6g8WAK4L8IeOPiEd9D3Ps40DzRH5j2f6SUja0t90mKMvHRcRf8zq0d4BkdB+JM7tjOkwxpuv8heA==",
"license": "MIT",
"dependencies": {
- "@sentry-internal/replay": "10.45.0",
- "@sentry/core": "10.45.0"
+ "@sentry-internal/replay": "10.47.0",
+ "@sentry/core": "10.47.0"
},
"engines": {
"node": ">=18"
@@ -6771,16 +6777,16 @@
}
},
"node_modules/@sentry/browser": {
- "version": "10.45.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.45.0.tgz",
- "integrity": "sha512-e/a8UMiQhqqv706McSIcG6XK+AoQf9INthi2pD+giZfNRTzXTdqHzUT5OIO5hg8Am6eF63nDJc+vrYNPhzs51Q==",
+ "version": "10.47.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.47.0.tgz",
+ "integrity": "sha512-rC0agZdxKA5XWfL4VwPOr/rJMogXDqZgnVzr93YWpFn9DMZT/7LzxSJVPIJwRUjx3bFEby3PcTa3YaX7pxm1AA==",
"license": "MIT",
"dependencies": {
- "@sentry-internal/browser-utils": "10.45.0",
- "@sentry-internal/feedback": "10.45.0",
- "@sentry-internal/replay": "10.45.0",
- "@sentry-internal/replay-canvas": "10.45.0",
- "@sentry/core": "10.45.0"
+ "@sentry-internal/browser-utils": "10.47.0",
+ "@sentry-internal/feedback": "10.47.0",
+ "@sentry-internal/replay": "10.47.0",
+ "@sentry-internal/replay-canvas": "10.47.0",
+ "@sentry/core": "10.47.0"
},
"engines": {
"node": ">=18"
@@ -7004,9 +7010,9 @@
}
},
"node_modules/@sentry/cli": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-3.3.3.tgz",
- "integrity": "sha512-4CZtfgiOraX+BntMjYQhfLDArXwpqt3sEo5Zdj2pqWSZSd4yI3ncfQ21CsxLcI/sUQrjmD5Vzidu4/1OShyxtA==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-3.3.5.tgz",
+ "integrity": "sha512-eyLHTj0rpeCsOUX+1ZU8UEWRXy6nXvTXNdhtAt1t6YXan9gSsAexZf28zVmDcYcP8WRbK0D2JMLp7NcaQCQgEA==",
"hasInstallScript": true,
"license": "FSL-1.1-MIT",
"dependencies": {
@@ -7022,20 +7028,20 @@
"node": ">= 18"
},
"optionalDependencies": {
- "@sentry/cli-darwin": "3.3.3",
- "@sentry/cli-linux-arm": "3.3.3",
- "@sentry/cli-linux-arm64": "3.3.3",
- "@sentry/cli-linux-i686": "3.3.3",
- "@sentry/cli-linux-x64": "3.3.3",
- "@sentry/cli-win32-arm64": "3.3.3",
- "@sentry/cli-win32-i686": "3.3.3",
- "@sentry/cli-win32-x64": "3.3.3"
+ "@sentry/cli-darwin": "3.3.5",
+ "@sentry/cli-linux-arm": "3.3.5",
+ "@sentry/cli-linux-arm64": "3.3.5",
+ "@sentry/cli-linux-i686": "3.3.5",
+ "@sentry/cli-linux-x64": "3.3.5",
+ "@sentry/cli-win32-arm64": "3.3.5",
+ "@sentry/cli-win32-i686": "3.3.5",
+ "@sentry/cli-win32-x64": "3.3.5"
}
},
"node_modules/@sentry/cli-darwin": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-3.3.3.tgz",
- "integrity": "sha512-P8DoL79eX5fhKCfBHHl7xwwTShDPOb2drJC8lizZ3v1iS1JLPrNweM1KEzDefR30zH1wghbLSwsYv/svWdM3wA==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-3.3.5.tgz",
+ "integrity": "sha512-E/SIY6+j2nt6Ri9nMt78sYle3LiF6uZyz4HGmvcEMU6HXjegmAayhy0J10JST+vZTzN6VixD8sUsa5UeJiOPcg==",
"license": "FSL-1.1-MIT",
"optional": true,
"os": [
@@ -7046,9 +7052,9 @@
}
},
"node_modules/@sentry/cli-linux-arm": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-3.3.3.tgz",
- "integrity": "sha512-a7o/huozveLIImXHe0HDwEMVhvDopOP2tLcopvV7sQsVE8f/QOShR5FudKjmiaZz2opdLzPJO9pv5WuF9jAZPg==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-3.3.5.tgz",
+ "integrity": "sha512-EGuEIvC2OQyar/vu+jAQEmovTMgxpoxdx5knnzL5dLhIemjEUNqwv/sXq+m/Aj+ThqCMofcTWB2TOZXsTtl0Tw==",
"cpu": [
"arm"
],
@@ -7064,9 +7070,9 @@
}
},
"node_modules/@sentry/cli-linux-arm64": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-3.3.3.tgz",
- "integrity": "sha512-9jaX9RGyTpjo9u2urNi5ciBDpRdTt107YJpFXev+BFHJ6Lwz/owgRuYzPRfAen8hKkOOFheZ3iy07kl576eZzw==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-3.3.5.tgz",
+ "integrity": "sha512-/W7HTk2OFKD0bguTvQR1ue6pkFQWaGiqPafOSIQKyq0aGfbZhBn/Uj+IRefgMZMhJQ29xRz0y/iGRGKE+ef4Vg==",
"cpu": [
"arm64"
],
@@ -7082,9 +7088,9 @@
}
},
"node_modules/@sentry/cli-linux-i686": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-3.3.3.tgz",
- "integrity": "sha512-VngQYzR2kDm2oojCuYF20ebLTK8HKvEwxe785J6gxob8Ef9JvZkERyUqENYppBa9aVgN0pandqPAqOECWykTMA==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-3.3.5.tgz",
+ "integrity": "sha512-qODMEWLEeUNp3IUlwwISB37EXSo8qgMmHQuLKfxDjpIKw+7NAFfptOloqPrHkLWK3TzFr+Nv643wIKZaYrz28Q==",
"cpu": [
"x86",
"ia32"
@@ -7101,9 +7107,9 @@
}
},
"node_modules/@sentry/cli-linux-x64": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-3.3.3.tgz",
- "integrity": "sha512-rBxXQeIYGefUNI2cXHxEr0y3bhxDQjOD4G6j/gqLz/Dj+l8gJ/iKP64kTudnoViNIpn0pdYccG69th7zmzM/Fg==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-3.3.5.tgz",
+ "integrity": "sha512-DCz7lQ4PySjQ1WvWOQ/uTdwauRo1D7hSHazxZ+fUAnK/epSPM9qLkjDMlD8uM5CaLoR8+ZTs7N94vV5LZs2QpA==",
"cpu": [
"x64"
],
@@ -7119,9 +7125,9 @@
}
},
"node_modules/@sentry/cli-win32-arm64": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-3.3.3.tgz",
- "integrity": "sha512-c52g+YS6BO0rzH8AEHqQPmpqZrw0GJjMWqy0tQ5jcqaGdaLVnxk0mMEubv8R6Dv5MR2LShoKjiNsaeVfrWIMUg==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-3.3.5.tgz",
+ "integrity": "sha512-VMNsHiyZcP8Ft3fcK/1zoO4L66soe1eSfXg2tglFQSc/2MYA5v1Br9B1GtjBwDIc3EmdPtFZhOGLyqIzszMxJw==",
"cpu": [
"arm64"
],
@@ -7135,9 +7141,9 @@
}
},
"node_modules/@sentry/cli-win32-i686": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-3.3.3.tgz",
- "integrity": "sha512-DygYzSY/+tS7oFj/mfeg/yzYxsQx3fO8cI+IWc2pns/at+JcJ9O5xyM/x/q55wOxpnwla7RL1D3rsqK2mqkYfg==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-3.3.5.tgz",
+ "integrity": "sha512-BE6aHOIpsm4jgavsvvXNcSikAr/8NSva3rk1N3BzoOLuX+dcFxBI60K1i2VzB1vsgtivJJo9YySNCi60dBgWTg==",
"cpu": [
"x86",
"ia32"
@@ -7152,9 +7158,9 @@
}
},
"node_modules/@sentry/cli-win32-x64": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-3.3.3.tgz",
- "integrity": "sha512-i0glPcHwkqbVA2Y+0Yz7CD/l8TSkfft1a+lTU9yk/+DDU8WGkyArEAxAji9bGo4p+k5HIFC8OC2MwpKdcdFM4Q==",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-3.3.5.tgz",
+ "integrity": "sha512-MSU+PtBuiLjEbiPFOvxk4CI3TCagwkIg9kvJ+DrI3+pBY0Sga/dOyeWKTIgb01xSVcfjdw0UkpU52VCvzTT9ew==",
"cpu": [
"x64"
],
@@ -7189,22 +7195,22 @@
}
},
"node_modules/@sentry/core": {
- "version": "10.45.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.45.0.tgz",
- "integrity": "sha512-s69UXxvefeQxuZ5nY7/THtTrIEvJxNVCp3ns4kwoCw1qMpgpvn/296WCKVmM7MiwnaAdzEKnAvLAwaxZc2nM7Q==",
+ "version": "10.47.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.47.0.tgz",
+ "integrity": "sha512-nsYRAx3EWezDut+Zl+UwwP07thh9uY7CfSAi2whTdcJl5hu1nSp2z8bba7Vq/MGbNLnazkd3A+GITBEML924JA==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@sentry/react": {
- "version": "10.45.0",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.45.0.tgz",
- "integrity": "sha512-jLezuxi4BUIU3raKyAPR5xMbQG/nhwnWmKo5p11NCbLmWzkS+lxoyDTUB4B8TAKZLfdtdkKLOn1S0tFc8vbUHw==",
+ "version": "10.47.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.47.0.tgz",
+ "integrity": "sha512-ZtJV6xxF8jUVE9e3YQUG3Do0XapG1GjniyLyqMPgN6cNvs/HaRJODf7m60By+VGqcl5XArEjEPTvx8CdPUXDfA==",
"license": "MIT",
"dependencies": {
- "@sentry/browser": "10.45.0",
- "@sentry/core": "10.45.0"
+ "@sentry/browser": "10.47.0",
+ "@sentry/core": "10.47.0"
},
"engines": {
"node": ">=18"
@@ -7751,31 +7757,31 @@
}
},
"node_modules/@vitest/expect": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.0.tgz",
- "integrity": "sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.2.tgz",
+ "integrity": "sha512-gbu+7B0YgUJ2nkdsRJrFFW6X7NTP44WlhiclHniUhxADQJH5Szt9mZ9hWnJPJ8YwOK5zUOSSlSvyzRf0u1DSBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.1.0",
"@types/chai": "^5.2.2",
- "@vitest/spy": "4.1.0",
- "@vitest/utils": "4.1.0",
+ "@vitest/spy": "4.1.2",
+ "@vitest/utils": "4.1.2",
"chai": "^6.2.2",
- "tinyrainbow": "^3.0.3"
+ "tinyrainbow": "^3.1.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/mocker": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.0.tgz",
- "integrity": "sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.2.tgz",
+ "integrity": "sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/spy": "4.1.0",
+ "@vitest/spy": "4.1.2",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.21"
},
@@ -7784,7 +7790,7 @@
},
"peerDependencies": {
"msw": "^2.4.9",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"msw": {
@@ -7816,26 +7822,26 @@
}
},
"node_modules/@vitest/pretty-format": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.0.tgz",
- "integrity": "sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.2.tgz",
+ "integrity": "sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "tinyrainbow": "^3.0.3"
+ "tinyrainbow": "^3.1.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/runner": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.0.tgz",
- "integrity": "sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.2.tgz",
+ "integrity": "sha512-Gr+FQan34CdiYAwpGJmQG8PgkyFVmARK8/xSijia3eTFgVfpcpztWLuP6FttGNfPLJhaZVP/euvujeNYar36OQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/utils": "4.1.0",
+ "@vitest/utils": "4.1.2",
"pathe": "^2.0.3"
},
"funding": {
@@ -7850,14 +7856,14 @@
"license": "MIT"
},
"node_modules/@vitest/snapshot": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.0.tgz",
- "integrity": "sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.2.tgz",
+ "integrity": "sha512-g7yfUmxYS4mNxk31qbOYsSt2F4m1E02LFqO53Xpzg3zKMhLAPZAjjfyl9e6z7HrW6LvUdTwAQR3HHfLjpko16A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.0",
- "@vitest/utils": "4.1.0",
+ "@vitest/pretty-format": "4.1.2",
+ "@vitest/utils": "4.1.2",
"magic-string": "^0.30.21",
"pathe": "^2.0.3"
},
@@ -7883,9 +7889,9 @@
"license": "MIT"
},
"node_modules/@vitest/spy": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.0.tgz",
- "integrity": "sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.2.tgz",
+ "integrity": "sha512-DU4fBnbVCJGNBwVA6xSToNXrkZNSiw59H8tcuUspVMsBDBST4nfvsPsEHDHGtWRRnqBERBQu7TrTKskmjqTXKA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -7893,15 +7899,15 @@
}
},
"node_modules/@vitest/utils": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.0.tgz",
- "integrity": "sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.2.tgz",
+ "integrity": "sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.0",
+ "@vitest/pretty-format": "4.1.2",
"convert-source-map": "^2.0.0",
- "tinyrainbow": "^3.0.3"
+ "tinyrainbow": "^3.1.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
@@ -8036,16 +8042,16 @@
}
},
"node_modules/antd": {
- "version": "6.3.3",
- "resolved": "https://registry.npmjs.org/antd/-/antd-6.3.3.tgz",
- "integrity": "sha512-T8FAQelw36zS96cZw2U/qEjpYny5yFc7hg+1W7DvVr8xMoSXWvyB8WvmiDVH0nS0LPYV4y2sxetsJoGZt7rhhw==",
+ "version": "6.3.5",
+ "resolved": "https://registry.npmjs.org/antd/-/antd-6.3.5.tgz",
+ "integrity": "sha512-8BPz9lpZWQm42PTx7yL4KxWAotVuqINiKcoYRcLtdd5BFmAcAZicVyFTnBJyRDlzGZFZeRW3foGu6jXYFnej6Q==",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^8.0.1",
"@ant-design/cssinjs": "^2.1.2",
"@ant-design/cssinjs-utils": "^2.1.2",
"@ant-design/fast-color": "^3.0.1",
- "@ant-design/icons": "^6.1.0",
+ "@ant-design/icons": "^6.1.1",
"@ant-design/react-slick": "~2.0.0",
"@babel/runtime": "^7.28.4",
"@rc-component/cascader": "~1.14.0",
@@ -8055,13 +8061,13 @@
"@rc-component/dialog": "~1.8.4",
"@rc-component/drawer": "~1.4.2",
"@rc-component/dropdown": "~1.0.2",
- "@rc-component/form": "~1.7.2",
- "@rc-component/image": "~1.6.0",
+ "@rc-component/form": "~1.8.0",
+ "@rc-component/image": "~1.8.0",
"@rc-component/input": "~1.1.2",
"@rc-component/input-number": "~1.6.2",
"@rc-component/mentions": "~1.6.0",
"@rc-component/menu": "~1.2.0",
- "@rc-component/motion": "^1.3.1",
+ "@rc-component/motion": "^1.3.2",
"@rc-component/mutate-observer": "^2.0.1",
"@rc-component/notification": "~1.2.0",
"@rc-component/pagination": "~1.2.0",
@@ -8069,9 +8075,9 @@
"@rc-component/progress": "~1.0.2",
"@rc-component/qrcode": "~1.1.1",
"@rc-component/rate": "~1.0.1",
- "@rc-component/resize-observer": "^1.1.1",
+ "@rc-component/resize-observer": "^1.1.2",
"@rc-component/segmented": "~1.3.0",
- "@rc-component/select": "~1.6.14",
+ "@rc-component/select": "~1.6.15",
"@rc-component/slider": "~1.0.1",
"@rc-component/steps": "~1.2.2",
"@rc-component/switch": "~1.0.3",
@@ -8084,7 +8090,7 @@
"@rc-component/tree-select": "~1.8.0",
"@rc-component/trigger": "^3.9.0",
"@rc-component/upload": "~1.1.0",
- "@rc-component/util": "^1.9.0",
+ "@rc-component/util": "^1.10.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.11",
"scroll-into-view-if-needed": "^3.1.0",
@@ -8420,14 +8426,23 @@
}
},
"node_modules/axios": {
- "version": "1.13.6",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz",
- "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz",
+ "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
- "proxy-from-env": "^1.1.0"
+ "proxy-from-env": "^2.1.0"
+ }
+ },
+ "node_modules/axios/node_modules/proxy-from-env": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
+ "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/babel-plugin-macros": {
@@ -8545,12 +8560,15 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
- "version": "2.9.12",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.12.tgz",
- "integrity": "sha512-Mij6Lij93pTAIsSYy5cyBQ975Qh9uLEc5rwGTpomiZeXZL9yIS6uORJakb3ScHgfs0serMMfIbXzokPMuEiRyw==",
+ "version": "2.10.12",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz",
+ "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==",
"license": "Apache-2.0",
"bin": {
- "baseline-browser-mapping": "dist/cli.js"
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
}
},
"node_modules/bidi-js": {
@@ -8782,9 +8800,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.28.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
- "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "version": "4.28.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
+ "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
"funding": [
{
"type": "opencollective",
@@ -8801,11 +8819,11 @@
],
"license": "MIT",
"dependencies": {
- "baseline-browser-mapping": "^2.9.0",
- "caniuse-lite": "^1.0.30001759",
- "electron-to-chromium": "^1.5.263",
- "node-releases": "^2.0.27",
- "update-browserslist-db": "^1.2.0"
+ "baseline-browser-mapping": "^2.10.12",
+ "caniuse-lite": "^1.0.30001782",
+ "electron-to-chromium": "^1.5.328",
+ "node-releases": "^2.0.36",
+ "update-browserslist-db": "^1.2.3"
},
"bin": {
"browserslist": "cli.js"
@@ -8972,9 +8990,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001762",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
- "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==",
+ "version": "1.0.30001782",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz",
+ "integrity": "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==",
"funding": [
{
"type": "opencollective",
@@ -9738,12 +9756,12 @@
"license": "MIT"
},
"node_modules/dayjs-business-days2": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/dayjs-business-days2/-/dayjs-business-days2-1.3.2.tgz",
- "integrity": "sha512-UDJcMw5tM6hoIu8QgP4ASKuVPrnFqB8WMbtfmLe2WNMX/n6zmXfPKwULJS2CKpS+N/+Jdq5Vmo8dkke0sIaV1A==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/dayjs-business-days2/-/dayjs-business-days2-1.3.3.tgz",
+ "integrity": "sha512-ogedXtGep3W1rl/rhzrSbZU7cOA7Cr3s9HY7iiXDqkDv/LarERc1AEI3kvQ+sF43K1HLoXfByu2XQvU7jfqF9w==",
"license": "MIT",
"dependencies": {
- "dayjs": "^1.11.19"
+ "dayjs": "^1.11.20"
}
},
"node_modules/debug": {
@@ -10088,9 +10106,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.267",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
- "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
+ "version": "1.5.329",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.329.tgz",
+ "integrity": "sha512-/4t+AS1l4S3ZC0Ja7PHFIWeBIxGA3QGqV8/yKsP36v7NcyUCl+bIcmw6s5zVuMIECWwBrAK/6QLzTmbJChBboQ==",
"license": "ISC"
},
"node_modules/elliptic": {
@@ -11411,9 +11429,9 @@
"license": "ISC"
},
"node_modules/graphql": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.1.tgz",
- "integrity": "sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==",
+ "version": "16.13.2",
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz",
+ "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==",
"license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
@@ -11435,9 +11453,9 @@
}
},
"node_modules/graphql-ws": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-6.0.7.tgz",
- "integrity": "sha512-yoLRW+KRlDmnnROdAu7sX77VNLC0bsFoZyGQJLy1cF+X/SkLg/fWkRGrEEYQK8o2cafJ2wmEaMqMEZB3U3DYDg==",
+ "version": "6.0.8",
+ "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-6.0.8.tgz",
+ "integrity": "sha512-m3EOaNsUBXwAnkBWbzPfe0Nq8pXUfxsWnolC54sru3FzHvhTZL0Ouf/BoQsaGAXqM+YPerXOJ47BUnmgmoupCw==",
"license": "MIT",
"engines": {
"node": ">=20"
@@ -11784,9 +11802,9 @@
}
},
"node_modules/i18next": {
- "version": "25.10.5",
- "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.10.5.tgz",
- "integrity": "sha512-jRnF7eRNsdcnh7AASSgaU3lj/8lJZuHkfsouetnLEDH0xxE1vVi7qhiJ9RhdSPUyzg4ltb7P7aXsFlTk9sxL2w==",
+ "version": "25.10.10",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.10.10.tgz",
+ "integrity": "sha512-cqUW2Z3EkRx7NqSyywjkgCLK7KLCL6IFVFcONG7nVYIJ3ekZ1/N5jUsihHV6Bq37NfhgtczxJcxduELtjTwkuQ==",
"funding": [
{
"type": "individual",
@@ -11806,7 +11824,7 @@
"@babel/runtime": "^7.29.2"
},
"peerDependencies": {
- "typescript": "^5"
+ "typescript": "^5 || ^6"
},
"peerDependenciesMeta": {
"typescript": {
@@ -12927,9 +12945,9 @@
}
},
"node_modules/libphonenumber-js": {
- "version": "1.12.40",
- "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.40.tgz",
- "integrity": "sha512-HKGs7GowShNls3Zh+7DTr6wYpPk5jC78l508yQQY3e8ZgJChM3A9JZghmMJZuK+5bogSfuTafpjksGSR3aMIEg==",
+ "version": "1.12.41",
+ "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.41.tgz",
+ "integrity": "sha512-lsmMmGXBxXIK/VMLEj0kL6MtUs1kBGj1nTCzi6zgQoG1DEwqwt2DQyHxcLykceIxAnfE3hya7NuIh6PpC6S3fA==",
"license": "MIT"
},
"node_modules/lightningcss": {
@@ -14310,9 +14328,9 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.27",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
- "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "version": "2.0.36",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz",
+ "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==",
"license": "MIT"
},
"node_modules/node-stdlib-browser": {
@@ -15070,9 +15088,9 @@
"license": "MIT"
},
"node_modules/posthog-js": {
- "version": "1.363.2",
- "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.363.2.tgz",
- "integrity": "sha512-4ZEWMrymlFzjgDSmh25VeJQT//2XUFbfKqEPDNUW4dxcqWiVMo1+gJFy5YhJgVYS46OAXLbMcJgmuZBCnDIgVg==",
+ "version": "1.364.4",
+ "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.364.4.tgz",
+ "integrity": "sha512-T71zr06gH5YcrjS7c+sdzqfZKMxqqXC/a0w++zMQIPbL1ejvF9PdfUi0Kyd6Sy78Ocbb2smobdzBh8vXLwC+lQ==",
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
"@opentelemetry/api": "^1.9.0",
@@ -15080,8 +15098,8 @@
"@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
"@opentelemetry/resources": "^2.2.0",
"@opentelemetry/sdk-logs": "^0.208.0",
- "@posthog/core": "1.24.1",
- "@posthog/types": "1.363.2",
+ "@posthog/core": "1.24.4",
+ "@posthog/types": "1.364.4",
"core-js": "^3.38.1",
"dompurify": "^3.3.2",
"fflate": "^0.4.8",
@@ -15447,12 +15465,12 @@
}
},
"node_modules/react-cookie": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-8.0.1.tgz",
- "integrity": "sha512-QNdAd0MLuAiDiLcDU/2s/eyKmmfMHtjPUKJ2dZ/5CcQ9QKUium4B3o61/haq6PQl/YWFqC5PO8GvxeHKhy3GFA==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-8.1.0.tgz",
+ "integrity": "sha512-Qs+gD3gpQmUXnJUZafhJtNWhhNdi8OYbOAF5YQRAZa/D171ILOIEMfXDz/tmhkE+nOthllmqryHH6I/qmvIYWQ==",
"license": "MIT",
"dependencies": {
- "@types/hoist-non-react-statics": "^3.3.6",
+ "@types/hoist-non-react-statics": "^3.3.7",
"hoist-non-react-statics": "^3.3.2",
"universal-cookie": "^8.0.0"
},
@@ -15512,16 +15530,16 @@
}
},
"node_modules/react-grid-layout": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-2.2.2.tgz",
- "integrity": "sha512-yNo9pxQWoxHWRAwHGSVT4DEGELYPyQ7+q9lFclb5jcqeFzva63/2F72CryS/jiTIr/SBIlTaDdyjqH+ODg8oBw==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-2.2.3.tgz",
+ "integrity": "sha512-OAEJHBxmfuxQfVtZwRzmsokijGlBgzYIJ7MUlLk/VSa43SaGzu15w5D0P2RDrfX5EvP9POMbL6bFrai/huDzbQ==",
"license": "MIT",
"dependencies": {
"clsx": "^2.1.1",
"fast-equals": "^4.0.3",
"prop-types": "^15.8.1",
"react-draggable": "^4.4.6",
- "react-resizable": "^3.0.5",
+ "react-resizable": "^3.1.3",
"resize-observer-polyfill": "^1.5.1"
},
"peerDependencies": {
@@ -15545,9 +15563,9 @@
"license": "MIT"
},
"node_modules/react-i18next": {
- "version": "16.6.2",
- "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.6.2.tgz",
- "integrity": "sha512-/S/GPzElTqEi5o2kzd0/O2627hPDmE6OGhJCCwCfUaQ3syyu+kaYH8/PYFtZeWc25NzfxTN/2fD1QjvrTgrFfA==",
+ "version": "16.6.6",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.6.6.tgz",
+ "integrity": "sha512-ZgL2HUoW34UKUkOV7uSQFE1CDnRPD+tCR3ywSuWH7u2iapnz86U8Bi3Vrs620qNDzCf1F47NxglCEkchCTDOHw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.29.2",
@@ -15555,9 +15573,9 @@
"use-sync-external-store": "^1.6.0"
},
"peerDependencies": {
- "i18next": ">= 25.6.2",
+ "i18next": ">= 25.10.9",
"react": ">= 16.8.0",
- "typescript": "^5"
+ "typescript": "^5 || ^6"
},
"peerDependenciesMeta": {
"react-dom": {
@@ -15858,9 +15876,9 @@
}
},
"node_modules/recharts": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.8.0.tgz",
- "integrity": "sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.8.1.tgz",
+ "integrity": "sha512-mwzmO1s9sFL0TduUpwndxCUNoXsBw3u3E/0+A+cLcrSfQitSG62L32N69GhqUrrT5qKcAE3pCGVINC6pqkBBQg==",
"license": "MIT",
"workspaces": [
"www"
@@ -18507,9 +18525,9 @@
}
},
"node_modules/vite-plugin-node-polyfills": {
- "version": "0.25.0",
- "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.25.0.tgz",
- "integrity": "sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg==",
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.26.0.tgz",
+ "integrity": "sha512-BAe5YzJf368XGev02hDvioidx4uVH8dqEJlG73bjQSxM26/AQnGcKFomq9n3vGq5yqpSHKN4h1XQNxx9l98mBg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -18520,7 +18538,7 @@
"url": "https://github.com/sponsors/davidmyersdev"
},
"peerDependencies": {
- "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/vite-plugin-pwa": {
@@ -18613,19 +18631,19 @@
}
},
"node_modules/vitest": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.0.tgz",
- "integrity": "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.2.tgz",
+ "integrity": "sha512-xjR1dMTVHlFLh98JE3i/f/WePqJsah4A0FK9cc8Ehp9Udk0AZk6ccpIZhh1qJ/yxVWRZ+Q54ocnD8TXmkhspGg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/expect": "4.1.0",
- "@vitest/mocker": "4.1.0",
- "@vitest/pretty-format": "4.1.0",
- "@vitest/runner": "4.1.0",
- "@vitest/snapshot": "4.1.0",
- "@vitest/spy": "4.1.0",
- "@vitest/utils": "4.1.0",
+ "@vitest/expect": "4.1.2",
+ "@vitest/mocker": "4.1.2",
+ "@vitest/pretty-format": "4.1.2",
+ "@vitest/runner": "4.1.2",
+ "@vitest/snapshot": "4.1.2",
+ "@vitest/spy": "4.1.2",
+ "@vitest/utils": "4.1.2",
"es-module-lexer": "^2.0.0",
"expect-type": "^1.3.0",
"magic-string": "^0.30.21",
@@ -18636,8 +18654,8 @@
"tinybench": "^2.9.0",
"tinyexec": "^1.0.2",
"tinyglobby": "^0.2.15",
- "tinyrainbow": "^3.0.3",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0",
+ "tinyrainbow": "^3.1.0",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
"why-is-node-running": "^2.3.0"
},
"bin": {
@@ -18653,13 +18671,13 @@
"@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
- "@vitest/browser-playwright": "4.1.0",
- "@vitest/browser-preview": "4.1.0",
- "@vitest/browser-webdriverio": "4.1.0",
- "@vitest/ui": "4.1.0",
+ "@vitest/browser-playwright": "4.1.2",
+ "@vitest/browser-preview": "4.1.2",
+ "@vitest/browser-webdriverio": "4.1.2",
+ "@vitest/ui": "4.1.2",
"happy-dom": "*",
"jsdom": "*",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"@edge-runtime/vm": {
@@ -18757,9 +18775,9 @@
}
},
"node_modules/web-vitals": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-5.1.0.tgz",
- "integrity": "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-5.2.0.tgz",
+ "integrity": "sha512-i2z98bEmaCqSDiHEDu+gHl/dmR4Q+TxFmG3/13KkMO+o8UxQzCqWaDRCiLgEa41nlO4VpXSI0ASa1xWmO9sBlA==",
"license": "Apache-2.0"
},
"node_modules/webidl-conversions": {
diff --git a/client/package.json b/client/package.json
index 4f03ad75d..7e95380a6 100644
--- a/client/package.json
+++ b/client/package.json
@@ -8,7 +8,7 @@
"private": true,
"proxy": "http://localhost:4000",
"dependencies": {
- "@amplitude/analytics-browser": "^2.37.0",
+ "@amplitude/analytics-browser": "^2.38.0",
"@ant-design/pro-layout": "^7.22.6",
"@apollo/client": "^4.1.6",
"@dnd-kit/core": "^6.3.1",
@@ -24,29 +24,29 @@
"@firebase/messaging": "^0.12.25",
"@jsreport/browser-client": "^3.1.0",
"@reduxjs/toolkit": "^2.11.2",
- "@sentry/cli": "^3.3.3",
- "@sentry/react": "^10.45.0",
+ "@sentry/cli": "^3.3.5",
+ "@sentry/react": "^10.47.0",
"@sentry/vite-plugin": "^4.9.1",
"@splitsoftware/splitio-react": "^2.6.1",
"@tanem/react-nprogress": "^5.0.63",
- "antd": "^6.3.3",
+ "antd": "^6.3.5",
"apollo-link-logger": "^3.0.0",
"autosize": "^6.0.1",
- "axios": "^1.13.6",
+ "axios": "^1.14.0",
"classnames": "^2.5.1",
"css-box-model": "^1.2.1",
"dayjs": "^1.11.20",
- "dayjs-business-days2": "^1.3.2",
+ "dayjs-business-days2": "^1.3.3",
"dinero.js": "^1.9.1",
"dotenv": "^17.3.1",
"env-cmd": "^11.0.0",
"exifr": "^7.1.3",
- "graphql": "^16.13.1",
- "graphql-ws": "^6.0.7",
- "i18next": "^25.10.5",
+ "graphql": "^16.13.2",
+ "graphql-ws": "^6.0.8",
+ "i18next": "^25.10.10",
"i18next-browser-languagedetector": "^8.2.1",
"immutability-helper": "^3.1.1",
- "libphonenumber-js": "^1.12.40",
+ "libphonenumber-js": "^1.12.41",
"lightningcss": "^1.32.0",
"logrocket": "^12.1.0",
"markerjs2": "^2.32.7",
@@ -54,18 +54,18 @@
"normalize-url": "^8.1.1",
"object-hash": "^3.0.0",
"phone": "^3.1.71",
- "posthog-js": "^1.363.2",
+ "posthog-js": "^1.364.4",
"prop-types": "^15.8.1",
"query-string": "^9.3.1",
"raf-schd": "^4.0.3",
"react": "^19.2.4",
"react-big-calendar": "^1.19.4",
"react-color": "^2.19.3",
- "react-cookie": "^8.0.1",
+ "react-cookie": "^8.1.0",
"react-dom": "^19.2.4",
"react-grid-gallery": "^1.0.1",
- "react-grid-layout": "^2.2.2",
- "react-i18next": "^16.6.2",
+ "react-grid-layout": "^2.2.3",
+ "react-i18next": "^16.6.6",
"react-icons": "^5.6.0",
"react-image-lightbox": "^5.1.4",
"react-markdown": "^10.1.0",
@@ -77,7 +77,7 @@
"react-router-dom": "^7.13.2",
"react-sticky": "^6.0.3",
"react-virtuoso": "^4.18.3",
- "recharts": "^3.8.0",
+ "recharts": "^3.8.1",
"redux": "^5.0.1",
"redux-actions": "^3.0.3",
"redux-persist": "^6.0.0",
@@ -89,7 +89,7 @@
"socket.io-client": "^4.8.3",
"styled-components": "^6.3.12",
"vite-plugin-ejs": "^1.7.0",
- "web-vitals": "^5.1.0"
+ "web-vitals": "^5.2.0"
},
"scripts": {
"postinstall": "echo 'when updating react-big-calendar, remember to check to localizer in the calendar wrapper'",
@@ -137,10 +137,10 @@
"@rollup/rollup-linux-x64-gnu": "4.6.1"
},
"devDependencies": {
- "@ant-design/icons": "^6.1.0",
+ "@ant-design/icons": "^6.1.1",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-react": "^7.28.5",
- "@dotenvx/dotenvx": "^1.57.2",
+ "@dotenvx/dotenvx": "^1.59.1",
"@emotion/babel-plugin": "^11.13.5",
"@emotion/react": "^11.14.0",
"@eslint/js": "^9.39.2",
@@ -150,7 +150,7 @@
"@testing-library/react": "^16.3.2",
"@vitejs/plugin-react": "^5.1.4",
"babel-plugin-react-compiler": "^1.0.0",
- "browserslist": "^4.28.1",
+ "browserslist": "^4.28.2",
"browserslist-to-esbuild": "^2.1.1",
"chalk": "^5.6.2",
"eslint": "^9.39.2",
@@ -167,10 +167,10 @@
"vite": "^7.3.1",
"vite-plugin-babel": "^1.6.0",
"vite-plugin-eslint": "^1.8.1",
- "vite-plugin-node-polyfills": "^0.25.0",
+ "vite-plugin-node-polyfills": "^0.26.0",
"vite-plugin-pwa": "^1.2.0",
"vite-plugin-style-import": "^2.0.0",
- "vitest": "^4.1.0",
+ "vitest": "^4.1.2",
"workbox-window": "^7.4.0"
}
}
diff --git a/client/src/components/alert/alert.component.jsx b/client/src/components/alert/alert.component.jsx
index 439822f68..f57dcb5fd 100644
--- a/client/src/components/alert/alert.component.jsx
+++ b/client/src/components/alert/alert.component.jsx
@@ -1,5 +1,5 @@
import { Alert } from "antd";
-export default function AlertComponent(props) {
- return ;
+export default function AlertComponent({ title, message, ...props }) {
+ return ;
}
diff --git a/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx b/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx
index 0f265d7db..69c5a1831 100644
--- a/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx
+++ b/client/src/components/form-fields-changed-alert/form-fields-changed-alert.component.jsx
@@ -4,20 +4,203 @@ import AlertComponent from "../alert/alert.component";
import "./form-fields-changed.styles.scss";
import Prompt from "../../utils/prompt";
-export default function FormsFieldChanged({ form, skipPrompt }) {
+export default function FormsFieldChanged({ form, skipPrompt, onErrorNavigate, onReset, onDirtyChange }) {
const { t } = useTranslation();
+ const normalizeNamePath = (namePath) => (Array.isArray(namePath) ? namePath.filter((part) => part !== undefined) : [namePath]);
+
+ const getFieldIdCandidates = (namePath) => {
+ const normalizedNamePath = normalizeNamePath(namePath).map((part) => String(part));
+ const underscoreId = normalizedNamePath.join("_");
+ const dashId = normalizedNamePath.join("-");
+ const dotName = normalizedNamePath.join(".");
+
+ return [underscoreId, dashId, dotName].filter(Boolean);
+ };
+
+ const clearFormMeta = () => {
+ const fieldMeta = form.getFieldsError().map(({ name }) => ({
+ name,
+ touched: false,
+ validating: false,
+ errors: [],
+ warnings: []
+ }));
+
+ if (fieldMeta.length > 0) {
+ form.setFields(fieldMeta);
+ }
+
+ onDirtyChange?.(false);
+ };
+
const handleReset = () => {
- form.resetFields();
+ if (onReset) {
+ onReset();
+ } else {
+ form.resetFields();
+ }
+
+ window.requestAnimationFrame(() => {
+ clearFormMeta();
+ });
+ };
+
+ const getFieldDomNode = (namePath) => {
+ const fieldInstance = form.getFieldInstance?.(namePath);
+ const fieldIdCandidates = getFieldIdCandidates(namePath);
+ const domCandidates = [
+ fieldInstance?.nativeElement,
+ fieldInstance?.input,
+ fieldInstance?.resizableTextArea?.textArea,
+ fieldInstance
+ ];
+
+ fieldIdCandidates.forEach((fieldId) => {
+ const escapedFieldId = CSS.escape(fieldId);
+ const directNode = document.getElementById(fieldId) || document.querySelector(`#${escapedFieldId}`);
+ const labelNode = document.querySelector(`label[for="${escapedFieldId}"]`);
+ const namedNode = document.querySelector(`[name="${escapedFieldId}"]`);
+ const formItemNode =
+ directNode?.closest?.(".ant-form-item") ||
+ labelNode?.closest?.(".ant-form-item") ||
+ namedNode?.closest?.(".ant-form-item");
+
+ domCandidates.push(directNode);
+ domCandidates.push(namedNode);
+ domCandidates.push(formItemNode);
+ domCandidates.push(formItemNode?.querySelector?.("input, textarea, select, .ant-select-selector"));
+ });
+
+ return domCandidates.find((candidate) => candidate instanceof HTMLElement) ?? null;
+ };
+
+ const waitForAnimationFrames = (frameCount = 1) =>
+ new Promise((resolve) => {
+ let remainingFrames = frameCount;
+ const nextFrame = () => {
+ if (remainingFrames <= 0) {
+ resolve();
+ return;
+ }
+ remainingFrames -= 1;
+ window.requestAnimationFrame(nextFrame);
+ };
+ window.requestAnimationFrame(nextFrame);
+ });
+
+ const getFieldOwningTabMeta = (namePath) => {
+ const fieldDomNode = getFieldDomNode(namePath);
+ const owningTabPane = fieldDomNode?.closest?.(".ant-tabs-tabpane");
+ const paneId = owningTabPane?.getAttribute?.("id") || null;
+ const owningTabButton = paneId
+ ? document.querySelector(`[role="tab"][aria-controls="${paneId.replace(/"/g, '\\"')}"]`)
+ : null;
+ const tabLabel = owningTabButton?.textContent?.trim() || null;
+
+ return {
+ owningTabPane,
+ owningTabButton,
+ tabLabel
+ };
+ };
+
+ const openFieldOwningTab = async (namePath) => {
+ const { owningTabPane, owningTabButton } = getFieldOwningTabMeta(namePath);
+ if (!owningTabPane || owningTabPane.classList.contains("ant-tabs-tabpane-active")) return false;
+
+ if (!(owningTabButton instanceof HTMLElement)) return false;
+
+ owningTabButton.click();
+
+ for (let index = 0; index < 24; index += 1) {
+ await waitForAnimationFrames();
+ if (owningTabPane.classList.contains("ant-tabs-tabpane-active")) return true;
+ }
+
+ return owningTabPane.classList.contains("ant-tabs-tabpane-active");
+ };
+
+ const scrollToErrorField = (namePath) => {
+ const normalizedNamePath = normalizeNamePath(namePath);
+ if (!normalizedNamePath.length) return;
+
+ try {
+ form.scrollToField(normalizedNamePath, {
+ behavior: "smooth",
+ block: "center",
+ focus: true
+ });
+ window.requestAnimationFrame(() => {
+ const fallbackNode = getFieldDomNode(normalizedNamePath);
+ fallbackNode?.focus?.();
+ });
+ return;
+ } catch {
+ const fallbackTarget = document.getElementById(normalizedNamePath[0]?.toString?.() ?? "");
+ fallbackTarget?.scrollIntoView({
+ behavior: "smooth",
+ block: "center"
+ });
+ }
+ };
+
+ const handleErrorClick = async (namePath) => {
+ const normalizedNamePath = normalizeNamePath(namePath);
+ if (!normalizedNamePath.length) return;
+
+ const switchedTab = await openFieldOwningTab(normalizedNamePath);
+ if (!switchedTab) {
+ const navigationDelayMs = onErrorNavigate?.(normalizedNamePath) ?? 0;
+ if (navigationDelayMs > 0) {
+ window.setTimeout(() => {
+ window.requestAnimationFrame(() => {
+ scrollToErrorField(normalizedNamePath);
+ });
+ }, navigationDelayMs);
+ return;
+ }
+ }
+
+ await waitForAnimationFrames(switchedTab ? 2 : 1);
+ scrollToErrorField(normalizedNamePath);
};
//if (!form.isFieldsTouched()) return <>>;
return (
{() => {
- const errors = form.getFieldsError().filter((e) => e.errors.length > 0);
+ const errors = form
+ .getFieldsError()
+ .filter((fieldError) => fieldError.errors.length > 0)
+ .flatMap((fieldError) => {
+ const tabMeta = getFieldOwningTabMeta(fieldError.name);
+
+ return fieldError.errors.map((errorMessage, errorIndex) => ({
+ key: `${(fieldError.name || []).join(".")}-${errorIndex}-${errorMessage}`,
+ message: errorMessage,
+ namePath: fieldError.name,
+ tabLabel: tabMeta.tabLabel
+ }));
+ });
+
+ const groupedErrors = errors.reduce((groups, error) => {
+ const groupKey = error.tabLabel || "__ungrouped__";
+ if (!groups[groupKey]) {
+ groups[groupKey] = {
+ key: groupKey,
+ label: error.tabLabel,
+ errors: []
+ };
+ }
+ groups[groupKey].errors.push(error);
+ return groups;
+ }, {});
+ const errorGroups = Object.values(groupedErrors);
+ const hasTabbedErrorGroups = errorGroups.some((group) => Boolean(group.label));
+
if (form.isFieldsTouched())
return (
-
+
0 && (
- {errors.map((e, idx) => e.errors.map((e2, idx2) => - {e2}
))}
+
+ {errorGroups.map((group) => (
+
+ {hasTabbedErrorGroups && group.label ? (
+
{group.label}
+ ) : null}
+
+ {group.errors.map((error) => (
+ -
+ {Array.isArray(error.namePath) && error.namePath.length > 0 ? (
+
+ ) : (
+ error.message
+ )}
+
+ ))}
+
+
+ ))}
}
showIcon
diff --git a/client/src/components/form-fields-changed-alert/form-fields-changed.styles.scss b/client/src/components/form-fields-changed-alert/form-fields-changed.styles.scss
index 155407907..cb3e3940f 100644
--- a/client/src/components/form-fields-changed-alert/form-fields-changed.styles.scss
+++ b/client/src/components/form-fields-changed-alert/form-fields-changed.styles.scss
@@ -4,4 +4,47 @@
min-height: unset !important;
}
}
+
+ &__error-list {
+ margin: 0;
+ padding-left: 18px;
+ }
+
+ &__error-groups {
+ display: grid;
+ gap: 10px;
+ }
+
+ &__error-group {
+ display: grid;
+ gap: 4px;
+ }
+
+ &__error-group-title {
+ font-weight: 600;
+ }
+
+ &__error-link {
+ display: inline;
+ padding: 0;
+ border: 0;
+ background: none;
+ color: inherit;
+ font: inherit;
+ line-height: inherit;
+ text-align: left;
+ cursor: pointer;
+ text-decoration: underline;
+ text-underline-offset: 2px;
+
+ &:hover {
+ color: color-mix(in srgb, var(--ant-color-error) 82%, var(--ant-color-text));
+ }
+
+ &:focus-visible {
+ outline: 2px solid color-mix(in srgb, var(--ant-color-error) 32%, transparent);
+ outline-offset: 2px;
+ border-radius: 4px;
+ }
+ }
}
diff --git a/client/src/components/form-items-formatted/phone-form-item.component.jsx b/client/src/components/form-items-formatted/phone-form-item.component.jsx
index ede4ec66c..cdf3f4fde 100644
--- a/client/src/components/form-items-formatted/phone-form-item.component.jsx
+++ b/client/src/components/form-items-formatted/phone-form-item.component.jsx
@@ -1,11 +1,88 @@
-import { Input } from "antd";
+import { PhoneFilled } from "@ant-design/icons";
+import { Button, Input, Space } from "antd";
import i18n from "i18next";
import parsePhoneNumber from "libphonenumber-js";
+import { forwardRef, useMemo, useState } from "react";
import "./phone-form-item.styles.scss";
-function FormItemPhone({ ref, ...props }) {
- return ;
-}
+/**
+ * Formats a phone number for display purposes. If the input value is a valid phone number, it will be formatted in a
+ * national format (e.g., (123) 456-7890 for US/CA). If the input is not a valid phone number, it will be returned as-is.
+ * @param value
+ * @returns {*}
+ */
+const formatPhoneDisplayValue = (value) => {
+ if (!value) return value;
+
+ try {
+ const parsedPhone = parsePhoneNumber(value, "CA");
+ return parsedPhone?.isValid() ? parsedPhone.formatNational() : value;
+ } catch {
+ return value;
+ }
+};
+
+/**
+ * Generates a "tel:" URL for a phone number if it's valid. If the input value is a valid phone number, it will return a
+ * URL in the format "tel:+1234567890". If the input is not a valid phone number, it will attempt to trim whitespace and
+ * return a "tel:" URL with the raw value, or null if the trimmed value is empty.
+ * @param value
+ * @returns {string|null}
+ */
+const getPhoneActionHref = (value) => {
+ if (!value) return null;
+
+ try {
+ const parsedPhone = parsePhoneNumber(value, "CA");
+ if (parsedPhone?.isValid()) return `tel:${parsedPhone.number}`;
+ } catch {
+ // Fall back to the raw value below.
+ }
+
+ const trimmedValue = String(value).trim();
+ return trimmedValue ? `tel:${trimmedValue}` : null;
+};
+
+const FormItemPhone = forwardRef(function FormItemPhone(
+ { formatDisplayOnly = false, showPhoneAction = false, value, onBlur, onFocus, ...props },
+ ref
+) {
+ const [isFocused, setIsFocused] = useState(false);
+ const displayValue = useMemo(() => {
+ if (!formatDisplayOnly || isFocused) return value;
+ return formatPhoneDisplayValue(value);
+ }, [formatDisplayOnly, isFocused, value]);
+ const phoneActionHref = useMemo(() => (showPhoneAction ? getPhoneActionHref(value) : null), [showPhoneAction, value]);
+
+ const input = (
+ {
+ setIsFocused(true);
+ onFocus?.(event);
+ }}
+ onBlur={(event) => {
+ setIsFocused(false);
+ onBlur?.(event);
+ }}
+ />
+ );
+
+ if (!showPhoneAction) return input;
+
+ return (
+
+ {input}
+ {phoneActionHref ? (
+ } href={phoneActionHref} />
+ ) : (
+ } disabled />
+ )}
+
+ );
+});
export default FormItemPhone;
diff --git a/client/src/components/form-items-formatted/url-form-item.component.jsx b/client/src/components/form-items-formatted/url-form-item.component.jsx
new file mode 100644
index 000000000..c038442fc
--- /dev/null
+++ b/client/src/components/form-items-formatted/url-form-item.component.jsx
@@ -0,0 +1,34 @@
+import { LinkOutlined } from "@ant-design/icons";
+import { Button, Input, Space } from "antd";
+import { forwardRef, useMemo } from "react";
+
+const HAS_URL_PROTOCOL_REGEX = /^[a-zA-Z][a-zA-Z\d+.-]*:/;
+const LOCALHOST_OR_IP_REGEX = /^(localhost|127(?:\.\d{1,3}){3}|\d{1,3}(?:\.\d{1,3}){3})(:\d+)?(\/.*)?$/i;
+
+const getUrlActionHref = (value) => {
+ const trimmedValue = String(value ?? "").trim();
+ if (!trimmedValue) return null;
+
+ if (HAS_URL_PROTOCOL_REGEX.test(trimmedValue)) return trimmedValue;
+ if (trimmedValue.startsWith("//")) return `https:${trimmedValue}`;
+ if (LOCALHOST_OR_IP_REGEX.test(trimmedValue)) return `http://${trimmedValue}`;
+
+ return `https://${trimmedValue}`;
+};
+
+const FormItemUrl = forwardRef(function FormItemUrl({ value, defaultValue, ...props }, ref) {
+ const urlActionHref = useMemo(() => getUrlActionHref(value ?? defaultValue), [defaultValue, value]);
+
+ return (
+
+
+ {urlActionHref ? (
+ } href={urlActionHref} target="_blank" rel="noopener noreferrer" />
+ ) : (
+ } disabled />
+ )}
+
+ );
+});
+
+export default FormItemUrl;
diff --git a/client/src/components/form-list-move-arrows/form-list-item-title.utils.js b/client/src/components/form-list-move-arrows/form-list-item-title.utils.js
new file mode 100644
index 000000000..03f1beeb8
--- /dev/null
+++ b/client/src/components/form-list-move-arrows/form-list-item-title.utils.js
@@ -0,0 +1,30 @@
+/**
+ * Normalize Form Item List Titles
+ * @param value
+ * @returns {*|string}
+ */
+const normalizeFormListTitleValue = (value) => {
+ if (value === null || value === undefined) return "";
+
+ if (Array.isArray(value)) {
+ return value
+ .map((item) => normalizeFormListTitleValue(item))
+ .filter(Boolean)
+ .join(", ");
+ }
+
+ return String(value).trim();
+};
+
+/**
+ * Get Form Listem Item Title
+ * @param fallbackLabel
+ * @param index
+ * @param candidates
+ * @returns {*|string}
+ */
+export function getFormListItemTitle(fallbackLabel, index, ...candidates) {
+ const title = candidates.map((candidate) => normalizeFormListTitleValue(candidate)).find(Boolean);
+
+ return title || `${fallbackLabel} ${index + 1}`;
+}
diff --git a/client/src/components/layout-form-row/config-list-actions.utils.jsx b/client/src/components/layout-form-row/config-list-actions.utils.jsx
new file mode 100644
index 000000000..73bec841e
--- /dev/null
+++ b/client/src/components/layout-form-row/config-list-actions.utils.jsx
@@ -0,0 +1,17 @@
+import { Button } from "antd";
+import ConfigListEmptyState from "./config-list-empty-state.component.jsx";
+
+export const buildConfigListActionButton = ({ key, label, onClick, id }) => (
+
+);
+
+export const renderConfigListOrEmpty = ({ fields, actionLabel, renderItems }) =>
+ fields.length === 0 ? : renderItems();
+
+export const buildSectionActionButton = (key, label, onClick, id) =>
+ buildConfigListActionButton({ key, label, onClick, id });
+
+export const renderListOrEmpty = (fields, actionLabel, renderItems) =>
+ renderConfigListOrEmpty({ fields, actionLabel, renderItems });
diff --git a/client/src/components/layout-form-row/config-list-empty-state.component.jsx b/client/src/components/layout-form-row/config-list-empty-state.component.jsx
new file mode 100644
index 000000000..fc0f41570
--- /dev/null
+++ b/client/src/components/layout-form-row/config-list-empty-state.component.jsx
@@ -0,0 +1,11 @@
+import { useTranslation } from "react-i18next";
+
+export default function ConfigListEmptyState({ actionLabel, minHeight = 96 }) {
+ const { t } = useTranslation();
+
+ return (
+
+ {t("general.labels.click_to_begin", { action: actionLabel })}
+
+ );
+}
diff --git a/client/src/components/layout-form-row/inline-form-row-title.utils.js b/client/src/components/layout-form-row/inline-form-row-title.utils.js
new file mode 100644
index 000000000..70c0e8dd2
--- /dev/null
+++ b/client/src/components/layout-form-row/inline-form-row-title.utils.js
@@ -0,0 +1,89 @@
+import { UnorderedListOutlined } from "@ant-design/icons";
+
+export const inlineFormRowTitleStyles = Object.freeze({
+ input: Object.freeze({
+ background: "transparent",
+ border: "none",
+ borderRadius: 0,
+ boxShadow: "none",
+ paddingInline: 0,
+ paddingBlock: 0,
+ lineHeight: 1.35,
+ flex: "1 1 auto",
+ minWidth: 0,
+ width: "100%"
+ }),
+ row: Object.freeze({
+ display: "flex",
+ gap: 6,
+ flexWrap: "wrap",
+ alignItems: "center",
+ width: "100%",
+ paddingInline: 4
+ }),
+ group: Object.freeze({
+ display: "flex",
+ alignItems: "center",
+ gap: 8,
+ paddingInline: 8,
+ paddingBlock: 4,
+ borderRadius: 10,
+ border: "1px solid var(--imex-form-title-group-border)",
+ background: "var(--imex-form-title-group-bg)",
+ minWidth: 0,
+ flex: "1 1 0"
+ }),
+ label: Object.freeze({
+ color: "var(--ant-color-text-secondary)",
+ fontSize: 12,
+ fontWeight: 600,
+ lineHeight: 1,
+ whiteSpace: "nowrap",
+ paddingInline: 6,
+ paddingBlock: 3,
+ borderRadius: 999,
+ border: "1px solid var(--imex-form-title-label-border)",
+ background: "var(--imex-form-title-label-bg)"
+ }),
+ handle: Object.freeze({
+ color: "var(--ant-color-text-tertiary)",
+ fontSize: 14,
+ flex: "0 0 auto",
+ marginRight: 2
+ }),
+ separator: Object.freeze({
+ width: 1,
+ height: 16,
+ background: "color-mix(in srgb, var(--imex-form-surface-border) 58%, transparent)",
+ borderRadius: 999,
+ flex: "0 0 auto",
+ marginInline: 2
+ }),
+ text: Object.freeze({
+ whiteSpace: "nowrap",
+ fontWeight: 500,
+ fontSize: "var(--ant-font-size-lg)",
+ lineHeight: 1.2
+ })
+});
+
+export const INLINE_TITLE_INPUT_STYLE = inlineFormRowTitleStyles.input;
+export const INLINE_TITLE_ROW_STYLE = inlineFormRowTitleStyles.row;
+export const INLINE_TITLE_GROUP_STYLE = inlineFormRowTitleStyles.group;
+export const InlineTitleListIcon = UnorderedListOutlined;
+export const INLINE_TITLE_SWITCH_GROUP_STYLE = Object.freeze({
+ ...inlineFormRowTitleStyles.group,
+ flex: "0 0 auto"
+});
+export const INLINE_TITLE_LABEL_STYLE = inlineFormRowTitleStyles.label;
+export const INLINE_TITLE_HANDLE_STYLE = inlineFormRowTitleStyles.handle;
+export const INLINE_TITLE_SEPARATOR_STYLE = inlineFormRowTitleStyles.separator;
+export const INLINE_TITLE_TEXT_STYLE = inlineFormRowTitleStyles.text;
+
+export const INLINE_FORM_ROW_WRAP_TITLE_STYLES = Object.freeze({
+ title: Object.freeze({
+ whiteSpace: "normal",
+ overflow: "visible",
+ textOverflow: "unset"
+ })
+});
diff --git a/client/src/components/layout-form-row/inline-validated-form-row.component.jsx b/client/src/components/layout-form-row/inline-validated-form-row.component.jsx
new file mode 100644
index 000000000..70910856b
--- /dev/null
+++ b/client/src/components/layout-form-row/inline-validated-form-row.component.jsx
@@ -0,0 +1,47 @@
+import { Form } from "antd";
+import LayoutFormRow from "./layout-form-row.component";
+
+export default function InlineValidatedFormRow({ actions, errorNames = [], extraErrors = [], form, ...layoutFormRowProps }) {
+ const normalizedErrorNames = Array.isArray(errorNames) ? errorNames : [errorNames];
+ const normalizedExtraErrors = Array.isArray(extraErrors) ? extraErrors.filter(Boolean) : [extraErrors].filter(Boolean);
+
+ return (
+
+ {() => {
+ const fieldErrors = normalizedErrorNames.flatMap((name) => form?.getFieldError?.(name) || []);
+ const errors = [...new Set([...fieldErrors, ...normalizedExtraErrors])];
+ const resolvedClassName = [
+ layoutFormRowProps.className,
+ errors.length > 0 ? "imex-form-row--error" : null
+ ]
+ .filter(Boolean)
+ .join(" ");
+
+ const normalizedActions = Array.isArray(actions) ? actions.filter(Boolean) : [actions].filter(Boolean);
+ const resolvedActions =
+ errors.length > 0
+ ? [
+ 0 ? 8 : 0,
+ width: "100%",
+ textAlign: "left"
+ }}
+ >
+
+ {normalizedActions.length > 0 ?
{normalizedActions}
: null}
+
+ ]
+ : normalizedActions.length > 0
+ ? normalizedActions
+ : undefined;
+
+ return ;
+ }}
+
+ );
+}
diff --git a/client/src/components/layout-form-row/layout-form-row.component.jsx b/client/src/components/layout-form-row/layout-form-row.component.jsx
index 22343a790..ade2cbaab 100644
--- a/client/src/components/layout-form-row/layout-form-row.component.jsx
+++ b/client/src/components/layout-form-row/layout-form-row.component.jsx
@@ -1,5 +1,6 @@
import { Card, Col, Row } from "antd";
import { Children, isValidElement } from "react";
+import { INLINE_FORM_ROW_WRAP_TITLE_STYLES } from "./inline-form-row-title.utils.js";
import "./layout-form-row.styles.scss";
export default function LayoutFormRow({
@@ -7,32 +8,45 @@ export default function LayoutFormRow({
children,
grow = false,
noDivider = false,
- gutter = [16, 16], // Responsive gutter: horizontal, vertical
+ titleOnly = false,
+ wrapTitle = false,
+ gutter,
rowProps,
// Optional overrides if you ever need per-section customization
surface = true,
surfaceBg,
surfaceHeaderBg,
+ surfaceBorderColor,
...cardProps
}) {
const items = Children.toArray(children).filter(Boolean);
- if (items.length === 0) return null;
+ const isCompactRow = noDivider;
const title = !noDivider && header ? header : undefined;
+ const resolvedTitle = cardProps.title ?? title;
+ const isHeaderOnly = titleOnly || items.length === 0;
+ const hideBody = isHeaderOnly;
+
+ if (items.length === 0 && !resolvedTitle) return null;
+ const resolvedGutter = gutter ?? [16, isCompactRow ? 8 : 16];
const bg = surfaceBg ?? (surface ? "var(--imex-form-surface)" : undefined);
const headBg = surfaceHeaderBg ?? (surface ? "var(--imex-form-surface-head)" : undefined);
+ const borderColor = surfaceBorderColor ?? (surface ? "var(--imex-form-surface-border)" : undefined);
const mergedStyles = mergeSemanticStyles(
{
+ ...(wrapTitle ? INLINE_FORM_ROW_WRAP_TITLE_STYLES : null),
header: {
- paddingInline: 16,
- background: headBg
+ paddingInline: isHeaderOnly ? 8 : isCompactRow ? 12 : 16,
+ background: headBg,
+ borderBottomColor: borderColor
},
body: {
- padding: 16,
+ padding: hideBody ? 0 : isCompactRow ? 12 : 16,
+ display: hideBody ? "none" : undefined,
background: bg
}
},
@@ -40,28 +54,12 @@ export default function LayoutFormRow({
);
const baseCardStyle = {
- marginBottom: ".8rem",
+ marginBottom: isHeaderOnly ? "0" : isCompactRow ? "8px" : ".8rem",
...(bg ? { background: bg } : null), // ensures the “circled area” is tinted
+ ...(borderColor ? { borderColor } : null),
...cardProps.style
};
- // single child => just render it
- if (items.length === 1) {
- return (
-
- {items[0]}
-
- );
- }
-
const count = items.length;
// Modern responsive strategy leveraging Ant Design 6:
@@ -125,20 +123,32 @@ export default function LayoutFormRow({
return (
-
- {items.map((child, idx) => (
-
- {child}
-
+ {!isHeaderOnly &&
+ (items.length === 1 ? (
+ items[0]
+ ) : (
+
+ {items.map((child, idx) => (
+
+ {child}
+
+ ))}
+
))}
-
);
}
@@ -152,6 +162,7 @@ function mergeSemanticStyles(defaults, userStyles) {
return {
...defaults,
...computed,
+ title: { ...(defaults.title || {}), ...(computed.title || {}) },
header: { ...defaults.header, ...(computed.header || {}) },
body: { ...defaults.body, ...(computed.body || {}) }
};
@@ -161,6 +172,7 @@ function mergeSemanticStyles(defaults, userStyles) {
return {
...defaults,
...userStyles,
+ title: { ...(defaults.title || {}), ...(userStyles.title || {}) },
header: { ...defaults.header, ...(userStyles.header || {}) },
body: { ...defaults.body, ...(userStyles.body || {}) }
};
diff --git a/client/src/components/layout-form-row/layout-form-row.styles.scss b/client/src/components/layout-form-row/layout-form-row.styles.scss
index 264ae9760..2c95c7973 100644
--- a/client/src/components/layout-form-row/layout-form-row.styles.scss
+++ b/client/src/components/layout-form-row/layout-form-row.styles.scss
@@ -13,6 +13,12 @@
--imex-form-surface: #fafafa; /* subtle contrast vs white page */
--imex-form-surface-head: #f5f5f5; /* header strip */
--imex-form-surface-border: #d9d9d9; /* matches AntD-ish border */
+ --imex-form-title-input-bg: rgba(255, 255, 255, 0.96);
+ --imex-form-title-input-border: rgba(0, 0, 0, 0.08);
+ --imex-form-title-group-bg: rgba(255, 255, 255, 0.72);
+ --imex-form-title-group-border: rgba(0, 0, 0, 0.08);
+ --imex-form-title-label-bg: rgba(0, 0, 0, 0.04);
+ --imex-form-title-label-border: rgba(0, 0, 0, 0.06);
}
/* Pick the selector that matches your app and remove the rest */
@@ -20,6 +26,12 @@ html[data-theme="dark"] {
--imex-form-surface: rgba(255, 255, 255, 0.01); /* subtle lift off page bg */
--imex-form-surface-head: rgba(255, 255, 255, 0.06); /* slightly stronger for header strip */
--imex-form-surface-border: rgba(5, 5, 5, 0.12);
+ --imex-form-title-input-bg: rgba(255, 255, 255, 0.12);
+ --imex-form-title-input-border: rgba(255, 255, 255, 0.2);
+ --imex-form-title-group-bg: rgba(255, 255, 255, 0.08);
+ --imex-form-title-group-border: rgba(255, 255, 255, 0.16);
+ --imex-form-title-label-bg: rgba(255, 255, 255, 0.06);
+ --imex-form-title-label-border: rgba(255, 255, 255, 0.12);
}
.imex-form-row {
@@ -38,18 +50,111 @@ html[data-theme="dark"] {
border-color: var(--imex-form-surface-border);
}
+ &.imex-form-row--error.ant-card {
+ border-color: var(--ant-color-error);
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--ant-color-error) 24%, transparent);
+ }
+
.ant-card-head {
background: var(--imex-form-surface-head);
border-bottom-color: var(--imex-form-surface-border);
}
+ &.imex-form-row--error {
+ .ant-card-head,
+ .ant-card-actions {
+ border-color: color-mix(in srgb, var(--ant-color-error) 34%, var(--imex-form-surface-border));
+ }
+ }
+
+ &.imex-form-row--compact {
+ .ant-card-head {
+ min-height: 40px;
+ }
+
+ .ant-card-head-title,
+ .ant-card-extra {
+ padding-block: 2px;
+ }
+
+ .ant-form-item {
+ margin-bottom: 12px;
+ }
+ }
+
+ &.imex-form-row--title-only {
+ .ant-card-head {
+ min-height: auto;
+ padding-inline: 6px;
+ padding-block: 0;
+ border-radius: inherit;
+ }
+
+ .ant-card-head-wrapper {
+ gap: 2px;
+ align-items: center;
+ }
+
+ .ant-card-head-title,
+ .ant-card-extra {
+ padding-block: 0;
+ display: flex;
+ align-items: center;
+ }
+
+ .ant-card-head-title {
+ white-space: normal;
+ overflow: visible;
+ text-overflow: unset;
+ font-size: var(--ant-font-size);
+ line-height: 1.1;
+ padding-inline: 4px;
+ }
+
+ .ant-card-body {
+ display: none;
+ padding: 0;
+ }
+
+ .ant-input,
+ .ant-input-number,
+ .ant-input-affix-wrapper,
+ .ant-select-selector,
+ .ant-picker {
+ background: var(--imex-form-title-input-bg);
+ border-color: var(--imex-form-title-input-border);
+ }
+
+ .ant-input-number-input {
+ background: transparent;
+ }
+ }
+
.ant-card-body {
background: var(--imex-form-surface);
}
+ .ant-card-actions {
+ background: var(--imex-form-surface-head);
+ border-top-color: var(--imex-form-surface-border);
+ }
+
+ .ant-card-actions > li {
+ margin: 10px 0;
+ padding-inline: 12px;
+ }
+
+ .ant-card-actions .ant-btn {
+ width: 100%;
+ }
+
+ .ant-form-item:last-child {
+ margin-bottom: 4px;
+ }
+
/* Optional: tighter spacing on phones for better space usage */
@media (max-width: 575px) {
- .ant-card-head {
+ &:not(.imex-form-row--title-only) .ant-card-head {
padding-inline: 12px;
padding-block: 12px;
}
@@ -70,6 +175,14 @@ html[data-theme="dark"] {
width: 100%;
}
+ .ant-form-item:has(.imex-form-row--compact) {
+ margin-bottom: 8px;
+ }
+
+ .ant-form-item:has(.imex-form-row--title-only) {
+ margin-bottom: 4px;
+ }
+
/* Better form item spacing on mobile */
@media (max-width: 575px) {
.ant-form-item {
@@ -77,3 +190,24 @@ html[data-theme="dark"] {
}
}
}
+
+.imex-form-row-empty-state {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px 16px;
+ text-align: center;
+ color: var(--ant-color-text-description);
+ font-size: var(--ant-font-size);
+ line-height: 1.5;
+}
+
+.imex-inline-form-row-errors {
+ color: var(--ant-color-error);
+
+ .ant-form-item-explain,
+ .ant-form-item-explain-error,
+ .ant-form-item-additional {
+ color: var(--ant-color-error);
+ }
+}
diff --git a/client/src/components/parts-order-modal/parts-order-modal.component.jsx b/client/src/components/parts-order-modal/parts-order-modal.component.jsx
index bfb0cb1df..3766b2e7b 100644
--- a/client/src/components/parts-order-modal/parts-order-modal.component.jsx
+++ b/client/src/components/parts-order-modal/parts-order-modal.component.jsx
@@ -1,12 +1,13 @@
import { DeleteFilled, DownOutlined, WarningFilled } from "@ant-design/icons";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
-import { Checkbox, Divider, Dropdown, Form, Input, InputNumber, Radio, Select, Space, Tag } from "antd";
+import { Button, Checkbox, Divider, Dropdown, Form, Input, InputNumber, Radio, Select, Space, Tag } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
import PartsOrderModalPriceChange from "./parts-order-modal-price-change.component";
@@ -50,6 +51,7 @@ export function PartsOrderModalComponent({
});
const { t } = useTranslation();
+ const partsOrderLines = Form.useWatch(["parts_order_lines", "data"], form) || [];
const handleClick = ({ item }) => {
form.setFieldsValue({ comments: item.props.value });
};
@@ -128,10 +130,38 @@ export function PartsOrderModalComponent({
{(fields, { remove, move }) => {
return (
- {fields.map((field, index) => (
-
-
-
+ {fields.map((field, index) => {
+ const partsOrderLine = partsOrderLines[field.name] || {};
+
+ return (
+
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
)}
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
-
- ))}
+
+ );
+ })}
);
}}
diff --git a/client/src/components/parts-receive-modal/parts-receive-modal.component.jsx b/client/src/components/parts-receive-modal/parts-receive-modal.component.jsx
index 723ccb9db..c4fdd1bd0 100644
--- a/client/src/components/parts-receive-modal/parts-receive-modal.component.jsx
+++ b/client/src/components/parts-receive-modal/parts-receive-modal.component.jsx
@@ -1,10 +1,11 @@
import { DeleteFilled } from "@ant-design/icons";
-import { Form, Input, InputNumber, Select, Typography } from "antd";
+import { Button, Form, Input, InputNumber, Select, Space, Typography } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
const mapStateToProps = createStructuredSelector({
@@ -15,6 +16,7 @@ export default connect(mapStateToProps, null)(PartsReceiveModalComponent);
export function PartsReceiveModalComponent({ bodyshop, form }) {
const { t } = useTranslation();
+ const partsOrderLines = Form.useWatch(["partsorderlines"], form) || [];
return (
@@ -42,16 +44,43 @@ export function PartsReceiveModalComponent({ bodyshop, form }) {
{(fields, { remove, move }) => {
return (
);
}}
diff --git a/client/src/components/parts-shop-info/parts-email-presets.component.jsx b/client/src/components/parts-shop-info/parts-email-presets.component.jsx
index deb5bb436..ba91f833d 100644
--- a/client/src/components/parts-shop-info/parts-email-presets.component.jsx
+++ b/client/src/components/parts-shop-info/parts-email-presets.component.jsx
@@ -2,10 +2,13 @@ import { DeleteFilled } from "@ant-design/icons";
import { Button, Form, Input, Select, Space } from "antd";
import { useTranslation } from "react-i18next";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function PartsEmailPresetsComponent() {
const { t } = useTranslation();
+ const form = Form.useFormInstance();
+ const emailPresets = Form.useWatch(["md_to_emails"], form) || [];
return (
@@ -14,31 +17,46 @@ export default function PartsEmailPresetsComponent() {
{(fields, { add, remove, move }) => {
return (
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
+ {fields.map((field, index) => {
+ const preset = emailPresets[field.name] || {};
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
+ return (
+
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+ );
+ })}
+ ]}
+ >
+ {employees.length === 0 ? (
+
+ ) : (
+ navigateToEmployee(props.id),
+ type: "radio",
+ selectedRowKeys: [selectedEmployeeId || search.employeeId]
+ }}
+ onChange={handleTableChange}
+ onRow={(record) => {
+ return {
+ onClick: () => {
+ handleOnRowClick(record);
+ }
+ };
+ }}
+ />
+ )}
+
);
}
diff --git a/client/src/components/shop-employees/shop-employees.container.jsx b/client/src/components/shop-employees/shop-employees.container.jsx
index 8b22b87a4..3582ee40c 100644
--- a/client/src/components/shop-employees/shop-employees.container.jsx
+++ b/client/src/components/shop-employees/shop-employees.container.jsx
@@ -1,29 +1,101 @@
+import { Drawer, Form, Grid } from "antd";
import { useQuery } from "@apollo/client/react";
+import queryString from "query-string";
import { connect } from "react-redux";
+import { useState } from "react";
+import { useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { QUERY_EMPLOYEES } from "../../graphql/employees.queries";
+import useConfirmDirtyFormNavigation from "../../hooks/useConfirmDirtyFormNavigation.jsx";
import AlertComponent from "../alert/alert.component";
import ShopEmployeesFormComponent from "./shop-employees-form.component";
import ShopEmployeesListComponent from "./shop-employees-list.component";
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
+import "./shop-employees.styles.scss";
const mapStateToProps = createStructuredSelector({});
function ShopEmployeesContainer() {
+ const [form] = Form.useForm();
+ const [isEmployeeFormDirty, setIsEmployeeFormDirty] = useState(false);
+ const location = useLocation();
+ const navigate = useNavigate();
+ const search = queryString.parse(location.search);
const { loading, error, data } = useQuery(QUERY_EMPLOYEES, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only"
});
+ const screens = Grid.useBreakpoint();
+ const hasSelectedEmployee = Boolean(search.employeeId);
+
+ const bpoints = {
+ xs: "100%",
+ sm: "100%",
+ md: "92%",
+ lg: "80%",
+ xl: "80%",
+ xxl: "80%"
+ };
+
+ let drawerPercentage = "100%";
+ if (screens.xxl) drawerPercentage = bpoints.xxl;
+ else if (screens.xl) drawerPercentage = bpoints.xl;
+ else if (screens.lg) drawerPercentage = bpoints.lg;
+ else if (screens.md) drawerPercentage = bpoints.md;
+ else if (screens.sm) drawerPercentage = bpoints.sm;
+ else if (screens.xs) drawerPercentage = bpoints.xs;
+
+ const hasDirtyEmployeeForm = Boolean(search.employeeId) && (isEmployeeFormDirty || form.isFieldsTouched());
+ const confirmCloseDirtyEmployee = useConfirmDirtyFormNavigation(hasDirtyEmployeeForm);
+
+ const navigateToEmployee = (employeeId) => {
+ if (employeeId === search.employeeId) return;
+ if (!confirmCloseDirtyEmployee()) return;
+
+ const nextSearch = { ...search, employeeId };
+ setIsEmployeeFormDirty(false);
+ navigate({
+ search: queryString.stringify(nextSearch)
+ });
+ };
+
+ const handleDrawerClose = () => {
+ if (!confirmCloseDirtyEmployee()) return;
+
+ const nextSearch = { ...search };
+ delete nextSearch.employeeId;
+ setIsEmployeeFormDirty(false);
+ navigate({
+ search: queryString.stringify(nextSearch)
+ });
+ };
if (error) return ;
return (
-
-
-
-
-
-
+
+
+
+ {hasSelectedEmployee ? (
+
+ ) : null}
+
+
);
}
diff --git a/client/src/components/shop-employees/shop-employees.styles.scss b/client/src/components/shop-employees/shop-employees.styles.scss
new file mode 100644
index 000000000..69ee5c1d0
--- /dev/null
+++ b/client/src/components/shop-employees/shop-employees.styles.scss
@@ -0,0 +1,7 @@
+.shop-employees-layout {
+ min-width: 0;
+}
+
+.shop-employees-layout__list {
+ min-width: 0;
+}
diff --git a/client/src/components/shop-info/shop-info.color.utils.js b/client/src/components/shop-info/shop-info.color.utils.js
new file mode 100644
index 000000000..d577aee25
--- /dev/null
+++ b/client/src/components/shop-info/shop-info.color.utils.js
@@ -0,0 +1,304 @@
+/**
+ * Default translucent card color used for tinting card surfaces when no specific color is provided.
+ * @type {{r: number, g: number, b: number, a: number}}
+ */
+export const DEFAULT_TRANSLUCENT_CARD_COLOR = {
+ r: 22,
+ g: 119,
+ b: 255,
+ a: 0.5
+};
+
+/**
+ * Rounds a color channel value to two decimal places.
+ * @param value
+ * @returns {number}
+ */
+const roundColorChannel = (value) => Math.round(value * 100) / 100;
+
+/**
+ * Rounds a tint percentage value to two decimal places.
+ * @param value
+ * @returns {number}
+ */
+const roundTintPercentage = (value) => Math.round(value * 100) / 100;
+
+/**
+ * Clamps an alpha value to the range [0, 1] and rounds it to two decimal places.
+ * @param value
+ * @returns {number}
+ */
+const clampAlpha = (value) => {
+ const numericValue = Number(value);
+
+ if (!Number.isFinite(numericValue)) return 1;
+ if (numericValue <= 0) return 0;
+ if (numericValue >= 1) return 1;
+
+ return numericValue;
+};
+
+/**
+ * Converts an RGB color object to a hexadecimal color string.
+ * @param param0
+ * @param param0.r
+ * @param param0.g
+ * @param param0.b
+ * @returns {`#${string}`}
+ */
+const rgbToHex = ({ r, g, b }) =>
+ `#${[r, g, b].map((channel) => Math.round(channel).toString(16).padStart(2, "0")).join("")}`;
+
+/**
+ * Converts an RGB color object to an HSL color object.
+ * @param param0
+ * @param param0.r
+ * @param param0.g
+ * @param param0.b
+ * @param param0.a
+ * @returns {{h: number, s: number, l: number, a: number}|{h: number, s: number, l: number, a: number}}
+ */
+const rgbToHsl = ({ r, g, b, a = 1 }) => {
+ const red = r / 255;
+ const green = g / 255;
+ const blue = b / 255;
+ const max = Math.max(red, green, blue);
+ const min = Math.min(red, green, blue);
+ const delta = max - min;
+ const lightness = (max + min) / 2;
+
+ if (delta === 0) {
+ return { h: 0, s: 0, l: roundColorChannel(lightness), a };
+ }
+
+ const saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);
+ let hue;
+
+ switch (max) {
+ case red:
+ hue = (green - blue) / delta + (green < blue ? 6 : 0);
+ break;
+ case green:
+ hue = (blue - red) / delta + 2;
+ break;
+ default:
+ hue = (red - green) / delta + 4;
+ break;
+ }
+
+ return {
+ h: roundColorChannel(hue * 60),
+ s: roundColorChannel(saturation),
+ l: roundColorChannel(lightness),
+ a
+ };
+};
+
+/**
+ * Converts an RGB color object to an HSV color object.
+ * @param param0
+ * @param param0.r
+ * @param param0.g
+ * @param param0.b
+ * @param param0.a
+ * @returns {{h: number, s: number, v: number, a: number}}
+ */
+const rgbToHsv = ({ r, g, b, a = 1 }) => {
+ const red = r / 255;
+ const green = g / 255;
+ const blue = b / 255;
+ const max = Math.max(red, green, blue);
+ const min = Math.min(red, green, blue);
+ const delta = max - min;
+ const saturation = max === 0 ? 0 : delta / max;
+ let hue = 0;
+
+ if (delta !== 0) {
+ switch (max) {
+ case red:
+ hue = (green - blue) / delta + (green < blue ? 6 : 0);
+ break;
+ case green:
+ hue = (blue - red) / delta + 2;
+ break;
+ default:
+ hue = (red - green) / delta + 4;
+ break;
+ }
+ }
+
+ return {
+ h: roundColorChannel(hue * 60),
+ s: roundColorChannel(saturation),
+ v: roundColorChannel(max),
+ a
+ };
+};
+
+/**
+ * Builds a comprehensive color value object for a color picker component based on an input RGB color object.
+ * @param rgb
+ * @returns {{hex: `#${string}`, rgb: *, hsl: {h: number, s: number, l: number, a: number}, hsv: {h: number, s: number, v: number, a: number}, oldHue: number, source: string}}
+ */
+const buildPickerColorValue = (rgb) => {
+ const hsl = rgbToHsl(rgb);
+
+ return {
+ hex: rgbToHex(rgb),
+ rgb: { ...rgb },
+ hsl,
+ hsv: rgbToHsv(rgb),
+ oldHue: hsl.h,
+ source: "rgb"
+ };
+};
+
+/**
+ * Default color value object for the color picker component, derived from the default translucent card color.
+ * @type {{hex: `#${string}`, rgb: *, hsl: {h: number, s: number, l: number, a: number}, hsv: {h: number, s: number, v: number, a: number}, oldHue: number, source: string}}
+ */
+export const DEFAULT_TRANSLUCENT_PICKER_COLOR = buildPickerColorValue(DEFAULT_TRANSLUCENT_CARD_COLOR);
+
+/**
+ * Parses a color string that may be a JSON representation of a color object. If the string is valid JSON and represents
+ * a color, it returns the parsed object; otherwise, it returns the original string.
+ * @param color
+ * @returns {*|string}
+ */
+const parseJsonColorString = (color) => {
+ if (typeof color !== "string") return color;
+
+ const trimmedColor = color.trim();
+ if (!trimmedColor.startsWith("{") && !trimmedColor.startsWith("[")) return color;
+
+ try {
+ return JSON.parse(trimmedColor);
+ } catch {
+ return color;
+ }
+};
+
+/**
+ * Parses a hexadecimal color string (e.g., "#RRGGBB" or "#RRGGBBAA") and returns an object containing the corresponding
+ * RGB color value and alpha transparency. Supports both 3/4-digit and 6/8-digit hex formats.
+ * @param color
+ * @returns {{colorCssValue: string, alpha: number}|null}
+ */
+const parseHexColor = (color) => {
+ if (typeof color !== "string") return null;
+
+ const normalizedHex = color.trim().replace(/^#/, "");
+
+ if (![3, 4, 6, 8].includes(normalizedHex.length) || /[^0-9a-f]/i.test(normalizedHex)) {
+ return null;
+ }
+
+ const expandedHex =
+ normalizedHex.length <= 4
+ ? normalizedHex
+ .split("")
+ .map((character) => `${character}${character}`)
+ .join("")
+ : normalizedHex;
+
+ const hasAlpha = expandedHex.length === 8;
+ const red = Number.parseInt(expandedHex.slice(0, 2), 16);
+ const green = Number.parseInt(expandedHex.slice(2, 4), 16);
+ const blue = Number.parseInt(expandedHex.slice(4, 6), 16);
+ const alpha = hasAlpha ? Number.parseInt(expandedHex.slice(6, 8), 16) / 255 : 1;
+
+ return {
+ colorCssValue: `rgb(${red}, ${green}, ${blue})`,
+ alpha: clampAlpha(alpha)
+ };
+};
+
+/**
+ * Parses an RGB or RGBA color string (e.g., "rgb(255, 0, 0)" or "rgba(255, 0, 0, 0.5)") and returns an object
+ * containing the corresponding RGB color value and alpha transparency. Supports both integer and percentage formats for
+ * color channels and alpha.
+ * @param color
+ * @returns {{colorCssValue: string, alpha: number}|null}
+ */
+const parseRgbColor = (color) => {
+ if (typeof color !== "string") return null;
+
+ const rgbMatch = color.trim().match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)$/i);
+
+ if (!rgbMatch) return null;
+
+ const [, red, green, blue, alpha = 1] = rgbMatch;
+
+ return {
+ colorCssValue: `rgb(${red}, ${green}, ${blue})`,
+ alpha: clampAlpha(alpha)
+ };
+};
+
+/**
+ * Normalizes a color input into a consistent descriptor object containing a CSS color value and an alpha transparency
+ * level.
+ * @param color
+ * @returns {{colorCssValue: string, alpha: number}|{colorCssValue: string, alpha: number}|*|{colorCssValue: string, alpha: number}|null}
+ */
+const getNormalizedColorDescriptor = (color) => {
+ if (!color) return null;
+
+ const normalizedColor = parseJsonColorString(color);
+
+ if (typeof normalizedColor === "string") {
+ return (
+ parseHexColor(normalizedColor) ||
+ parseRgbColor(normalizedColor) || {
+ colorCssValue: normalizedColor,
+ alpha: 1
+ }
+ );
+ }
+
+ if (typeof normalizedColor === "object" && normalizedColor.rgb) {
+ return getNormalizedColorDescriptor(normalizedColor.rgb);
+ }
+
+ if (typeof normalizedColor === "object" && typeof normalizedColor.hex === "string") {
+ return getNormalizedColorDescriptor(normalizedColor.hex);
+ }
+
+ if (
+ typeof normalizedColor === "object" &&
+ normalizedColor.r !== undefined &&
+ normalizedColor.g !== undefined &&
+ normalizedColor.b !== undefined
+ ) {
+ return {
+ colorCssValue: `rgb(${normalizedColor.r}, ${normalizedColor.g}, ${normalizedColor.b})`,
+ alpha: clampAlpha(normalizedColor.a)
+ };
+ }
+
+ return null;
+};
+
+/**
+ * Generates CSS styles for tinting card surfaces based on a provided color input. The function normalizes the input
+ * color,
+ * @param color
+ * @returns {{surfaceBg: string, surfaceHeaderBg: string, surfaceBorderColor: string}|{}}
+ */
+export const getTintedCardSurfaceStyles = (color) => {
+ const normalizedColor = getNormalizedColorDescriptor(color);
+ if (!normalizedColor?.colorCssValue) return {};
+
+ const tintStrength = clampAlpha(normalizedColor.alpha);
+ if (tintStrength === 0) return {};
+
+ const backgroundTint = roundTintPercentage(10 * tintStrength);
+ const headerTint = roundTintPercentage(18 * tintStrength);
+ const borderTint = roundTintPercentage(30 * tintStrength);
+
+ return {
+ surfaceBg: `color-mix(in srgb, ${normalizedColor.colorCssValue} ${backgroundTint}%, var(--imex-form-surface))`,
+ surfaceHeaderBg: `color-mix(in srgb, ${normalizedColor.colorCssValue} ${headerTint}%, var(--imex-form-surface-head))`,
+ surfaceBorderColor: `color-mix(in srgb, ${normalizedColor.colorCssValue} ${borderTint}%, var(--imex-form-surface-border))`
+ };
+};
diff --git a/client/src/components/shop-info/shop-info.color.utils.test.js b/client/src/components/shop-info/shop-info.color.utils.test.js
new file mode 100644
index 000000000..d39fb810f
--- /dev/null
+++ b/client/src/components/shop-info/shop-info.color.utils.test.js
@@ -0,0 +1,52 @@
+import { describe, expect, it } from "vitest";
+import { getTintedCardSurfaceStyles } from "./shop-info.color.utils";
+
+describe("shop info color utilities", () => {
+ it("scales card tint intensity with alpha for plain rgba values", () => {
+ expect(
+ getTintedCardSurfaceStyles({
+ r: 22,
+ g: 119,
+ b: 255,
+ a: 0.5
+ })
+ ).toEqual({
+ surfaceBg: "color-mix(in srgb, rgb(22, 119, 255) 5%, var(--imex-form-surface))",
+ surfaceHeaderBg: "color-mix(in srgb, rgb(22, 119, 255) 9%, var(--imex-form-surface-head))",
+ surfaceBorderColor: "color-mix(in srgb, rgb(22, 119, 255) 15%, var(--imex-form-surface-border))"
+ });
+ });
+
+ it("returns no tint when the selected color alpha is zero", () => {
+ expect(
+ getTintedCardSurfaceStyles({
+ hex: "#1677ff",
+ rgb: {
+ r: 22,
+ g: 119,
+ b: 255,
+ a: 0
+ }
+ })
+ ).toEqual({});
+ });
+
+ it("supports legacy JSON-stringified picker values", () => {
+ expect(
+ getTintedCardSurfaceStyles(
+ JSON.stringify({
+ rgb: {
+ r: 255,
+ g: 0,
+ b: 0,
+ a: 0.25
+ }
+ })
+ )
+ ).toEqual({
+ surfaceBg: "color-mix(in srgb, rgb(255, 0, 0) 2.5%, var(--imex-form-surface))",
+ surfaceHeaderBg: "color-mix(in srgb, rgb(255, 0, 0) 4.5%, var(--imex-form-surface-head))",
+ surfaceBorderColor: "color-mix(in srgb, rgb(255, 0, 0) 7.5%, var(--imex-form-surface-border))"
+ });
+ });
+});
diff --git a/client/src/components/shop-info/shop-info.component.jsx b/client/src/components/shop-info/shop-info.component.jsx
index 8dd04843e..901a14afe 100644
--- a/client/src/components/shop-info/shop-info.component.jsx
+++ b/client/src/components/shop-info/shop-info.component.jsx
@@ -1,6 +1,7 @@
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { Button, Card, Tabs } from "antd";
import queryString from "query-string";
+import { useRef } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";
@@ -21,6 +22,7 @@ import ShopInfoResponsibilityCenterComponent from "./shop-info.responsibilitycen
import ShopInfoRoGuard from "./shop-info.roguard.component";
import ShopInfoROStatusComponent from "./shop-info.rostatus.component";
import ShopInfoSchedulingComponent from "./shop-info.scheduling.component";
+import ShopInfoSectionNavigator from "./shop-info.section-navigator.component.jsx";
import ShopInfoSpeedPrint from "./shop-info.speedprint.component";
import ShopInfoTaskPresets from "./shop-info.task-presets.component";
import ShopInfoIntellipay from "./shop-intellipay-config.component";
@@ -33,7 +35,7 @@ const mapDispatchToProps = () => ({
});
export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoComponent);
-export function ShopInfoComponent({ bodyshop, form, saveLoading }) {
+export function ShopInfoComponent({ bodyshop, form, saveLoading, isDirty }) {
const {
treatments: { CriticalPartsScanning, Enhanced_Payroll }
} = useTreatmentsWithConfig({
@@ -47,6 +49,7 @@ export function ShopInfoComponent({ bodyshop, form, saveLoading }) {
const history = useNavigate();
const location = useLocation();
const search = queryString.parse(location.search);
+ const tabsRef = useRef(null);
const tabItems = [
{
@@ -154,23 +157,35 @@ export function ShopInfoComponent({ bodyshop, form, saveLoading }) {
]
: [])
];
+ const activeTabKey = search.subtab || tabItems[0]?.key;
+
return (
}
extra={
- form.submit()} id="shop-info-save-button">
- {t("general.actions.save")}
+ form.submit()}
+ id="shop-info-save-button"
+ style={{ minWidth: 210 }}
+ >
+ {t("bodyshop.actions.save_shop_information")}
}
>
-
- history({
- search: `?tab=${search.tab}&subtab=${key}`
- })
- }
- items={tabItems}
- />
+
+
+ history({
+ search: `?tab=${search.tab}&subtab=${key}`
+ })
+ }
+ items={tabItems}
+ />
+
);
}
diff --git a/client/src/components/shop-info/shop-info.consent.component.jsx b/client/src/components/shop-info/shop-info.consent.component.jsx
index 28992e594..621095c14 100644
--- a/client/src/components/shop-info/shop-info.consent.component.jsx
+++ b/client/src/components/shop-info/shop-info.consent.component.jsx
@@ -1,4 +1,4 @@
-import { Card, Typography } from "antd";
+import { Card } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -15,9 +15,8 @@ function ShopInfoConsentComponent({ bodyshop }) {
const { t } = useTranslation();
return (
-
- {t("settings.title")}
- {}
+
+
);
}
diff --git a/client/src/components/shop-info/shop-info.container.jsx b/client/src/components/shop-info/shop-info.container.jsx
index a43403776..823091b12 100644
--- a/client/src/components/shop-info/shop-info.container.jsx
+++ b/client/src/components/shop-info/shop-info.container.jsx
@@ -1,6 +1,6 @@
import { useMutation, useQuery } from "@apollo/client/react";
import { Form } from "antd";
-import { useEffect, useState } from "react";
+import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
import { logImEXEvent } from "../../firebase/firebase.utils";
@@ -15,6 +15,7 @@ import { FEATURE_CONFIGS, useFormDataPreservation } from "./useFormDataPreservat
export default function ShopInfoContainer() {
const [form] = Form.useForm();
const { t } = useTranslation();
+ const [isShopInfoDirty, setIsShopInfoDirty] = useState(false);
const [saveLoading, setSaveLoading] = useState(false);
const [updateBodyshop] = useMutation(UPDATE_SHOP);
const { loading, error, data, refetch } = useQuery(QUERY_BODYSHOP, {
@@ -33,7 +34,10 @@ export default function ShopInfoContainer() {
return acc;
}, {});
- const combinedFeatureConfig = combineFeatureConfigs(FEATURE_CONFIGS.general, FEATURE_CONFIGS.responsibilitycenters);
+ const combinedFeatureConfig = useMemo(
+ () => combineFeatureConfigs(FEATURE_CONFIGS.general, FEATURE_CONFIGS.responsibilitycenters),
+ []
+ );
// Use form data preservation for all shop-info features
const { createSubmissionHandler, preserveHiddenFormData } = useFormDataPreservation(
@@ -51,7 +55,10 @@ export default function ShopInfoContainer() {
})
.then(() => {
notification.success({ title: t("bodyshop.successes.save") });
- refetch().then(() => form.resetFields());
+ refetch().then(() => {
+ form.resetFields();
+ setIsShopInfoDirty(false);
+ });
})
.catch((error) => {
notification.error({
@@ -66,6 +73,7 @@ export default function ShopInfoContainer() {
form.resetFields();
// After reset, re-apply hidden field preservation so values aren't wiped
preserveHiddenFormData();
+ setIsShopInfoDirty(false);
}, [data, form, preserveHiddenFormData]);
if (error) return ;
@@ -76,6 +84,9 @@ export default function ShopInfoContainer() {
layout="vertical"
autoComplete="new-password"
onFinish={handleFinish}
+ onValuesChange={() => {
+ setIsShopInfoDirty(form.isFieldsTouched());
+ }}
initialValues={
data
? data?.bodyshops?.[0]?.accountingconfig?.ClosingPeriod
@@ -99,8 +110,8 @@ export default function ShopInfoContainer() {
: null
}
>
-
-
+
+
);
}
diff --git a/client/src/components/shop-info/shop-info.general.component.jsx b/client/src/components/shop-info/shop-info.general.component.jsx
index 00410f0f9..fa3a2c3af 100644
--- a/client/src/components/shop-info/shop-info.general.component.jsx
+++ b/client/src/components/shop-info/shop-info.general.component.jsx
@@ -1,5 +1,5 @@
import { DeleteFilled } from "@ant-design/icons";
-import { Button, Form, Input, InputNumber, Select, Space, Switch } from "antd";
+import { Button, Col, Form, Input, InputNumber, Row, Select, Space, Switch } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -7,10 +7,24 @@ import FeatureWrapper from "../feature-wrapper/feature-wrapper.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import FormItemEmail from "../form-items-formatted/email-form-item.component";
import PhoneFormItem, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component";
+import FormItemUrl from "../form-items-formatted/url-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import { buildSectionActionButton, renderListOrEmpty } from "../layout-form-row/config-list-actions.utils.jsx";
+import InlineValidatedFormRow from "../layout-form-row/inline-validated-form-row.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
+import {
+ INLINE_TITLE_GROUP_STYLE,
+ INLINE_TITLE_HANDLE_STYLE,
+ INLINE_TITLE_INPUT_STYLE,
+ INLINE_TITLE_LABEL_STYLE,
+ INLINE_TITLE_ROW_STYLE,
+ INLINE_TITLE_SEPARATOR_STYLE,
+ INLINE_TITLE_SWITCH_GROUP_STYLE,
+ InlineTitleListIcon
+} from "../layout-form-row/inline-form-row-title.utils.js";
const timeZonesList = Intl.supportedValuesOf("timeZone");
+
const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = () => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
@@ -19,6 +33,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoGeneral);
export function ShopInfoGeneral({ form }) {
const { t } = useTranslation();
+ const insuranceCompanies = Form.useWatch(["md_ins_cos"], form) || [];
+ const duplicateInsuranceCompanyIndexes = getDuplicateIndexSetByNormalizedName(insuranceCompanies, "name");
return (
+ }
+ wrapTitle
+ >
-
+
-
-
-
-
+
- {[
+ <>
- ,
+
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
- ({
- validator(rule, value) {
- if (!value && !getFieldValue(["md_hour_split", "paint"])) {
- return Promise.resolve();
- }
- if (value + getFieldValue(["md_hour_split", "paint"]) === 1) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.larsplit"));
- }
- })
- ]}
- >
-
- ,
- ({
- validator(rule, value) {
- if (!value && !getFieldValue(["md_hour_split", "paint"])) {
- return Promise.resolve();
- }
- if (value + getFieldValue(["md_hour_split", "prep"]) === 1) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.larsplit"));
- }
- })
- ]}
- >
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
+
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ,
-
-
- ]}
-
-
-
-
-
-
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {t("general.actions.add")}
-
-
-
- );
- }}
-
-
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
+ {t("bodyshop.labels.localmediaserver")}
+
+
- {t("general.actions.add")}
-
-
-
- );
- }}
-
-
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
-
+
+
+
+ {t("bodyshop.fields.system_settings.local_media_server.enabled")}
+
+
+
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
+
+
+
+ }
+ wrapTitle
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {t("bodyshop.actions.addpartslocation")}
-
-
-
- );
- }}
-
+ {t("bodyshop.labels.jobcosting")}
+
+
+
+
+
+ {t("bodyshop.fields.system_settings.job_costing.use_paint_scale_data")}
+
+
+
+
+
+
+
+ }
+ wrapTitle
+ >
+
+
+
+
({
+ validator(rule, value) {
+ if (!value && !getFieldValue(["md_hour_split", "paint"])) {
+ return Promise.resolve();
+ }
+ if (value + getFieldValue(["md_hour_split", "paint"]) === 1) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.larsplit"));
+ }
+ })
+ ]}
+ >
+
+
+
({
+ validator(rule, value) {
+ if (!value && !getFieldValue(["md_hour_split", "paint"])) {
+ return Promise.resolve();
+ }
+ if (value + getFieldValue(["md_hour_split", "prep"]) === 1) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.larsplit"));
+ }
+ })
+ ]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.add_messaging_preset"), () =>
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("bodyshop.fields.messaginglabel_short")}
+
+
+
+
+
+ }
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+
+
+
+
+ );
+ })
+ )}
+
+
+ );
+ }}
+
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.add_note_preset"), () =>
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("bodyshop.fields.noteslabel_short")}
+
+
+
+
+
+ }
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+
+
+
+
+ );
+ })
+ )}
+
+
+ );
+ }}
+
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.addpartslocation"), () =>
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("bodyshop.fields.partslocation")}
+
+
+
+
+
+ }
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ />
+
+ );
+ })
+ )}
+
+
+ );
+ }}
+
{/*Start Insurance Provider Row */}
-
+
+ );
+ }}
+
{/*End Insurance Provider Row */}
-
-
- {(fields, { add, remove, move }) => {
- return (
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
-
-
- PhoneItemFormatterValidation(getFieldValue, [field.name, "est_ph"])
- ]}
- >
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
-
- );
- }}
-
-
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
- PhoneItemFormatterValidation(getFieldValue, [field.name, "ins_ph"])
- ]}
- >
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
-
- );
- }}
-
-
- null}>
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("jobs.fields.est_ct_fn_short")}
+
+
+
+
+
+
+
{t("jobs.fields.est_ct_ln_short")}
+
+
+
+
+
+
+
{t("jobs.fields.est_co_nm_short")}
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
>
-
-
- PhoneItemFormatterValidation(getFieldValue, [field.name, "est_ph"])
+ ]}
+ >
+
+
+
+
+
+
+
+ );
+ })
+ )}
+
+
+ );
+ }}
+
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.add_adjuster"), () =>
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("jobs.fields.ins_ct_fn_short")}
+
+
+
+
+
+
+
{t("jobs.fields.ins_ct_ln_short")}
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
>
-
+ PhoneItemFormatterValidation(getFieldValue, [field.name, "ins_ph"])
+ ]}
+ >
+
+
+
+
+
+
+
+ );
+ })
+ )}
+
+
+ );
+ }}
+
+ null}>
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ }
+ )
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.add_courtesy_car_rate_preset"), () =>
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("general.labels.label")}
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
+ );
+ })
+ )}
- );
- }}
-
-
+
+ );
+ }}
+
-
-
- {(fields, { add, remove, move }) => {
- return (
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
+ );
+ })
+ )}
- );
- }}
-
-
-
+ );
+ }}
+
+
+ {(fields, { add, remove, move }) => {
+ return (
+
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
+ );
+ })
+ )}
- );
- }}
-
-
-
-
- {(fields, { add, remove, move }) => {
- return (
+
+ );
+ }}
+
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
- {fields.map((field, index) => (
-
-
-
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("general.labels.label")}
+
+
+
+
+
}
- ]}
- >
-
-
-
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
}
- ]}
- >
-
+ >
+
+
+
+
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
+ );
+ })
+ )}
- );
- }}
-
-
+
+ );
+ }}
+
);
}
+
+function getDuplicateIndexSetByNormalizedName(list, key) {
+ const indexes = new Set();
+ const firstIndexByValue = new Map();
+
+ (Array.isArray(list) ? list : []).forEach((item, index) => {
+ const normalizedValue = (item?.[key] ?? "").toString().trim().toLowerCase();
+ if (!normalizedValue) return;
+
+ if (firstIndexByValue.has(normalizedValue)) {
+ indexes.add(firstIndexByValue.get(normalizedValue));
+ indexes.add(index);
+ return;
+ }
+
+ firstIndexByValue.set(normalizedValue, index);
+ });
+
+ return indexes;
+}
diff --git a/client/src/components/shop-info/shop-info.intake.component.jsx b/client/src/components/shop-info/shop-info.intake.component.jsx
index 174a6ddf0..9a8b6bc12 100644
--- a/client/src/components/shop-info/shop-info.intake.component.jsx
+++ b/client/src/components/shop-info/shop-info.intake.component.jsx
@@ -5,7 +5,19 @@ import styled from "styled-components";
import { TemplateList } from "../../utils/TemplateConstants";
import ConfigFormTypes from "../config-form-components/config-form-types";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
+import InlineValidatedFormRow from "../layout-form-row/inline-validated-form-row.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
+import {
+ INLINE_TITLE_GROUP_STYLE,
+ INLINE_TITLE_HANDLE_STYLE,
+ INLINE_TITLE_INPUT_STYLE,
+ INLINE_TITLE_LABEL_STYLE,
+ INLINE_TITLE_ROW_STYLE,
+ INLINE_TITLE_SEPARATOR_STYLE,
+ INLINE_TITLE_SWITCH_GROUP_STYLE,
+ InlineTitleListIcon
+} from "../layout-form-row/inline-form-row-title.utils.js";
const SelectorDiv = styled.div`
.ant-form-item .ant-select {
@@ -19,306 +31,386 @@ export default function ShopInfoIntakeChecklistComponent({ form }) {
const TemplateListGenerated = TemplateList();
return (
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
- ({ value: i, label: i }))} />
-
-
-
-
-
-
- {() => {
- if (form.getFieldValue(["intakechecklist", "form", index, "type"]) !== "slider") return null;
- return (
- <>
-
-
-
-
-
-
- >
- );
- }}
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
-
- );
- }}
-
-
-
- ({
- value: TemplateListGenerated[i].key,
- label: TemplateListGenerated[i].title
- }))}
- />
-
-
-
-
+
+
+ ({
+ value: TemplateListGenerated[i].key,
+ label: TemplateListGenerated[i].title
+ }))}
+ />
+
+
+ ({
+ value: TemplateListGenerated[i].key,
+ label: TemplateListGenerated[i].title
+ }))}
+ />
+
+
+
+
+
+
+
+
-
-
-
- {(fields, { add, remove, move }) => {
- return (
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ }}
+ >
+ {t("bodyshop.actions.add_intake_checklist_item")}
+
+ ]}
+ >
- {fields.map((field, index) => (
-
-
-
+ ) : (
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("jobs.fields.intake.name")}
+
+
+
+
+
+
+
{t("jobs.fields.intake.required")}
+
+
+
+
+
}
- ]}
- >
-
-
-
-
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
}
- ]}
- >
- ({ value: i, label: i }))} />
-
+ >
+
+ ({ value: i, label: i }))} />
+
+
+
+
-
-
+
+ {() => {
+ if (form.getFieldValue(["intakechecklist", "form", index, "type"]) !== "slider")
+ return null;
+ return (
+ <>
+
+
+
+
+
+
+ >
+ );
+ }}
+
+
-
-
- {() => {
- if (form.getFieldValue(["deliverchecklist", "form", index, "type"]) !== "slider") return null;
- return (
- <>
-
-
-
-
-
-
- >
- );
- }}
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
+ );
+ })
+ )}
- );
- }}
-
-
-
-
- ({
- value: TemplateListGenerated[i].key,
- label: TemplateListGenerated[i].title
- }))}
- />
-
-
-
-
-
+
+ );
+ }}
+
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ }}
+ >
+ {t("bodyshop.actions.add_delivery_checklist_item")}
+
+ ]}
+ >
+
+ {fields.length === 0 ? (
+
+ ) : (
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("jobs.fields.intake.name")}
+
+
+
+
+
+
+
{t("jobs.fields.intake.required")}
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+ ({ value: i, label: i }))} />
+
+
+
+
+
+
+
+ {() => {
+ if (form.getFieldValue(["deliverchecklist", "form", index, "type"]) !== "slider")
+ return null;
+ return (
+ <>
+
+
+
+
+
+
+ >
+ );
+ }}
+
+
+
+ );
+ })
+ )}
+
+
+ );
+ }}
+
);
}
diff --git a/client/src/components/shop-info/shop-info.laborrates.component.jsx b/client/src/components/shop-info/shop-info.laborrates.component.jsx
index e4ec950fe..fccdaf73a 100644
--- a/client/src/components/shop-info/shop-info.laborrates.component.jsx
+++ b/client/src/components/shop-info/shop-info.laborrates.component.jsx
@@ -3,344 +3,392 @@ import { Button, Form, Input, Space } from "antd";
import { useTranslation } from "react-i18next";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
+import InlineValidatedFormRow from "../layout-form-row/inline-validated-form-row.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
+import {
+ INLINE_TITLE_GROUP_STYLE,
+ INLINE_TITLE_HANDLE_STYLE,
+ INLINE_TITLE_INPUT_STYLE,
+ INLINE_TITLE_LABEL_STYLE,
+ INLINE_TITLE_ROW_STYLE,
+ InlineTitleListIcon
+} from "../layout-form-row/inline-form-row-title.utils.js";
export default function ShopInfoLaborRates() {
const { t } = useTranslation();
+ const form = Form.useFormInstance();
return (
<>
-
+
-
+
-
-
- {(fields, { add, remove, move }) => {
- return (
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ }}
+ >
+ {t("bodyshop.actions.newlaborrate")}
+
+ ]}
+ >
- {fields.map((field, index) => (
-
-
-
+ ) : (
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("jobs.fields.labor_rate_desc")}
+
+
+
+
+
}
- ]}
- >
-
-
-
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
}
- ]}
- >
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{
- required: true
- //message: t("general.validation.required"),
+ //
+ //
+ //
+ //
+ //
+ //
}
- ]}
- >
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- //
- //
- //
- //
- //
- //
- }
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("bodyshop.actions.newlaborrate")}
-
-
+ );
+ })
+ )}
- );
- }}
-
-
+
+ );
+ }}
+
>
);
}
diff --git a/client/src/components/shop-info/shop-info.notifications-autoadd.component.jsx b/client/src/components/shop-info/shop-info.notifications-autoadd.component.jsx
index 45a8ef838..3647cc95c 100644
--- a/client/src/components/shop-info/shop-info.notifications-autoadd.component.jsx
+++ b/client/src/components/shop-info/shop-info.notifications-autoadd.component.jsx
@@ -1,6 +1,7 @@
import { Form, Typography } from "antd";
import { useTranslation } from "react-i18next";
import EmployeeSearchSelectComponent from "../employee-search-select/employee-search-select.component.jsx";
+import LayoutFormRow from "../layout-form-row/layout-form-row.component";
const { Text, Paragraph } = Typography;
@@ -11,43 +12,45 @@ export default function ShopInfoNotificationsAutoadd({ bodyshop }) {
const employeeOptions = bodyshop?.employees?.filter((e) => e.active && e.user_email && e.id) || [];
return (
-
-
{t("bodyshop.fields.notifications.description")}
-
{t("bodyshop.labels.notifications.followers")}
- {employeeOptions.length > 0 ? (
-
(value || []).filter((id) => typeof id === "string" && id.trim() !== "")}
- name="notification_followers"
- rules={[
- {
- type: "array",
- message: t("general.validation.array")
- },
- {
- validator: async (_, value) => {
- if (!value || value.length === 0) {
- return Promise.resolve(); // Allow empty array
+
+
+
{t("bodyshop.fields.notifications.description")}
+
{t("bodyshop.labels.notifications.followers")}
+ {employeeOptions.length > 0 ? (
+
(value || []).filter((id) => typeof id === "string" && id.trim() !== "")}
+ name="notification_followers"
+ rules={[
+ {
+ type: "array",
+ message: t("general.validation.array")
+ },
+ {
+ validator: async (_, value) => {
+ if (!value || value.length === 0) {
+ return Promise.resolve(); // Allow empty array
+ }
+ const hasInvalid = value.some((id) => id == null || typeof id !== "string" || id.trim() === "");
+ if (hasInvalid) {
+ return Promise.reject(new Error(t("bodyshop.fields.notifications.invalid_followers")));
+ }
+ return Promise.resolve();
}
- const hasInvalid = value.some((id) => id == null || typeof id !== "string" || id.trim() === "");
- if (hasInvalid) {
- return Promise.reject(new Error(t("bodyshop.fields.notifications.invalid_followers")));
- }
- return Promise.resolve();
}
- }
- ]}
- >
-
-
- ) : (
-
{t("bodyshop.fields.no_employees_available")}
- )}
-
+ ]}
+ >
+
+
+ ) : (
+
{t("bodyshop.fields.no_employees_available")}
+ )}
+
+
);
}
diff --git a/client/src/components/shop-info/shop-info.parts-scan.jsx b/client/src/components/shop-info/shop-info.parts-scan.jsx
index 51fdbbfe4..03c55b937 100644
--- a/client/src/components/shop-info/shop-info.parts-scan.jsx
+++ b/client/src/components/shop-info/shop-info.parts-scan.jsx
@@ -3,7 +3,19 @@ import { Button, Col, Form, Input, Row, Select, Space, Switch } from "antd";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
+import InlineValidatedFormRow from "../layout-form-row/inline-validated-form-row.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
+import {
+ INLINE_TITLE_GROUP_STYLE,
+ INLINE_TITLE_HANDLE_STYLE,
+ INLINE_TITLE_INPUT_STYLE,
+ INLINE_TITLE_LABEL_STYLE,
+ INLINE_TITLE_ROW_STYLE,
+ INLINE_TITLE_SEPARATOR_STYLE,
+ INLINE_TITLE_SWITCH_GROUP_STYLE,
+ InlineTitleListIcon
+} from "../layout-form-row/inline-form-row-title.utils.js";
import i18n from "i18next";
const predefinedPartTypes = ["PAN", "PAC", "PAR", "PAL", "PAA", "PAM", "PAP", "PAS", "PASL", "PAG"];
@@ -68,195 +80,223 @@ export default function ShopInfoPartsScan({ form }) {
return (
-
-
- {(fields, { add, remove, move }) => (
+
+ {(fields, { add, remove, move }) => (
+
+ add({
+ field: "line_desc",
+ operation: "contains",
+ mark_critical: true,
+ caseInsensitive: true
+ })
+ }
+ >
+ {t("bodyshop.actions.addpartsrule")}
+
+ ]}
+ >
- {fields.map((field, index) => {
- const selectedField = watchedFields?.[index]?.field || "line_desc";
- const fieldType = getFieldType(selectedField);
+ {fields.length === 0 ? (
+
+ ) : (
+ fields.map((field, index) => {
+ const selectedField = watchedFields?.[index]?.field || "line_desc";
+ const fieldType = getFieldType(selectedField);
- return (
-
-
- {/* Select Field */}
-
-
- {
- form.setFields([
- { name: ["md_parts_scan", index, "operation"], value: "contains" },
- { name: ["md_parts_scan", index, "value"], value: undefined }
- ]);
- }}
- />
-
-
+ return (
+
+
+
+
+
{t("bodyshop.fields.md_parts_scan.field")}
+
+ {
+ form.setFields([
+ { name: ["md_parts_scan", index, "operation"], value: "contains" },
+ { name: ["md_parts_scan", index, "value"], value: undefined }
+ ]);
+ }}
+ style={{
+ width: "100%"
+ }}
+ styles={{
+ selector: INLINE_TITLE_INPUT_STYLE
+ }}
+ size="small"
+ />
+
+
+ {fieldType === "string" && (
+ <>
+
+
+
+ {t("bodyshop.fields.md_parts_scan.caseInsensitive")}
+
+
+
+
+
+ >
+ )}
+
+
+
+ {t("bodyshop.fields.md_parts_scan.mark_critical")}
+
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+ {/* Operation */}
+ {fieldType !== "predefined" && fieldType && (
+
+
+
+
+
+ )}
- {/* Operation */}
- {fieldType !== "predefined" && fieldType && (
-
-
-
-
-
- )}
+ {/* Value */}
+ {fieldType && (
+
+
+ {fieldType === "predefined" ? (
+ ({
+ label: type,
+ value: type
+ }))
+ : predefinedModLbrTypes.map((type) => ({
+ label: type,
+ value: type
+ }))
+ }
+ />
+ ) : (
+
+ )}
+
+
+ )}
- {/* Value */}
- {fieldType && (
-
-
- {fieldType === "predefined" ? (
+ {/* Update Field */}
+
+
({
- label: type,
- value: type
- }))
- : predefinedModLbrTypes.map((type) => ({
- label: type,
- value: type
- }))
+ options={fieldSelectOptions}
+ allowClear
+ onClear={() =>
+ form.setFields([{ name: ["md_parts_scan", index, "update_field"], value: null }])
}
/>
- ) : (
+
+
+
+ {/* Update Field */}
+
+
- )}
-
-
- )}
-
- {/* Case Sensitivity */}
- {fieldType === "string" && (
-
-
-
-
-
- )}
-
- {/* Mark Line as Critical */}
-
-
-
-
-
-
- {/* Update Field */}
-
-
-
- form.setFields([{ name: ["md_parts_scan", index, "update_field"], value: null }])
- }
- />
-
-
-
- {/* Update Field */}
-
-
-
-
-
-
- {/* Actions */}
-
-
- remove(field.name)} />
-
-
-
-
-
- );
- })}
-
-
-
- add({
- field: "line_desc",
- operation: "contains",
- mark_critical: true,
- caseInsensitive: true
- })
- }
- style={{ width: "100%" }}
- >
- {t("bodyshop.actions.addpartsrule")}
-
-
+
+
+
+
+
+ );
+ })
+ )}
- )}
-
-
+
+ )}
+
);
}
diff --git a/client/src/components/shop-info/shop-info.rbac.component.jsx b/client/src/components/shop-info/shop-info.rbac.component.jsx
index c0377cc17..1e24355ec 100644
--- a/client/src/components/shop-info/shop-info.rbac.component.jsx
+++ b/client/src/components/shop-info/shop-info.rbac.component.jsx
@@ -27,7 +27,7 @@ export function ShopInfoRbacComponent({ bodyshop }) {
});
return (
-
+
{[
...(HasFeatureAccess({ featureName: "export", bodyshop })
? [
diff --git a/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx b/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx
index 3a9588272..b8784a4bf 100644
--- a/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx
+++ b/client/src/components/shop-info/shop-info.responsibilitycenters.component.jsx
@@ -1,6 +1,6 @@
import { DeleteFilled } from "@ant-design/icons";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
-import { Button, DatePicker, Form, Input, InputNumber, Radio, Select, Space, Switch } from "antd";
+import { Button, Col, DatePicker, Divider, Form, Input, InputNumber, Radio, Row, Select, Space, Switch } from "antd";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
@@ -11,7 +11,20 @@ import InstanceRenderManager from "../../utils/instanceRenderMgr";
import DataLabel from "../data-label/data-label.component";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
+import { buildSectionActionButton, renderListOrEmpty } from "../layout-form-row/config-list-actions.utils.jsx";
+import InlineValidatedFormRow from "../layout-form-row/inline-validated-form-row.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
+import {
+ INLINE_TITLE_GROUP_STYLE,
+ INLINE_TITLE_HANDLE_STYLE,
+ INLINE_TITLE_INPUT_STYLE,
+ INLINE_TITLE_LABEL_STYLE,
+ INLINE_TITLE_ROW_STYLE,
+ INLINE_TITLE_SEPARATOR_STYLE,
+ INLINE_TITLE_SWITCH_GROUP_STYLE,
+ InlineTitleListIcon
+} from "../layout-form-row/inline-form-row-title.utils.js";
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
import ShopInfoResponsibilitycentersTaxesComponent from "./shop-info.responsibilitycenters.taxes.component";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
@@ -32,6 +45,9 @@ export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoResponsibili
export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
const { t } = useTranslation();
+ const taxAccountRowCol = { xs: 24, sm: 12, md: 12, lg: 6, xl: 6, xxl: 6 };
+ const taxAccountFullRowCol = { xs: 24 };
+ const dmsPayers = Form.useWatch(["cdk_configuration", "payers"], form) || [];
const hasDMSKey = bodyshopHasDmsKey(bodyshop);
@@ -66,240 +82,21 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
};
const ReceivableCustomFieldSelect = (
-
+
);
return (
- {[
- ...(HasFeatureAccess({ featureName: "export", bodyshop })
- ? !hasDMSKey
- ? [
-
-
- ,
- InstanceRenderManager({
- imex: (
-
- {() => (
-
-
-
- )}
-
- )
- }),
-
-
- ,
-
-
- 2
- 3
-
- ,
-
- {() => {
- return (
-
-
- {t("bodyshop.labels.2tiername")}
- {t("bodyshop.labels.2tiersource")}
-
-
- );
- }}
- ,
-
-
- ,
-
-
- ,
-
- {ReceivableCustomFieldSelect}
- ,
-
- {ReceivableCustomFieldSelect}
- ,
-
- {ReceivableCustomFieldSelect}
- ,
- {
- return {
- required: getFieldValue("enforce_class"),
- //message: t("general.validation.required"),
- type: "array"
- };
- }
- ]}
- >
-
- ,
-
-
- ,
-
-
-
- ]
- : []
- : []),
-
-
- ,
-
-
- ,
- InstanceRenderManager({
- imex: (
-
-
-
- )
- }),
-
-
- ,
- ...(HasFeatureAccess({ featureName: "bills", bodyshop })
- ? [
- InstanceRenderManager({
- imex: (
-
-
-
- )
- }),
-
-
- ,
-
-
-
- ]
- : []),
+ <>
- ,
- ...(HasFeatureAccess({ featureName: "timetickets", bodyshop })
- ? [
+
+
+
+
+
-
- ,
-
-
+
- ]
- : []),
- ...(HasFeatureAccess({ featureName: "bills", bodyshop })
- ? [
+
+
-
- ,
-
-
+
- ]
- : []),
- ...(HasFeatureAccess({ featureName: "export", bodyshop })
- ? [
- ...(ClosingPeriod.treatment === "on"
- ? [
-
-
+
+ {InstanceRenderManager({
+ imex: (
+
+
+
+
+
+ )
+ })}
+
+
+
+
+
+ {HasFeatureAccess({ featureName: "export", bodyshop }) &&
+ ClosingPeriod.treatment === "on" && (
+
+
+
+
+
+ )}
+ {HasFeatureAccess({ featureName: "export", bodyshop }) &&
+ ADPPayroll.treatment === "on" && (
+
+
+
+
+
+ )}
+ {HasFeatureAccess({ featureName: "export", bodyshop }) &&
+ ADPPayroll.treatment === "on" && (
+
+
+
+
+
+ )}
+ {HasFeatureAccess({ featureName: "export", bodyshop }) && !hasDMSKey && (
+ <>
+
+
+
+ 2
+ 3
+
+
+
+
+
+ {() => {
+ return (
+
+
+ {t("bodyshop.labels.2tiername")}
+ {t("bodyshop.labels.2tiersource")}
+
+
+ );
+ }}
+
+
+
+ {
+ return {
+ required: getFieldValue("enforce_class"),
+ //message: t("general.validation.required"),
+ type: "array"
+ };
+ }
+ ]}
+ >
+
+
+
+ >
+ )}
+
+
+
+
+
+ {HasFeatureAccess({ featureName: "export", bodyshop }) && !hasDMSKey && (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+ {HasFeatureAccess({ featureName: "timetickets", bodyshop }) && (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+ {HasFeatureAccess({ featureName: "bills", bodyshop }) && (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+ {HasFeatureAccess({ featureName: "export", bodyshop }) && !hasDMSKey && (
+
}>
+
+ {t("bodyshop.labels.qbo")}
+
+
- ]
- : []),
- ...(ADPPayroll.treatment === "on"
- ? [
-
-
-
- ]
- : []),
- ...(ADPPayroll.treatment === "on"
- ? [
-
-
-
- ]
- : [])
- ]
- : [])
- ]}
+
+ {InstanceRenderManager({
+ imex: (
+
+ {t("bodyshop.labels.qbo_usa")}
+
+ {() => (
+
+
+
+ )}
+
+
+ )
+ })}
+
+ }
+ >
+
+
+
+
+ {ReceivableCustomFieldSelect}
+
+
+ {ReceivableCustomFieldSelect}
+
+
+ {ReceivableCustomFieldSelect}
+
+
+ )}
+
+ {HasFeatureAccess({ featureName: "bills", bodyshop }) && (
+
+ {InstanceRenderManager({
+ imex: (
+
+
+
+ )
+ })}
+
+
+
+
+
+
+
+ )}
+
+ >
{hasDMSKey && (
- <>
-
- {bodyshop.rr_dealerid && (
- {form.getFieldValue("rr_dealerid")}
- )}
- {bodyshop.cdk_dealerid && (
-
- {form.getFieldValue("cdk_dealerid")}
-
- )}
- {bodyshop.pbs_serialnumber && (
-
- {form.getFieldValue("pbs_serialnumber")}
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {bodyshop.pbs_serialnumber && (
+
+
+
+ {bodyshop.rr_dealerid && (
+
+ {form.getFieldValue("rr_dealerid")}
+
+ )}
+ {bodyshop.cdk_dealerid && (
+
+ {form.getFieldValue("cdk_dealerid")}
+
+ )}
+ {bodyshop.pbs_serialnumber && (
+
+ {form.getFieldValue("pbs_serialnumber")}
+
+ )}
+
+
-
+
- )}
- {bodyshop.pbs_serialnumber && (
-
+
- )}
- {bodyshop.pbs_serialnumber && (
-
+
- )}
- {bodyshop.pbs_serialnumber && (
-
+
- )}
- {bodyshop.pbs_serialnumber && (
-
-
+
+
- )}
-
+ {bodyshop.pbs_serialnumber && (
+
+
+
+ )}
+ {bodyshop.pbs_serialnumber && (
+
+
+
+ )}
+ {bodyshop.pbs_serialnumber && (
+
+
+
+ )}
+ {bodyshop.pbs_serialnumber && (
+
+
+
+ )}
+ {bodyshop.pbs_serialnumber && (
+
+
+
+ )}
+
- {!bodyshop.rr_dealerid && (
- <>
-
+ {!bodyshop.rr_dealerid && (
+ <>
{(fields, { add, remove, move }) => {
return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
-
+ {
+ add();
+ })
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("jobs.actions.addpayer"), () =>
+ fields.map((field, index) => {
+ const dmsPayer = dmsPayers[field.name] || {};
+
+ return (
+
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+ );
+ })
+ )}
+
+
);
}}
-
-
{(fields, { add, remove }) => {
return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
- ))}
-
- {
+ {
add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
-
+ }
+ )
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.add_control_number"), () =>
+ fields.map((field, index) => (
+
+
+
+
+
+
+
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ ))
+ )}
+
+
);
}}
-
- >
- )}
- >
+ >
+ )}
+
+
)}
{HasFeatureAccess({ featureName: "export", bodyshop }) && (
<>
-
-
- {(fields, { add, remove, move }) => {
- return (
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
-
-
-
- >
- )}
-
- {bodyshop.cdk_dealerid && (
-
-
-
- )}
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
-
- );
- }}
-
-
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
- {!hasDMSKey && (
-
-
-
- )}
- {hasDMSKey && !bodyshop.rr_dealerid && (
-
-
-
- )}
- {bodyshop.cdk_dealerid && (
-
-
-
- )}
- {bodyshop.rr_dealerid && (
- <>
-
-
-
-
-
-
-
-
-
-
-
- >
- )}
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
-
- );
- }}
-
-
-
- {hasDMSKey && (
-
-
- {(fields, { add, remove }) => {
- return (
-
- {fields.map((field, index) => (
-
-
- 0 ? false : true}>
+ {!hasDMSKey && (
-
+
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
+ )}
+ {hasDMSKey && !bodyshop.rr_dealerid && (
+ <>
+
+
+
+
- ({ value: item, label: item }))} />
-
+ ]}
+ >
+
+
+ >
+ )}
+
+ {bodyshop.cdk_dealerid && (
({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAA`}
- name={[field.name, "costs", "LAA"]}
+ label={t("bodyshop.fields.dms.dms_control_override")}
+ key={`${index}dms_control_override`}
+ name={[field.name, "dms_control_override"]}
>
- ({ value: item, label: item }))} />
+
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAB`}
- name={[field.name, "costs", "LAB"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAD`}
- name={[field.name, "costs", "LAD"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAE`}
- name={[field.name, "costs", "LAE"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAF`}
- name={[field.name, "costs", "LAF"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAG`}
- name={[field.name, "costs", "LAG"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAM`}
- name={[field.name, "costs", "LAM"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAR`}
- name={[field.name, "costs", "LAR"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAS`}
- name={[field.name, "costs", "LAS"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LAU`}
- name={[field.name, "costs", "LAU"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LA1`}
- name={[field.name, "costs", "LA1"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LA2`}
- name={[field.name, "costs", "LA2"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LA3`}
- name={[field.name, "costs", "LA3"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-LA4`}
- name={[field.name, "costs", "LA4"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAA`}
- name={[field.name, "costs", "PAA"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAC`}
- name={[field.name, "costs", "PAC"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAG`}
- name={[field.name, "costs", "PAG"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAL`}
- name={[field.name, "costs", "PAL"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAM`}
- name={[field.name, "costs", "PAM"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAN`}
- name={[field.name, "costs", "PAN"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAO`}
- name={[field.name, "costs", "PAO"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAP`}
- name={[field.name, "costs", "PAP"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAR`}
- name={[field.name, "costs", "PAR"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PAS`}
- name={[field.name, "costs", "PAS"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-PASL`}
- name={[field.name, "costs", "PASL"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-TOW`}
- name={[field.name, "costs", "TOW"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-MAPA`}
- name={[field.name, "costs", "MAPA"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (costOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}costs-MASH`}
- name={[field.name, "costs", "MASH"]}
- >
- ({ value: item, label: item }))} />
-
-
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-ATS`}
- name={[field.name, "profits", "ATS"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAA`}
- name={[field.name, "profits", "LAA"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAB`}
- name={[field.name, "profits", "LAB"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAD`}
- name={[field.name, "profits", "LAD"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAE`}
- name={[field.name, "profits", "LAE"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAF`}
- name={[field.name, "profits", "LAF"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAG`}
- name={[field.name, "profits", "LAG"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAM`}
- name={[field.name, "profits", "LAM"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAR`}
- name={[field.name, "profits", "LAR"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAS`}
- name={[field.name, "profits", "LAS"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LAU`}
- name={[field.name, "profits", "LAU"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LA1`}
- name={[field.name, "profits", "LA1"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LA2`}
- name={[field.name, "profits", "LA2"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LA3`}
- name={[field.name, "profits", "LA3"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-LA4`}
- name={[field.name, "profits", "LA4"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAA`}
- name={[field.name, "profits", "PAA"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAC`}
- name={[field.name, "profits", "PAC"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAG`}
- name={[field.name, "profits", "PAG"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAL`}
- name={[field.name, "profits", "PAL"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAM`}
- name={[field.name, "profits", "PAM"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAN`}
- name={[field.name, "profits", "PAN"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAO`}
- name={[field.name, "profits", "PAO"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAP`}
- name={[field.name, "profits", "PAP"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAR`}
- name={[field.name, "profits", "PAR"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PAS`}
- name={[field.name, "profits", "PAS"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-PASL`}
- name={[field.name, "profits", "PASL"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-TOW`}
- name={[field.name, "profits", "TOW"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-MAPA`}
- name={[field.name, "profits", "MAPA"]}
- >
- ({ value: item, label: item }))} />
-
- ({
- validator(rule, value) {
- if (profitOptions.includes(value)) {
- return Promise.resolve();
- }
- return Promise.reject(t("bodyshop.validation.centermustexist"));
- }
- })
- ]}
- key={`${index}profits-MASH`}
- name={[field.name, "profits", "MASH"]}
- >
- ({ value: item, label: item }))} />
-
-
-
+ )}
+
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
+ );
+ })
+ )}
+
+
+ );
+ }}
+
+
+ {(fields, { add, remove, move }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.add_profit_center"), () =>
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
+ {t("bodyshop.fields.responsibilitycenter")}
+
+
+
+
+
+
+
+
+ {t("bodyshop.fields.responsibilitycenter_accountdesc")}
+
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+ {!hasDMSKey && (
+
+
+
+ )}
+ {bodyshop.rr_dealerid && (
+
+
+
+ )}
+ {hasDMSKey && !bodyshop.rr_dealerid && (
+
+
+
+ )}
+ {bodyshop.cdk_dealerid && (
+
+
+
+ )}
+ {bodyshop.rr_dealerid && [
+
+
+ ,
+
+
+
+ ]}
+
+
+ );
+ })
+ )}
+
+
+ );
+ }}
+
+
+ {hasDMSKey && (
+
+ {(fields, { add, remove }) => {
+ return (
+ {
+ add();
+ }
+ )
+ ]}
+ >
+
+ {renderListOrEmpty(fields, t("bodyshop.actions.add_dms_allocation"), () =>
+ fields.map((field, index) => {
+ const dmsDefault = form.getFieldValue([
+ "md_responsibility_centers",
+ "dms_defaults",
+ field.name
+ ]) || { name: undefined };
+
+ return (
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-ats`}
+ name={[field.name, "costs", "ATS"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAA`}
+ name={[field.name, "costs", "LAA"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAB`}
+ name={[field.name, "costs", "LAB"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAD`}
+ name={[field.name, "costs", "LAD"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAE`}
+ name={[field.name, "costs", "LAE"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAF`}
+ name={[field.name, "costs", "LAF"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAG`}
+ name={[field.name, "costs", "LAG"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAM`}
+ name={[field.name, "costs", "LAM"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAR`}
+ name={[field.name, "costs", "LAR"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAS`}
+ name={[field.name, "costs", "LAS"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LAU`}
+ name={[field.name, "costs", "LAU"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LA1`}
+ name={[field.name, "costs", "LA1"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LA2`}
+ name={[field.name, "costs", "LA2"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LA3`}
+ name={[field.name, "costs", "LA3"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-LA4`}
+ name={[field.name, "costs", "LA4"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAA`}
+ name={[field.name, "costs", "PAA"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAC`}
+ name={[field.name, "costs", "PAC"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAG`}
+ name={[field.name, "costs", "PAG"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAL`}
+ name={[field.name, "costs", "PAL"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAM`}
+ name={[field.name, "costs", "PAM"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAN`}
+ name={[field.name, "costs", "PAN"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAO`}
+ name={[field.name, "costs", "PAO"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAP`}
+ name={[field.name, "costs", "PAP"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAR`}
+ name={[field.name, "costs", "PAR"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PAS`}
+ name={[field.name, "costs", "PAS"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-PASL`}
+ name={[field.name, "costs", "PASL"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-TOW`}
+ name={[field.name, "costs", "TOW"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-MAPA`}
+ name={[field.name, "costs", "MAPA"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (costOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}costs-MASH`}
+ name={[field.name, "costs", "MASH"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-ATS`}
+ name={[field.name, "profits", "ATS"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAA`}
+ name={[field.name, "profits", "LAA"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAB`}
+ name={[field.name, "profits", "LAB"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAD`}
+ name={[field.name, "profits", "LAD"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAE`}
+ name={[field.name, "profits", "LAE"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAF`}
+ name={[field.name, "profits", "LAF"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAG`}
+ name={[field.name, "profits", "LAG"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAM`}
+ name={[field.name, "profits", "LAM"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAR`}
+ name={[field.name, "profits", "LAR"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAS`}
+ name={[field.name, "profits", "LAS"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LAU`}
+ name={[field.name, "profits", "LAU"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LA1`}
+ name={[field.name, "profits", "LA1"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LA2`}
+ name={[field.name, "profits", "LA2"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LA3`}
+ name={[field.name, "profits", "LA3"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-LA4`}
+ name={[field.name, "profits", "LA4"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAA`}
+ name={[field.name, "profits", "PAA"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAC`}
+ name={[field.name, "profits", "PAC"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAG`}
+ name={[field.name, "profits", "PAG"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAL`}
+ name={[field.name, "profits", "PAL"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAM`}
+ name={[field.name, "profits", "PAM"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAN`}
+ name={[field.name, "profits", "PAN"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAO`}
+ name={[field.name, "profits", "PAO"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAP`}
+ name={[field.name, "profits", "PAP"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAR`}
+ name={[field.name, "profits", "PAR"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PAS`}
+ name={[field.name, "profits", "PAS"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-PASL`}
+ name={[field.name, "profits", "PASL"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-TOW`}
+ name={[field.name, "profits", "TOW"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-MAPA`}
+ name={[field.name, "profits", "MAPA"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+ ({
+ validator(rule, value) {
+ if (profitOptions.includes(value)) {
+ return Promise.resolve();
+ }
+ return Promise.reject(t("bodyshop.validation.centermustexist"));
+ }
+ })
+ ]}
+ key={`${index}profits-MASH`}
+ name={[field.name, "profits", "MASH"]}
+ >
+ ({ value: item, label: item }))}
+ />
+
+
+
+
+
+ );
+ })
+ )}
- );
- }}
-
-
+
+ );
+ }}
+
)}
@@ -2921,43 +3332,110 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
)}
-
-
-
-
-
-
-
-
-
- {hasDMSKey && (
-
+
-
-
- )}
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ {hasDMSKey && (
+
+
+
+ )}
+
+
+ {InstanceRenderManager({
+ imex: (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {hasDMSKey && (
+
+
+
+ )}
+
+ ),
+ rome: null
+ })}
+
{DmsAp.treatment === "on" && (
@@ -2997,75 +3475,34 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
rules={[{ required: true }]}
name={["md_responsibility_centers", "taxes", "federal_itc", "rate"]}
>
-
+
)}
{InstanceRenderManager({
- imex: (
-
-
-
-
-
-
-
-
-
-
-
- {hasDMSKey && (
-
-
-
- )}
-
-
-
-
- ),
+ imex: null,
rome:
})}
{HasFeatureAccess({ featureName: "export", bodyshop }) && (
<>
{InstanceRenderManager({
rome: (
- <>
+
- >
+
)
})}
AR} id="AR">
@@ -3163,78 +3600,119 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
)}
-
-
- {(fields, { add, remove }) => {
- return (
+
+ {(fields, { add, remove }) => {
+ return (
+ {
+ add();
+ })
+ ]}
+ >
- {fields.map((field, index) => (
-
- 0 ? false : true}>
-
-
+ {renderListOrEmpty(fields, t("bodyshop.actions.newsalestaxcode"), () =>
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
+ {t("bodyshop.fields.responsibilitycenters.sales_tax_codes.description")}
+
+
+
+
+
+
+
+
+ {t("bodyshop.fields.responsibilitycenters.sales_tax_codes.code")}
+
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+ }
+ >
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("bodyshop.actions.newsalestaxcode")}
-
-
+ );
+ })
+ )}
- );
- }}
-
-
+
+ );
+ }}
+
>
)}
diff --git a/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx b/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx
index a947f7d1c..d742628eb 100644
--- a/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx
+++ b/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx
@@ -1,4 +1,4 @@
-import { Collapse, Divider, Form, Input, InputNumber, Space, Switch } from "antd";
+import { Col, Collapse, Form, Input, InputNumber, Row, Switch } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -6,6 +6,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { bodyshopHasDmsKey } from "../../utils/dmsUtils.js";
+import "./shop-info.responsibilitycenters.taxes.styles.scss";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -16,53 +17,102 @@ const mapDispatchToProps = () => ({
});
export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoResponsibilityCenters);
+const taxRootColProps = {
+ xs: 24,
+ sm: 12,
+ md: 8,
+ lg: { flex: "0 0 280px" },
+ xl: { flex: "0 0 240px" },
+ xxl: { flex: "0 0 300px" }
+};
+
+const taxTierFieldColProps = {
+ xs: 24,
+ sm: 12,
+ lg: 6
+};
+
export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
const { t } = useTranslation();
- //Iteratively build the form items.
- const formItems = [];
- for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
- const section = [];
+ const profileTaxCards = [];
+ for (let typeNum = 1; typeNum <= 5; typeNum++) {
+ const rootTaxItems = getRootTaxFormItems({ typeNum, bodyshop, t });
- section.push(
- TaxFormItems({
- typeNum: tyCounter,
- rootElements: true,
- bodyshop
- })
+ profileTaxCards.push(
+
+
+
+ {rootTaxItems.map((item, index) => (
+
+ {item}
+
+ ))}
+
+
+ {Array.from({ length: 5 }, (_, index) => {
+ const typeNumIterator = index + 1;
+ const tierTaxItems = getTierTaxFormItems({
+ typeNum,
+ typeNumIterator,
+ t
+ });
+
+ return (
+
+
+
+ {tierTaxItems.map((item, tierIndex) => (
+
+ {item}
+
+ ))}
+
+
+
+ );
+ })}
+
+
+
);
- for (let iterator = 1; iterator <= 5; iterator++) {
- section.push(
- TaxFormItems({
- typeNum: tyCounter,
- typeNumIterator: iterator,
- rootElements: false
- })
- );
- }
- formItems.push({section});
- formItems.push();
}
+
return (
<>
-
- {t("jobs.labels.cieca_pft")}
-
- {formItems}
+
+ {profileTaxCards}
+
-
+
+
-
+
-
+
);
}}
@@ -135,7 +185,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.cieca_pfl.lbr_adjp")}
name={["md_responsibility_centers", "cieca_pfl", "LAD", "lbr_adjp"]}
>
-
+
-
+
);
}}
@@ -208,7 +258,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.cieca_pfl.lbr_adjp")}
name={["md_responsibility_centers", "cieca_pfl", "LAE", "lbr_adjp"]}
>
-
+
-
+
);
}}
@@ -281,7 +331,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.cieca_pfl.lbr_adjp")}
name={["md_responsibility_centers", "cieca_pfl", "LAF", "lbr_adjp"]}
>
-
+
-
+
);
}}
@@ -354,7 +404,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.cieca_pfl.lbr_adjp")}
name={["md_responsibility_centers", "cieca_pfl", "LAG", "lbr_adjp"]}
>
-
+
-
+
);
}}
@@ -427,7 +477,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.cieca_pfl.lbr_adjp")}
name={["md_responsibility_centers", "cieca_pfl", "LAM", "lbr_adjp"]}
>
-
+
-
+
);
}}
@@ -500,7 +550,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.cieca_pfl.lbr_adjp")}
name={["md_responsibility_centers", "cieca_pfl", "LAR", "lbr_adjp"]}
>
-
+
-
+
);
}}
@@ -573,7 +623,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.cieca_pfl.lbr_adjp")}
name={["md_responsibility_centers", "cieca_pfl", "LAS", "lbr_adjp"]}
>
-
+
-
+
);
}}
@@ -740,7 +790,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.materials.mat_adjp")}
name={["md_responsibility_centers", "cieca_pfm", "MAPA", "mat_adjp"]}
>
-
+
-
+
);
}}
@@ -825,7 +875,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
label={t("jobs.fields.materials.mat_adjp")}
name={["md_responsibility_centers", "cieca_pfm", "MASH", "mat_adjp"]}
>
-
+
-
+
);
}}
@@ -893,15 +943,15 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
- >
- )
- },
- {
- key: "cieca_pfo",
- label: t("jobs.labels.cieca_pfo"),
- forceRender: true,
- children: (
- <>
+ >
+ )
+ },
+ {
+ key: "cieca_pfo",
+ label: t("jobs.labels.cieca_pfo"),
+ forceRender: true,
+ children: (
+ <>
- >
- )
- }
- ]}
- />
+ >
+ )
+ }
+ ]}
+ />
+
>
);
}
-function TaxFormItems({ typeNum, typeNumIterator, rootElements, bodyshop }) {
- const { t } = useTranslation();
-
- if (rootElements)
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {bodyshopHasDmsKey(bodyshop) && (
+function getRootTaxFormItems({ typeNum, bodyshop, t }) {
+ return [
+
+
+ ,
+
+
+ ,
+
+
+ ,
+
+
+ ,
+ ...(bodyshopHasDmsKey(bodyshop)
+ ? [
- )}
- >
- );
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
+ ]
+ : [])
+ ];
+}
+
+function getTierTaxFormItems({ typeNum, typeNumIterator, t }) {
+ return [
+
+
+ ,
+
+
+ ,
+
+
+ ,
+
+
+
+ ];
}
diff --git a/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.styles.scss b/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.styles.scss
new file mode 100644
index 000000000..5cbfe7f95
--- /dev/null
+++ b/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.styles.scss
@@ -0,0 +1,25 @@
+.responsibility-centers-tax-tier-grid__col.ant-col {
+ flex: 0 0 100%;
+ max-width: 100%;
+}
+
+@media (min-width: 992px) {
+ .responsibility-centers-tax-tier-grid__col.ant-col {
+ flex: 0 0 50%;
+ max-width: 50%;
+ }
+}
+
+@media (min-width: 1600px) {
+ .responsibility-centers-tax-tier-grid__col.ant-col {
+ flex: 0 0 25%;
+ max-width: 25%;
+ }
+}
+
+@media (min-width: 2400px) {
+ .responsibility-centers-tax-tier-grid__col.ant-col {
+ flex: 0 0 20%;
+ max-width: 20%;
+ }
+}
diff --git a/client/src/components/shop-info/shop-info.roguard.component.jsx b/client/src/components/shop-info/shop-info.roguard.component.jsx
index a8b6e983e..66638a9f5 100644
--- a/client/src/components/shop-info/shop-info.roguard.component.jsx
+++ b/client/src/components/shop-info/shop-info.roguard.component.jsx
@@ -21,7 +21,7 @@ export default function ShopInfoRoGuard({ form }) {
{() => {
const disabled = !form.getFieldValue(["md_ro_guard", "enabled"]);
return (
-
+
-
+
[...new Set((statuses || []).map((item) => item?.trim()).filter(Boolean))];
+
+const getTranslatedDragRect = (active, delta) => {
+ const rect = active?.rect?.current?.initial || active?.rect?.current?.translated;
+
+ if (!rect) return null;
+
+ const x = delta?.x || 0;
+ const y = delta?.y || 0;
+
+ return {
+ left: rect.left + x,
+ right: rect.right + x,
+ top: rect.top + y,
+ bottom: rect.bottom + y,
+ width: rect.width,
+ height: rect.height
+ };
+};
+
+const isPointWithinRect = (point, rect) => {
+ if (!point || !rect) return false;
+
+ return point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom;
+};
+
+const DraggableStatusTag = ({ label, value, closable, onClose }) => {
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
+ id: value
+ });
+ const labelText = String(label ?? value);
+
+ return (
+ {
+ event.stopPropagation();
+ }}
+ onClick={(event) => {
+ event.stopPropagation();
+ }}
+ {...attributes}
+ {...listeners}
+ >
+ {
+ if (event.target.closest(".ant-select-selection-item-remove")) {
+ event.stopPropagation();
+ return;
+ }
+
+ event.preventDefault();
+ event.stopPropagation();
+ }}
+ onClick={(event) => {
+ if (event.target.closest(".ant-select-selection-item-remove")) {
+ event.stopPropagation();
+ return;
+ }
+
+ event.stopPropagation();
+ }}
+ title={labelText}
+ >
+
+
+
+ {labelText}
+ {closable ? (
+ {
+ event.stopPropagation();
+ onClose?.(event);
+ }}
+ onMouseDown={(event) => {
+ event.stopPropagation();
+ }}
+ >
+
+
+ ) : null}
+
+
+ );
+};
+
+const SortableStatusesSelect = ({ value, onChange, mode = "tags", options = [] }) => {
+ const statuses = normalizeStatuses(value);
+ const isTagsMode = mode === "tags";
+ const [knownStatuses, setKnownStatuses] = useState(statuses);
+ const selectWrapperRef = useRef(null);
+ const dragRectRef = useRef(null);
+ const tagSensors = useSensors(
+ useSensor(PointerSensor, {
+ activationConstraint: {
+ distance: 6
+ }
+ })
+ );
+
+ const handleStatusesChange = (nextValues) => {
+ const normalizedNextValues = normalizeStatuses(nextValues);
+ if (isTagsMode) {
+ setKnownStatuses((currentKnownStatuses) => normalizeStatuses([...currentKnownStatuses, ...normalizedNextValues]));
+ }
+ onChange?.(normalizedNextValues);
+ };
+
+ useEffect(() => {
+ if (isTagsMode) {
+ setKnownStatuses((currentKnownStatuses) => normalizeStatuses([...currentKnownStatuses, ...statuses]));
+ }
+ }, [isTagsMode, statuses]);
+
+ const shouldMoveStatusToEnd = (activeId, dragRect) => {
+ const selectRect =
+ selectWrapperRef.current?.querySelector?.(".ant-select-selector")?.getBoundingClientRect?.() ||
+ selectWrapperRef.current?.getBoundingClientRect?.();
+ if (!dragRect || !selectRect) return false;
+
+ const dragLeadingPoint = {
+ x: dragRect.left,
+ y: dragRect.top
+ };
+ const dragTrailingPoint = {
+ x: dragRect.right,
+ y: dragRect.bottom
+ };
+
+ if (!isPointWithinRect(dragLeadingPoint, selectRect) && !isPointWithinRect(dragTrailingPoint, selectRect)) {
+ return false;
+ }
+
+ const trailingStatus = statuses.filter((status) => status !== activeId).at(-1);
+ if (!trailingStatus) return false;
+
+ const trailingTagNode = selectWrapperRef.current?.querySelector?.(
+ `.job-statuses-source-tag-wrapper[data-status-tag-value="${CSS.escape(String(trailingStatus))}"]`
+ );
+ const trailingTagRect = trailingTagNode?.getBoundingClientRect?.();
+
+ if (!trailingTagRect) return false;
+
+ const isOnTrailingRow = dragRect.bottom >= trailingTagRect.top && dragRect.top <= trailingTagRect.bottom;
+ if (isOnTrailingRow) {
+ return dragRect.left >= trailingTagRect.right - 4;
+ }
+
+ return dragRect.top >= trailingTagRect.bottom - 4;
+ };
+
+ const handleStatusSortEnd = ({ active, over, delta }) => {
+ const oldIndex = statuses.indexOf(active.id);
+ const dragRect = dragRectRef.current || getTranslatedDragRect(active, delta);
+ dragRectRef.current = null;
+
+ if (oldIndex < 0) return;
+
+ if (!over) {
+ if (oldIndex !== statuses.length - 1 && shouldMoveStatusToEnd(active.id, dragRect)) {
+ onChange?.(arrayMove(statuses, oldIndex, statuses.length - 1));
+ }
+ return;
+ }
+
+ if (active.id === over.id) return;
+
+ const newIndex = statuses.indexOf(over.id);
+
+ if (newIndex < 0) return;
+
+ onChange?.(arrayMove(statuses, oldIndex, newIndex));
+ };
+
+ const renderStatusTag = ({ label, value: tagValue, closable, onClose }) => {
+ return ;
+ };
+
+ const statusSelectOptions = isTagsMode
+ ? knownStatuses.map((status) => ({
+ value: status,
+ label: status
+ }))
+ : options;
+
+ if (statuses.length === 0) {
+ return (
+
+ );
+ }
+
+ return (
+
+ {
+ dragRectRef.current = null;
+ }}
+ onDragEnd={handleStatusSortEnd}
+ onDragMove={({ active, delta }) => {
+ dragRectRef.current = getTranslatedDragRect(active, delta);
+ }}
+ sensors={tagSensors}
+ >
+
+
+
+
+
+ );
+};
+
export function ShopInfoROStatusComponent({ bodyshop, form }) {
const { t } = useTranslation();
+ const allStatuses = normalizeStatuses(Form.useWatch(["md_ro_statuses", "statuses"], form));
+ const productionStatuses = Form.useWatch(["md_ro_statuses", "production_statuses"], form) || [];
+ const additionalBoardStatuses = Form.useWatch(["md_ro_statuses", "additional_board_statuses"], form) || [];
+ const productionColors = Form.useWatch(["md_ro_statuses", "production_colors"], form) || [];
+ const statusOptions = allStatuses;
+ const statusSelectOptions = statusOptions.map((item) => ({ value: item, label: item }));
+ const availableProductionStatuses = [...new Set([...productionStatuses, ...additionalBoardStatuses].filter(Boolean))];
const {
treatments: { Production_List_Status_Colors }
@@ -37,117 +375,119 @@ export function ShopInfoROStatusComponent({ bodyshop, form }) {
splitKey: bodyshop.imexshopid
});
- const [options, setOptions] = useState(form.getFieldValue(["md_ro_statuses", "statuses"]) || []);
-
- const [productionStatus, setProductionStatus] = useState(
- (form.getFieldValue(["md_ro_statuses", "production_statuses"]) || []).concat(
- form.getFieldValue(["md_ro_statuses", "additional_board_statuses"]) || []
- ) || []
- );
-
- const handleBlur = () => {
- setOptions(form.getFieldValue(["md_ro_statuses", "statuses"]));
- setProductionStatus(
- form
- .getFieldValue(["md_ro_statuses", "production_statuses"])
- .concat(form.getFieldValue(["md_ro_statuses", "additional_board_statuses"]))
- );
- };
-
return (
-
-
-
-
- ({ value: item, label: item }))} />
-
-
- ({ value: item, label: item }))} />
-
-
- ({ value: item, label: item }))} />
-
-
- ({ value: item, label: item }))} />
-
-
- ({ value: item, label: item }))} />
-
-
- ({ value: item, label: item }))} />
-
-
+
+
+
{
+ const populatedStatuses = normalizeStatuses(value);
+
+ if (populatedStatuses.length === 0) {
+ return Promise.reject(
+ new Error(
+ t("general.validation.required", {
+ label: t("bodyshop.labels.alljobstatuses")
+ })
+ )
+ );
+ }
+
+ if (populatedStatuses.length !== (value || []).filter(Boolean).length) {
+ return Promise.reject(new Error(t("bodyshop.errors.duplicate_job_status")));
+ }
+ }
+ }
+ ]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- ({ value: item, label: item }))} />
+
- ({ value: item, label: item }))} />
+
- ({ value: item, label: item }))} />
+
- ({ value: item, label: item }))} />
+
- ({ value: item, label: item }))} />
+
- ({ value: item, label: item }))} />
+
- ({ value: item, label: item }))} />
+
- ({ value: item, label: item }))} />
+
{Production_List_Status_Colors.treatment === "on" && (
-
-
- {(fields, { add, remove }) => {
- return (
+
+ {(fields, { add, remove }) => {
+ return (
+ {
+ add({
+ color: { ...DEFAULT_TRANSLUCENT_CARD_COLOR }
+ });
+ }}
+ >
+ {t("bodyshop.actions.add_production_status_color")}
+
+ ]}
+ >
-
- {fields.map((field, index) => (
-
-
-
-
- ({ value: item, label: item }))} />
-
- {
- remove(field.name);
- }}
- />
-
-
+ ) : (
+
+ {fields.map((field, index) => {
+ const productionColor = productionColors[field.name] || {};
+ const productionColorSurfaceStyles = getTintedCardSurfaceStyles(productionColor.color);
+ const selectedProductionColorStatuses = productionColors
+ .map((item) => item?.status)
+ .filter(Boolean);
+ const productionColorStatusOptions = [
+ ...new Set([productionColor.status, ...availableProductionStatuses])
+ ]
+ .filter(Boolean)
+ .filter(
+ (status) =>
+ status === productionColor.status || !selectedProductionColorStatuses.includes(status)
+ );
+
+ return (
+
+ ({
+ value: item,
+ label: item
+ }))}
+ />
+
+ }
+ extra={
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+ }
+ {...productionColorSurfaceStyles}
+ style={{ width: 260, marginBottom: 0 }}
>
-
-
-
-
- ))}
-
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("general.actions.add")}
-
-
+
+
+
+
+
+
+ );
+ })}
+
+ )}
- );
- }}
-
-
+
+ );
+ }}
+
)}
);
diff --git a/client/src/components/shop-info/shop-info.scheduling.component.jsx b/client/src/components/shop-info/shop-info.scheduling.component.jsx
index f5d6026df..bbe0a1af2 100644
--- a/client/src/components/shop-info/shop-info.scheduling.component.jsx
+++ b/client/src/components/shop-info/shop-info.scheduling.component.jsx
@@ -1,5 +1,5 @@
-import { DeleteFilled } from "@ant-design/icons";
-import { Button, Divider, Form, Input, InputNumber, Select, Space, Switch, TimePicker } from "antd";
+import { DeleteFilled, ReloadOutlined } from "@ant-design/icons";
+import { Button, Col, Form, Input, InputNumber, Row, Select, Space, Switch, TimePicker, Tooltip } from "antd";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -7,8 +7,16 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
+import InlineValidatedFormRow from "../layout-form-row/inline-validated-form-row.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { ColorPicker } from "./shop-info.rostatus.component";
+import {
+ DEFAULT_TRANSLUCENT_CARD_COLOR,
+ DEFAULT_TRANSLUCENT_PICKER_COLOR,
+ getTintedCardSurfaceStyles
+} from "./shop-info.color.utils";
+import "./shop-info.scheduling.styles.scss";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -17,301 +25,514 @@ const mapDispatchToProps = () => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
+const WORKING_DAYS = [
+ { key: "sunday", labelKey: "general.labels.sunday" },
+ { key: "monday", labelKey: "general.labels.monday" },
+ { key: "tuesday", labelKey: "general.labels.tuesday" },
+ { key: "wednesday", labelKey: "general.labels.wednesday" },
+ { key: "thursday", labelKey: "general.labels.thursday" },
+ { key: "friday", labelKey: "general.labels.friday" },
+ { key: "saturday", labelKey: "general.labels.saturday" }
+];
+
+const APPOINTMENT_COLOR_PICKER_STYLES = {
+ default: {
+ wrap: {
+ display: "flex",
+ flexWrap: "wrap",
+ gap: "12px",
+ alignItems: "flex-start"
+ },
+ hue: {
+ flex: "1 1 180px",
+ height: "12px",
+ position: "relative",
+ marginTop: "20px"
+ },
+ swatches: {
+ flex: "1 1 160px"
+ }
+ }
+};
+
+const SCHEDULING_BUCKET_COLOR_PICKER_STYLES = {
+ default: {
+ picker: {
+ width: "100%",
+ height: "100%",
+ background: "color-mix(in srgb, var(--imex-form-surface) 92%, transparent)",
+ boxShadow: "none",
+ border: "1px solid color-mix(in srgb, var(--imex-form-surface-border) 72%, transparent)",
+ borderRadius: "8px",
+ boxSizing: "border-box",
+ overflow: "hidden"
+ },
+ saturation: {
+ width: "100%",
+ paddingBottom: "48%",
+ position: "relative",
+ borderRadius: "8px 8px 0 0",
+ overflow: "hidden"
+ },
+ body: {
+ padding: "12px"
+ },
+ controls: {
+ display: "flex",
+ gap: "10px"
+ },
+ color: {
+ width: "28px"
+ },
+ swatch: {
+ marginTop: "0",
+ width: "12px",
+ height: "12px",
+ borderRadius: "999px"
+ },
+ toggles: {
+ flex: "1"
+ },
+ hue: {
+ height: "10px",
+ position: "relative",
+ marginBottom: "8px"
+ },
+ alpha: {
+ height: "10px",
+ position: "relative"
+ }
+ }
+};
+
+const SECTION_TITLE_INPUT_STYLE = {
+ background: "color-mix(in srgb, var(--imex-form-surface) 78%, transparent)",
+ border: "1px solid color-mix(in srgb, var(--imex-form-surface-border) 72%, transparent)",
+ borderRadius: 6,
+ fontWeight: 500
+};
+
+const SECTION_TITLE_INPUT_ROW_STYLE = {
+ display: "flex",
+ gap: 8,
+ flexWrap: "wrap",
+ alignItems: "center",
+ minWidth: 180,
+ maxWidth: "100%"
+};
+
+const SECTION_TITLE_INPUT_GROUP_STYLE = {
+ display: "flex",
+ alignItems: "center",
+ gap: 6,
+ minWidth: 0
+};
+
+const SECTION_TITLE_INPUT_LABEL_STYLE = {
+ fontSize: 12,
+ lineHeight: 1.1,
+ opacity: 0.75,
+ whiteSpace: "nowrap"
+};
+
export function ShopInfoSchedulingComponent({ form, bodyshop }) {
const { t } = useTranslation();
+ const appointmentColors = Form.useWatch(["appt_colors"], form) || form.getFieldValue(["appt_colors"]) || [];
+ const schedulingBuckets = Form.useWatch(["ssbuckets"], form) || form.getFieldValue(["ssbuckets"]) || [];
return (
+
+ );
+ }}
+
+ {HasFeatureAccess({ featureName: "smartscheduling", bodyshop }) && (
+
{(fields, { add, remove, move }) => {
return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
+ {
- add();
+ add({
+ color: { ...DEFAULT_TRANSLUCENT_CARD_COLOR }
+ });
}}
- style={{ width: "100%" }}
>
- {t("bodyshop.actions.addapptcolor")}
+ {t("bodyshop.actions.addbucket")}
-
-
+ ]}
+ >
+
+ {fields.length === 0 ? (
+
+ ) : (
+ fields.map((field, index) => {
+ const schedulingBucket =
+ schedulingBuckets[field.name] || form.getFieldValue(["ssbuckets", field.name]) || {};
+ const schedulingBucketSurfaceStyles = getTintedCardSurfaceStyles(schedulingBucket.color);
+
+ return (
+
+
+
+
{t("bodyshop.fields.ssbuckets.id")}
+
+
+
+
+
+
+ {t("bodyshop.fields.ssbuckets.label")}
+
+
+
+
+
+
+ }
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+ }
+ onClick={() => {
+ form.setFieldValue(["ssbuckets", field.name, "color"]);
+
+ form.setFields([
+ {
+ name: ["ssbuckets", field.name, "color"],
+ touched: true
+ }
+ ]);
+ }}
+ />
+
+
+
+ }
+ {...schedulingBucketSurfaceStyles}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ })
+ )}
+
+
);
}}
-
- {HasFeatureAccess({ featureName: "smartscheduling", bodyshop }) && (
-
-
- {(fields, { add, remove, move }) => {
- return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {t("bodyshop.fields.ssbuckets.color")}
- {
- form.setFieldValue(["ssbuckets", field.name, "color"]);
-
- form.setFields([
- {
- name: ["ssbuckets", field.name, "color"],
- touched: true
- }
- ]);
- }}
- >
- Reset
-
-
- }
- key={`${index}color`}
- name={[field.name, "color"]}
- >
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
-
- ))}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("bodyshop.actions.addbucket")}
-
-
-
- );
- }}
-
-
)}
);
diff --git a/client/src/components/shop-info/shop-info.scheduling.styles.scss b/client/src/components/shop-info/shop-info.scheduling.styles.scss
new file mode 100644
index 000000000..b04a92e15
--- /dev/null
+++ b/client/src/components/shop-info/shop-info.scheduling.styles.scss
@@ -0,0 +1,58 @@
+.shop-info-scheduling__bucket-card-body {
+ display: flex;
+ gap: 12px;
+ align-items: stretch;
+}
+
+.shop-info-scheduling__bucket-card-fields {
+ flex: 1 1 0;
+ min-width: 0;
+ display: grid;
+ grid-template-columns: repeat(3, minmax(92px, 1fr));
+ gap: 0 12px;
+}
+
+.shop-info-scheduling__bucket-card-fields .ant-form-item {
+ margin-bottom: 10px;
+}
+
+.shop-info-scheduling__bucket-card-color {
+ flex: 0 0 360px;
+ min-width: 360px;
+ max-width: 360px;
+ display: flex;
+ align-items: stretch;
+}
+
+.shop-info-scheduling__bucket-card-color .ant-form-item {
+ margin-bottom: 0;
+ width: 100%;
+}
+
+.shop-info-scheduling__bucket-card-color .ant-form-item-control,
+.shop-info-scheduling__bucket-card-color .ant-form-item-control-input,
+.shop-info-scheduling__bucket-card-color .ant-form-item-control-input-content {
+ height: 100%;
+}
+
+@media (max-width: 1199px) {
+ .shop-info-scheduling__bucket-card-body {
+ flex-direction: column;
+ }
+
+ .shop-info-scheduling__bucket-card-fields {
+ grid-template-columns: repeat(2, minmax(120px, 1fr));
+ }
+
+ .shop-info-scheduling__bucket-card-color {
+ flex-basis: auto;
+ min-width: 0;
+ max-width: none;
+ }
+}
+
+@media (max-width: 575px) {
+ .shop-info-scheduling__bucket-card-fields {
+ grid-template-columns: minmax(0, 1fr);
+ }
+}
diff --git a/client/src/components/shop-info/shop-info.section-navigator.component.jsx b/client/src/components/shop-info/shop-info.section-navigator.component.jsx
new file mode 100644
index 000000000..3d120c0e5
--- /dev/null
+++ b/client/src/components/shop-info/shop-info.section-navigator.component.jsx
@@ -0,0 +1,213 @@
+import { Select } from "antd";
+import { useEffect, useRef, useState } from "react";
+import { useTranslation } from "react-i18next";
+import "./shop-info.section-navigator.styles.scss";
+
+const HIGHLIGHT_CLASS = "shop-info-section-navigator__target--active";
+
+export default function ShopInfoSectionNavigator({ tabsRef, activeTabKey }) {
+ const { t } = useTranslation();
+ const targetMapRef = useRef(new Map());
+ const highlightedTargetRef = useRef(null);
+ const [options, setOptions] = useState([]);
+ const [selectedSection, setSelectedSection] = useState(undefined);
+
+ useEffect(() => {
+ const tabsContainer = tabsRef.current;
+ if (!tabsContainer) return undefined;
+
+ let animationFrameId = 0;
+
+ const refreshOptions = () => {
+ const activePane = tabsContainer.querySelector(".ant-tabs-tabpane-active");
+ if (!activePane) {
+ targetMapRef.current = new Map();
+ setOptions([]);
+ return;
+ }
+
+ const nextTargetMap = new Map();
+ const nextOptions = Array.from(activePane.querySelectorAll(".imex-form-row"))
+ .filter((card) => {
+ return shouldIncludeCardInNavigator(card, activePane);
+ })
+ .map((card, index) => {
+ const { title, depth, searchLabel } = getCardNavigatorInfo(card, activePane);
+ const value = `${activeTabKey}-shop-info-section-${index}`;
+
+ nextTargetMap.set(value, card);
+
+ return {
+ label: renderNavigatorOptionLabel(title, depth),
+ labelText: title,
+ searchLabel,
+ depth,
+ value
+ };
+ });
+
+ targetMapRef.current = nextTargetMap;
+ setOptions((currentOptions) => (areOptionsEqual(currentOptions, nextOptions) ? currentOptions : nextOptions));
+ };
+
+ const scheduleRefresh = () => {
+ cancelAnimationFrame(animationFrameId);
+ animationFrameId = requestAnimationFrame(refreshOptions);
+ };
+
+ scheduleRefresh();
+
+ const observer = new MutationObserver(scheduleRefresh);
+ observer.observe(tabsContainer, {
+ childList: true,
+ subtree: true,
+ characterData: true,
+ attributes: true,
+ attributeFilter: ["class"]
+ });
+
+ return () => {
+ cancelAnimationFrame(animationFrameId);
+ observer.disconnect();
+ };
+ }, [activeTabKey, tabsRef]);
+
+ useEffect(() => {
+ clearHighlightedTarget(highlightedTargetRef);
+ setSelectedSection(undefined);
+ }, [activeTabKey]);
+
+ const handleSectionChange = (value) => {
+ setSelectedSection(value);
+
+ clearHighlightedTarget(highlightedTargetRef);
+ if (!value) return;
+
+ const target = targetMapRef.current.get(value);
+ if (target) {
+ target.classList.add(HIGHLIGHT_CLASS);
+ highlightedTargetRef.current = target;
+ target.scrollIntoView({
+ behavior: "smooth",
+ block: "start"
+ });
+ }
+
+ window.setTimeout(() => {
+ setSelectedSection(undefined);
+ }, 0);
+ };
+
+ return (
+
+ option?.searchLabel?.toLowerCase().includes(input.toLowerCase())}
+ onChange={handleSectionChange}
+ />
+
+ );
+}
+
+function getOwnCardTitleNode(card) {
+ const headNode = Array.from(card.children).find((child) => child.classList?.contains("ant-card-head"));
+ return headNode?.querySelector(".ant-card-head-title");
+}
+
+function getOwnCardTitle(card) {
+ return getOwnCardTitleNode(card)?.textContent?.trim();
+}
+
+function getAncestorCards(card, activePane) {
+ const ancestors = [];
+ let currentCard = card.parentElement?.closest(".imex-form-row");
+
+ while (currentCard && activePane.contains(currentCard)) {
+ ancestors.push(currentCard);
+ currentCard = currentCard.parentElement?.closest(".imex-form-row");
+ }
+
+ return ancestors.reverse();
+}
+
+function getCardDepth(card, activePane) {
+ return getAncestorCards(card, activePane).length;
+}
+
+function isVisibleCard(card) {
+ return card.offsetParent !== null;
+}
+
+function isNavigatorEligibleSubsection(card) {
+ return (
+ !card.classList.contains("imex-form-row--compact") &&
+ !card.classList.contains("imex-form-row--title-only") &&
+ !card.querySelector(":scope > .ant-card-actions")
+ );
+}
+
+function shouldIncludeCardInNavigator(card, activePane) {
+ const title = getOwnCardTitle(card);
+ if (!title || !isVisibleCard(card)) return false;
+
+ const depth = getCardDepth(card, activePane);
+ if (depth === 0) return true;
+ if (depth === 1) return isNavigatorEligibleSubsection(card);
+
+ return false;
+}
+
+function getCardNavigatorInfo(card, activePane) {
+ const title = getOwnCardTitle(card);
+ const ancestors = getAncestorCards(card, activePane);
+ const depth = ancestors.length;
+ const parentTitle = depth === 1 ? getOwnCardTitle(ancestors[0]) : null;
+
+ return {
+ title,
+ depth,
+ searchLabel: parentTitle ? `${parentTitle} ${title}` : title
+ };
+}
+
+function renderNavigatorOptionLabel(title, depth) {
+ return (
+ 0 ? "shop-info-section-navigator__option--subsection" : null
+ ]
+ .filter(Boolean)
+ .join(" ")}
+ >
+ {title}
+
+ );
+}
+
+function clearHighlightedTarget(highlightedTargetRef) {
+ if (highlightedTargetRef.current) {
+ highlightedTargetRef.current.classList.remove(HIGHLIGHT_CLASS);
+ highlightedTargetRef.current = null;
+ }
+}
+
+function areOptionsEqual(currentOptions, nextOptions) {
+ if (currentOptions.length !== nextOptions.length) return false;
+
+ return currentOptions.every((option, index) => {
+ const nextOption = nextOptions[index];
+ return (
+ option.labelText === nextOption.labelText &&
+ option.searchLabel === nextOption.searchLabel &&
+ option.depth === nextOption.depth &&
+ option.value === nextOption.value
+ );
+ });
+}
diff --git a/client/src/components/shop-info/shop-info.section-navigator.styles.scss b/client/src/components/shop-info/shop-info.section-navigator.styles.scss
new file mode 100644
index 000000000..ba9a1b9d0
--- /dev/null
+++ b/client/src/components/shop-info/shop-info.section-navigator.styles.scss
@@ -0,0 +1,55 @@
+.shop-info-section-navigator {
+ max-width: 360px;
+ width: min(360px, 100%);
+
+ .ant-select {
+ width: 100%;
+ }
+}
+
+.shop-info-section-navigator__option {
+ display: inline-flex;
+ align-items: center;
+ min-height: 24px;
+}
+
+.shop-info-section-navigator__option--subsection {
+ position: relative;
+ padding-left: 18px;
+}
+
+.shop-info-section-navigator__option--subsection::before {
+ content: "";
+ position: absolute;
+ left: 6px;
+ top: 50%;
+ width: 8px;
+ height: 1px;
+ background: var(--ant-colorTextDescription);
+ transform: translateY(-50%);
+}
+
+.shop-info-section-navigator__option-label {
+ display: inline-block;
+}
+
+.imex-form-row.shop-info-section-navigator__target--active.ant-card {
+ border-color: color-mix(
+ in srgb,
+ var(--ant-colorPrimary, #1890ff) 65%,
+ var(--imex-form-surface-border)
+ );
+ background: color-mix(in srgb, var(--ant-colorPrimary, #1890ff) 7%, var(--imex-form-surface));
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--ant-colorPrimary, #1890ff) 24%, transparent);
+ transition: border-color 0.2s ease,
+ background-color 0.2s ease,
+ box-shadow 0.2s ease;
+
+ .ant-card-head {
+ background: color-mix(in srgb, var(--ant-colorPrimary, #1890ff) 12%, var(--imex-form-surface-head));
+ }
+
+ .ant-card-body {
+ background: color-mix(in srgb, var(--ant-colorPrimary, #1890ff) 7%, var(--imex-form-surface));
+ }
+}
diff --git a/client/src/components/shop-info/shop-info.speedprint.component.jsx b/client/src/components/shop-info/shop-info.speedprint.component.jsx
index 08d9e816a..7dedf39c4 100644
--- a/client/src/components/shop-info/shop-info.speedprint.component.jsx
+++ b/client/src/components/shop-info/shop-info.speedprint.component.jsx
@@ -3,11 +3,23 @@ import { Button, Form, Input, Select, Space } from "antd";
import { useTranslation } from "react-i18next";
import { TemplateList } from "../../utils/TemplateConstants";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
+import InlineValidatedFormRow from "../layout-form-row/inline-validated-form-row.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
+import {
+ INLINE_TITLE_GROUP_STYLE,
+ INLINE_TITLE_HANDLE_STYLE,
+ INLINE_TITLE_INPUT_STYLE,
+ INLINE_TITLE_LABEL_STYLE,
+ INLINE_TITLE_ROW_STYLE,
+ INLINE_TITLE_SEPARATOR_STYLE,
+ InlineTitleListIcon
+} from "../layout-form-row/inline-form-row-title.utils.js";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
export default function ShopInfoSpeedPrint() {
const { t } = useTranslation();
+ const form = Form.useFormInstance();
const allTemplates = TemplateList("job");
const TemplateListGenerated = InstanceRenderManager({
imex: Object.fromEntries(Object.entries(allTemplates).filter(([, { enhanced_payroll }]) => !enhanced_payroll)),
@@ -18,80 +30,131 @@ export default function ShopInfoSpeedPrint() {
{(fields, { add, remove, move }) => {
return (
-
- {fields.map((field, index) => (
-
-
-
-
-
-
-
-
-
-
- ({
- value: TemplateListGenerated[key].key,
- label: TemplateListGenerated[key].title
- }))}
- />
-
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
-
+ {
add();
}}
- style={{ width: "100%" }}
>
{t("bodyshop.actions.addspeedprint")}
-
-
+ ]}
+ >
+
+ {fields.length === 0 ? (
+
+ ) : (
+ fields.map((field, index) => {
+ return (
+
+
+
+
+
{t("bodyshop.fields.speedprint.id")}
+
+
+
+
+
+
+
{t("bodyshop.fields.speedprint.label")}
+
+
+
+
+
+ }
+ wrapTitle
+ extra={
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
+ }
+ >
+
+ ({
+ value: TemplateListGenerated[key].key,
+ label: TemplateListGenerated[key].title
+ }))}
+ />
+
+
+
+ );
+ })
+ )}
+
+
);
}}
diff --git a/client/src/components/shop-info/shop-info.task-presets.component.jsx b/client/src/components/shop-info/shop-info.task-presets.component.jsx
index d5cf92cc2..987451f5e 100644
--- a/client/src/components/shop-info/shop-info.task-presets.component.jsx
+++ b/client/src/components/shop-info/shop-info.task-presets.component.jsx
@@ -2,6 +2,8 @@ import { DeleteFilled } from "@ant-design/icons";
import { Button, Checkbox, Col, Form, Input, InputNumber, Row, Select, Space, Switch } from "antd";
import { useTranslation } from "react-i18next";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
+import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
+import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { connect } from "react-redux";
@@ -55,10 +57,12 @@ const getTaskPresetAllocationErrors = (presets = [], t) => {
export function ShopInfoTaskPresets({ bodyshop }) {
const { t } = useTranslation();
+ const form = Form.useFormInstance();
+ const taskPresets = Form.useWatch(["md_tasks_presets", "presets"], form) || [];
return (
<>
-
+
-
- {
- const allocationErrors = getTaskPresetAllocationErrors(presets, t);
+ {
+ const allocationErrors = getTaskPresetAllocationErrors(presets, t);
- if (allocationErrors.length > 0) {
- throw new Error(allocationErrors.join(" "));
- }
+ if (allocationErrors.length > 0) {
+ throw new Error(allocationErrors.join(" "));
}
}
- ]}
- >
- {(fields, { add, remove, move }, { errors }) => {
- return (
+ }
+ ]}
+ >
+ {(fields, { add, remove, move }, { errors }) => {
+ return (
+ {
+ add();
+ }}
+ >
+ {t("bodyshop.actions.add_task_preset")}
+
+ ]}
+ >
- {fields.map((field, index) => (
-
-
-
+ ) : (
+ fields.map((field, index) => {
+ const taskPreset = taskPresets[field.name] || {};
+
+ return (
+
+
+ }
+ onClick={() => {
+ remove(field.name);
+ }}
+ />
+
+
}
- ]}
- >
-
+ >
+
+
+
+
+
+
+
+
+ {t("joblines.fields.lbr_types.LAA")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAB")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAD")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAE")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAF")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAG")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAM")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAR")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAS")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LAU")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LA1")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LA2")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LA3")}
+
+
+
+
+ {t("joblines.fields.lbr_types.LA4")}
+
+
+
+
+
+
+
+
+
+
+
+
+ ({
+ value: o,
+ label: o
+ }))}
+ />
+
+
-
-
-
-
-
- {t("joblines.fields.lbr_types.LAA")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAB")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAD")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAE")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAF")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAG")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAM")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAR")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAS")}
-
-
-
-
- {t("joblines.fields.lbr_types.LAU")}
-
-
-
-
- {t("joblines.fields.lbr_types.LA1")}
-
-
-
-
- {t("joblines.fields.lbr_types.LA2")}
-
-
-
-
- {t("joblines.fields.lbr_types.LA3")}
-
-
-
-
- {t("joblines.fields.lbr_types.LA4")}
-
-
-
-
-
-
-
-
-
-
-
-
- ({
- value: o,
- label: o
- }))}
- />
-
-
- {
- remove(field.name);
- }}
- />
-
-
-
-
- ))}
+ );
+ })
+ )}
-
- {
- add();
- }}
- style={{ width: "100%" }}
- >
- {t("bodyshop.actions.add_task_preset")}
-
-
- );
- }}
-
-
+
+ );
+ }}
+
>
);
}
diff --git a/client/src/components/shop-info/shop-intellipay-config.component.jsx b/client/src/components/shop-info/shop-intellipay-config.component.jsx
index bdbf80c02..8f8878766 100644
--- a/client/src/components/shop-info/shop-intellipay-config.component.jsx
+++ b/client/src/components/shop-info/shop-intellipay-config.component.jsx
@@ -5,6 +5,7 @@ import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
+import InstanceRenderManager from "../../utils/instanceRenderMgr";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -17,19 +18,22 @@ export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoIntellipay);
// noinspection JSUnusedLocalSymbols
export function ShopInfoIntellipay({ bodyshop, form }) {
const { t } = useTranslation();
+ const cashDiscountEnabled = Form.useWatch(["intellipay_config", "enable_cash_discount"], form);
return (
<>
-
- {() => {
- const { intellipay_config } = form.getFieldsValue();
+ {cashDiscountEnabled && (
+
+ )}
- if (intellipay_config?.enable_cash_discount)
- return ;
- }}
-
-
-
+
(payoutMethod === "commission" ? "gold" : "blue");
-
-const getEmployeeDisplayName = (employees = [], employeeId) => {
- const employee = employees.find((currentEmployee) => currentEmployee.id === employeeId);
- if (!employee) return null;
-
- const fullName = [employee.first_name, employee.last_name].filter(Boolean).join(" ").trim();
- return fullName || employee.employee_number || null;
-};
-
const formatAllocationPercentage = (percentage) => {
if (percentage === null || percentage === undefined || percentage === "") return null;
@@ -82,16 +64,19 @@ const formatAllocationPercentage = (percentage) => {
return `${numericValue.toFixed(2).replace(/\.?0+$/, "")}%`;
};
-export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
+export function ShopEmployeeTeamsFormComponent({ bodyshop, form, onDirtyChange, isDirty }) {
const { t } = useTranslation();
- const [form] = Form.useForm();
+ const [internalForm] = Form.useForm();
+ const [internalIsDirty, setInternalIsDirty] = useState(false);
+ const teamForm = form ?? internalForm;
+ const resolvedIsDirty = typeof isDirty === "boolean" ? isDirty : internalIsDirty;
const history = useNavigate();
const search = querystring.parse(useLocation().search);
const notification = useNotification();
const [hydratedTeamId, setHydratedTeamId] = useState(search.employeeTeamId === "new" ? "new" : null);
const isNewTeam = search.employeeTeamId === "new";
- const { error, data, loading } = useQuery(QUERY_EMPLOYEE_TEAM_BY_ID, {
+ const { error, data, loading, refetch } = useQuery(QUERY_EMPLOYEE_TEAM_BY_ID, {
variables: { id: search.employeeTeamId },
skip: !search.employeeTeamId || isNewTeam,
fetchPolicy: "network-only",
@@ -99,29 +84,68 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
notifyOnNetworkStatusChange: true
});
- useEffect(() => {
- if (!search.employeeTeamId) return;
+ const currentTeamData = data?.employee_teams_by_pk?.id === search.employeeTeamId ? data.employee_teams_by_pk : null;
+
+ const updateDirtyState = useCallback(
+ (nextDirtyState) => {
+ setInternalIsDirty(nextDirtyState);
+ onDirtyChange?.(nextDirtyState);
+ },
+ [onDirtyChange]
+ );
+
+ const clearTeamFormMeta = useCallback(() => {
+ const fieldMeta = teamForm.getFieldsError().map(({ name }) => ({
+ name,
+ touched: false,
+ validating: false,
+ errors: [],
+ warnings: []
+ }));
+
+ if (fieldMeta.length > 0) {
+ teamForm.setFields(fieldMeta);
+ }
+
+ updateDirtyState(false);
+ }, [teamForm, updateDirtyState]);
+
+ const resetTeamFormToCurrentData = useCallback(() => {
+ let hydrationFrameId;
+
+ teamForm.resetFields();
if (isNewTeam) {
- form.resetFields();
setHydratedTeamId("new");
- return;
+ hydrationFrameId = window.requestAnimationFrame(() => {
+ clearTeamFormMeta();
+ });
+ return () => {
+ if (hydrationFrameId) window.cancelAnimationFrame(hydrationFrameId);
+ };
}
setHydratedTeamId(null);
- }, [form, isNewTeam, search.employeeTeamId]);
- useEffect(() => {
- if (!search.employeeTeamId || isNewTeam || loading) return;
-
- if (data?.employee_teams_by_pk?.id === search.employeeTeamId) {
- form.setFieldsValue(normalizeEmployeeTeam(data.employee_teams_by_pk));
- setHydratedTeamId(search.employeeTeamId);
- } else {
- form.resetFields();
- setHydratedTeamId(search.employeeTeamId);
+ if (loading) {
+ return undefined;
}
- }, [data, form, isNewTeam, loading, search.employeeTeamId]);
+
+ if (currentTeamData) {
+ teamForm.setFieldsValue(normalizeEmployeeTeam(currentTeamData));
+ }
+
+ hydrationFrameId = window.requestAnimationFrame(() => {
+ setHydratedTeamId(search.employeeTeamId);
+ clearTeamFormMeta();
+ });
+
+ return () => {
+ if (hydrationFrameId) window.cancelAnimationFrame(hydrationFrameId);
+ };
+ }, [clearTeamFormMeta, currentTeamData, isNewTeam, loading, search.employeeTeamId, teamForm]);
+
+ useEffect(() => resetTeamFormToCurrentData(), [resetTeamFormToCurrentData]);
const [updateEmployeeTeam] = useMutation(UPDATE_EMPLOYEE_TEAM);
const [insertEmployeeTeam] = useMutation(INSERT_EMPLOYEE_TEAM);
@@ -129,34 +153,25 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
label: t(labelKey),
value
}));
- const teamName = Form.useWatch("name", form);
- const teamMembers = Form.useWatch(["employee_team_members"], form) || [];
+ const teamName = Form.useWatch("name", teamForm);
+ const teamMembers = Form.useWatch(["employee_team_members"], teamForm) || [];
const isTeamHydrating = !isNewTeam && Boolean(search.employeeTeamId) && hydratedTeamId !== search.employeeTeamId;
- const teamCardTitle = isTeamHydrating
- ? t("employee_teams.fields.name")
- : teamName?.trim() || t("employee_teams.fields.name");
-
- const getTeamMemberTitle = (teamMember = {}) => {
- const employeeName =
- getEmployeeDisplayName(bodyshop.employees, teamMember.employeeid) || t("employee_teams.fields.employeeid");
- const allocation = formatAllocationPercentage(teamMember.percentage);
- const payoutMethod =
- teamMember.payout_method === "commission"
- ? t("employee_teams.options.commission")
- : t("employee_teams.options.hourly");
-
- return (
-
- {employeeName}
-
- {`${t("employee_teams.fields.allocation")}: ${allocation || "--"}`}
-
-
- {payoutMethod}
-
-
- );
- };
+ const isAllocationTotalExact = hasExactSplitTotal(teamMembers);
+ const allocationTotalValue = formatAllocationPercentage(getSplitTotal(teamMembers))?.replace("%", "") || "0";
+ const teamNameDisplay = teamName?.trim() || t("employee_teams.fields.name");
+ const teamCardTitle = isTeamHydrating ? (
+ t("employee_teams.fields.name")
+ ) : (
+
+ {teamNameDisplay}
+ -
+
+ {t("employee_teams.labels.allocation_total", {
+ total: allocationTotalValue
+ })}
+
+
+ );
const handleFinish = async ({ employee_team_members = [], ...values }) => {
const { normalizedTeamMembers, errorKey } = validateEmployeeTeamMembers(employee_team_members);
@@ -193,6 +208,8 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
});
if (!result.errors) {
+ updateDirtyState(false);
+ void refetch();
notification.success({
title: t("employees.successes.save")
});
@@ -216,6 +233,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
},
refetchQueries: ["QUERY_TEAMS"]
}).then((response) => {
+ updateDirtyState(false);
search.employeeTeamId = response.data.insert_employee_teams_one.id;
history({ search: querystring.stringify(search) });
notification.success({
@@ -230,18 +248,66 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
return (
form.submit()} disabled={isTeamHydrating}>
- {t("general.actions.save")}
+ teamForm.submit()}
+ disabled={isTeamHydrating || !resolvedIsDirty}
+ style={{ minWidth: 190 }}
+ >
+ {t("employee_teams.actions.save_team")}
}
>
{isTeamHydrating ? (
) : (
-
+ );
+ })
+ )}
+
+
);
}}
diff --git a/client/src/components/shop-teams/shop-employee-teams.form.component.test.jsx b/client/src/components/shop-teams/shop-employee-teams.form.component.test.jsx
index c23a35615..9208b6a64 100644
--- a/client/src/components/shop-teams/shop-employee-teams.form.component.test.jsx
+++ b/client/src/components/shop-teams/shop-employee-teams.form.component.test.jsx
@@ -42,9 +42,11 @@ vi.mock("react-i18next", () => ({
"employee_teams.options.commission": "Commission",
"employee_teams.options.commission_percentage": "Commission",
"employee_teams.actions.newmember": "New Team Member",
+ "employee_teams.actions.save_team": "Save Employee Team",
"employee_teams.errors.minimum_one_member": "Add at least one team member.",
"employee_teams.errors.duplicate_member": "Team members must be unique.",
"employee_teams.errors.allocation_total_exact": "Allocation must total exactly 100%.",
+ "general.labels.click_to_begin": `Click ${values.action ?? ""} to begin`,
"general.actions.save": "Save",
"employees.successes.save": "Saved"
};
@@ -66,6 +68,10 @@ vi.mock("../../contexts/Notifications/notificationContext.jsx", () => ({
useNotification: () => notification
}));
+vi.mock("../form-fields-changed-alert/form-fields-changed-alert.component.jsx", () => ({
+ default: () => null
+}));
+
vi.mock("../../firebase/firebase.utils", () => ({
logImEXEvent: vi.fn()
}));
@@ -101,11 +107,12 @@ vi.mock("../form-items-formatted/currency-form-item.component", () => ({
}));
vi.mock("../layout-form-row/layout-form-row.component", () => ({
- default: ({ title, extra, children }) => (
+ default: ({ title, extra, actions, children }) => (
{title}
{extra}
{children}
+ {actions}
)
}));
@@ -144,7 +151,7 @@ const addBaseTeamMember = ({ employeeId = "emp-1", percentage = 100, rate = 25 }
fireEvent.change(screen.getByLabelText("Employee"), {
target: { value: employeeId }
});
- fireEvent.change(screen.getByRole("spinbutton", { name: "Allocation %" }), {
+ fireEvent.change(screen.getByRole("spinbutton", { name: "Allocation" }), {
target: { value: String(percentage) }
});
fillHourlyRates(rate);
@@ -211,7 +218,7 @@ describe("ShopEmployeeTeamsFormComponent", () => {
rate: 27.5
});
- fireEvent.click(screen.getByRole("button", { name: "Save" }));
+ fireEvent.click(screen.getByRole("button", { name: "Save Employee Team" }));
await waitFor(() => {
expect(insertEmployeeTeamMock).toHaveBeenCalledWith({
diff --git a/client/src/components/shop-teams/shop-employee-teams.list.jsx b/client/src/components/shop-teams/shop-employee-teams.list.jsx
index 4c0ac837b..6acb89f45 100644
--- a/client/src/components/shop-teams/shop-employee-teams.list.jsx
+++ b/client/src/components/shop-teams/shop-employee-teams.list.jsx
@@ -2,20 +2,47 @@ import { Button } from "antd";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router-dom";
+import ConfigListEmptyState from "../layout-form-row/config-list-empty-state.component.jsx";
+import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
-export default function ShopEmployeeTeamsListComponent({ loading, employee_teams }) {
+export default function ShopEmployeeTeamsListComponent({
+ loading,
+ employee_teams,
+ onRequestTeamChange,
+ selectedTeamId
+}) {
const { t } = useTranslation();
const history = useNavigate();
const search = queryString.parse(useLocation().search);
+ const navigateToTeam = (employeeTeamId) => {
+ if (onRequestTeamChange) {
+ onRequestTeamChange(employeeTeamId);
+ return;
+ }
+
+ history({
+ search: queryString.stringify({
+ ...search,
+ employeeTeamId
+ })
+ });
+ };
+
+ const clearTeamSelection = () => {
+ const { employeeTeamId, ...nextSearch } = search;
+ void employeeTeamId;
+ history({
+ search: queryString.stringify(nextSearch)
+ });
+ };
+
const handleOnRowClick = (record) => {
if (record) {
- search.employeeTeamId = record.id;
- history({ search: queryString.stringify(search) });
+ navigateToTeam(record.id);
} else {
- delete search.employeeTeamId;
- history({ search: queryString.stringify(search) });
+ clearTeamSelection();
}
};
const columns = [
@@ -27,43 +54,38 @@ export default function ShopEmployeeTeamsListComponent({ loading, employee_teams
];
return (
-
- {
- return (
- {
- search.employeeTeamId = "new";
- history({ search: queryString.stringify(search) });
- }}
- >
- {t("employee_teams.actions.new")}
-
- );
- }}
- loading={loading}
- pagination={{ placement: "top" }}
- columns={columns}
- mobileColumnKeys={["name"]}
- rowKey="id"
- dataSource={employee_teams}
- rowSelection={{
- onSelect: (props) => {
- search.employeeTeamId = props.id;
- history({ search: queryString.stringify(search) });
- },
- type: "radio",
- selectedRowKeys: [search.employeeTeamId]
- }}
- onRow={(record) => {
- return {
- onClick: () => {
- handleOnRowClick(record);
- }
- };
- }}
- />
-
+ navigateToTeam("new")}>
+ {t("employee_teams.actions.new")}
+
+ ]}
+ >
+ {employee_teams.length === 0 ? (
+
+ ) : (
+ navigateToTeam(props.id),
+ type: "radio",
+ selectedRowKeys: [selectedTeamId || search.employeeTeamId]
+ }}
+ onRow={(record) => {
+ return {
+ onClick: () => {
+ handleOnRowClick(record);
+ }
+ };
+ }}
+ />
+ )}
+
);
}
diff --git a/client/src/components/shop-teams/shop-teams.container.jsx b/client/src/components/shop-teams/shop-teams.container.jsx
index 9f5211f59..b55534b2d 100644
--- a/client/src/components/shop-teams/shop-teams.container.jsx
+++ b/client/src/components/shop-teams/shop-teams.container.jsx
@@ -1,36 +1,70 @@
+import { Form } from "antd";
import { useQuery } from "@apollo/client/react";
+import queryString from "query-string";
import { connect } from "react-redux";
+import { useState } from "react";
+import { useLocation, useNavigate } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { QUERY_TEAMS } from "../../graphql/employee_teams.queries";
+import useConfirmDirtyFormNavigation from "../../hooks/useConfirmDirtyFormNavigation.jsx";
import AlertComponent from "../alert/alert.component";
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
import ShopEmployeeTeamsListComponent from "./shop-employee-teams.list";
import ShopEmployeeTeamsFormComponent from "./shop-employee-teams.form.component";
-import { Col, Row } from "antd";
+import "./shop-teams.styles.scss";
const mapStateToProps = createStructuredSelector({});
function ShopTeamsContainer() {
+ const [form] = Form.useForm();
+ const [isTeamFormDirty, setIsTeamFormDirty] = useState(false);
+ const navigate = useNavigate();
+ const search = queryString.parse(useLocation().search);
const { loading, error, data } = useQuery(QUERY_TEAMS, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only"
});
+ const hasSelectedTeam = Boolean(search.employeeTeamId);
+ const hasDirtyTeamForm = Boolean(search.employeeTeamId) && isTeamFormDirty;
+ const confirmCloseDirtyTeam = useConfirmDirtyFormNavigation(hasDirtyTeamForm);
+
+ const navigateToTeam = (employeeTeamId) => {
+ if (employeeTeamId === search.employeeTeamId) return;
+ if (!confirmCloseDirtyTeam()) return;
+
+ setIsTeamFormDirty(false);
+ navigate({
+ search: queryString.stringify({
+ ...search,
+ employeeTeamId
+ })
+ });
+ };
if (error) return ;
return (
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ {hasSelectedTeam ? (
+
+
+
+ ) : null}
+
+
);
}
diff --git a/client/src/components/shop-teams/shop-teams.styles.scss b/client/src/components/shop-teams/shop-teams.styles.scss
new file mode 100644
index 000000000..2582f7232
--- /dev/null
+++ b/client/src/components/shop-teams/shop-teams.styles.scss
@@ -0,0 +1,16 @@
+.shop-teams-layout {
+ display: grid;
+ gap: 16px;
+ align-items: start;
+}
+
+.shop-teams-layout__list,
+.shop-teams-layout__details {
+ min-width: 0;
+}
+
+@media (min-width: 1700px) {
+ .shop-teams-layout--with-detail {
+ grid-template-columns: minmax(420px, 500px) minmax(0, 1fr);
+ }
+}
diff --git a/client/src/components/shop-users/shop-users.component.jsx b/client/src/components/shop-users/shop-users.component.jsx
index d3fd16b45..d4e972b11 100644
--- a/client/src/components/shop-users/shop-users.component.jsx
+++ b/client/src/components/shop-users/shop-users.component.jsx
@@ -6,6 +6,7 @@ import { createStructuredSelector } from "reselect";
import { QUERY_SHOP_ASSOCIATIONS } from "../../graphql/user.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component";
+import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
import ResponsiveTable from "../responsive-table/responsive-table.component";
import ShopUsersAuthEdit from "../shop-users-auth-edit/shop-users-auth-edit.component";
@@ -66,7 +67,7 @@ export function ShopInfoUsersComponent({ bodyshop }) {
return ;
}
return (
-
+
-
+
);
}
diff --git a/client/src/hooks/useConfirmDirtyFormNavigation.jsx b/client/src/hooks/useConfirmDirtyFormNavigation.jsx
new file mode 100644
index 000000000..5b77bbf88
--- /dev/null
+++ b/client/src/hooks/useConfirmDirtyFormNavigation.jsx
@@ -0,0 +1,11 @@
+import { useCallback } from "react";
+import { useTranslation } from "react-i18next";
+
+export default function useConfirmDirtyFormNavigation(isDirty) {
+ const { t } = useTranslation();
+
+ return useCallback(() => {
+ if (!isDirty) return true;
+ return window.confirm(t("general.messages.unsavedchangespopup"));
+ }, [isDirty, t]);
+}
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index f0d1ebbff..d8deb99b2 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -293,7 +293,23 @@
},
"bodyshop": {
"actions": {
+ "add_adjuster": "Add Adjuster",
+ "add_control_number": "Add Control Number",
+ "add_cost_center": "Add Cost Center",
+ "add_courtesy_car_rate_preset": "Add Courtesy Car Contract Rate Preset",
+ "add_delivery_checklist_item": "Add Delivery Checklist Item",
+ "add_dms_allocation": "Add DMS Allocation",
+ "add_estimator": "Add Estimator",
+ "add_insurance_company": "Add Insurance Company",
+ "add_intake_checklist_item": "Add Intake Checklist Item",
+ "add_jobline_preset": "Add Jobline Preset",
+ "add_messaging_preset": "Add Messaging Preset",
+ "add_note_preset": "Add Note Preset",
+ "add_parts_order_comment": "Add Parts Order Comment",
+ "add_production_status_color": "Add Production Status Color",
+ "add_profit_center": "Add Profit Center",
"add_task_preset": "Add Task Preset",
+ "add_to_email_preset": "Add To Email Preset",
"addapptcolor": "Add Appointment Color",
"addbucket": "Add Definition",
"addpartslocation": "Add Parts Location",
@@ -302,11 +318,13 @@
"addtemplate": "Add Template",
"newlaborrate": "New Labor Rate",
"newsalestaxcode": "New Sales Tax Code",
+ "save_shop_information": "Save Shop Information",
"newstatus": "Add Status",
"testrender": "Test Render"
},
"errors": {
"creatingdefaultview": "Error creating default view.",
+ "duplicate_job_status": "Duplicate job status. Each job status must be unique.",
"duplicate_insurance_company": "Duplicate insurance company name. Each insurance company name must be unique",
"loading": "Unable to load shop details. Please call technical support.",
"saving": "Error encountered while saving. {{message}}",
@@ -404,6 +422,35 @@
"logo_img_path": "Shop Logo",
"logo_img_path_height": "Logo Image Height",
"logo_img_path_width": "Logo Image Width",
+ "scoreboard_setup": {
+ "daily_body_target": "Daily Body Target",
+ "daily_paint_target": "Daily Paint Target",
+ "ignore_blocked_days": "Ignore Blocked Days",
+ "last_number_working_days": "Last Number of Working Days",
+ "production_target_hours": "Production Target Hours"
+ },
+ "system_settings": {
+ "auto_email": {
+ "attach_pdf_to_email": "Attach PDF to Sent Emails?",
+ "from_emails": "Additional From Emails",
+ "parts_order_cc": "Parts Orders CC",
+ "parts_return_slip_cc": "Parts Returns CC"
+ },
+ "job_costing": {
+ "paint_hour_split": "Paint Hour Split",
+ "paint_materials_hourly_cost_rate": "Paint Materials Hourly Cost Rate",
+ "prep_hour_split": "Prep Hour Split",
+ "shop_materials_hourly_cost_rate": "Shop Materials Hourly Cost Rate",
+ "target_touch_time": "Target Touch Time",
+ "use_paint_scale_data": "Use Paint Scale Data"
+ },
+ "local_media_server": {
+ "enabled": "Enabled",
+ "http_path": "HTTP Path",
+ "network_path": "Network Path",
+ "token": "Token"
+ }
+ },
"md_categories": "Categories",
"md_ccc_rates": "Courtesy Car Contract Rate Presets",
"md_classes": "Classes",
@@ -464,9 +511,13 @@
"use_approvals": "Use Time Ticket Approval Queue"
},
"messaginglabel": "Messaging Preset Label",
+ "messaginglabel_short": "Label",
"messagingtext": "Messaging Preset Text",
+ "messagingtext_short": "Text",
"noteslabel": "Note Label",
+ "noteslabel_short": "Label",
"notestext": "Note Text",
+ "notestext_short": "Text",
"notifications": {
"description": "Select employees to automatically follow new jobs and receive notifications for job updates.",
"invalid_followers": "Invalid selection. Please select valid employees.",
@@ -600,12 +651,17 @@
"federal_tax_itc": "Federal Tax Credit",
"gogcode": "GOG Code (BreakOut)",
"gst_override": "GST Override Account #",
+ "invoice_federal_tax_rate_short": "Federal Tax Rate",
+ "invoice_local_tax_rate_short": "Local Tax Rate",
+ "invoice_state_tax_rate_short": "State Tax Rate",
"invoiceexemptcode": "QuickBooks US - Invoice Tax Exempt Code",
+ "invoiceexemptcode_short": "Invoice Tax Exempt Code",
"item_type": "Item Type",
"item_type_freight": "Freight",
"item_type_gog": "GOG",
"item_type_paint": "Paint Materials",
"itemexemptcode": "QuickBooks US - Line Item Tax Exempt Code",
+ "itemexemptcode_short": "Line Item Tax Exempt Code",
"la1": "LA1",
"la2": "LA2",
"la3": "LA3",
@@ -722,6 +778,7 @@
"customtemplates": "Custom Templates",
"defaultcostsmapping": "Default Costs Mapping",
"defaultprofitsmapping": "Default Profits Mapping",
+ "dms_setup": "DMS Setup",
"deliverchecklist": "Delivery Checklist",
"dms": {
"cdk": {
@@ -738,24 +795,33 @@
},
"emaillater": "Email Later",
"employee_teams": "Employee Teams",
+ "employee_options": "Employee Options",
+ "employee_rates": "Employee Rates",
+ "employee_vacation": "Employee Vacation",
"employees": "Employees",
"estimators": "Estimators",
"filehandlers": "Adjusters",
"imexpay": "ImEX Pay",
"insurancecos": "Insurance Companies",
+ "intake_delivery": "Intake / Delivery Options",
"intakechecklist": "Intake Checklist",
"intellipay_cash_discount": "Please ensure that cash discounting has been enabled on your merchant account. Reach out to IntelliPay Support if you need assistance. ",
+ "job_status_options": "Job Status Options",
"jobstatuses": "Job Statuses",
"laborrates": "Labor Rates",
"licensing": "Licensing",
"md_parts_scan": "Parts Scan Rules",
"md_ro_guard": "RO Guard",
+ "md_ro_guard_options": "RO Guard Options",
"md_tasks_presets": "Tasks Presets",
+ "task_preset_options": "Task Preset Options",
"md_to_emails": "Preset To Emails",
"md_to_emails_emails": "Emails",
"messagingpresets": "Messaging Presets",
+ "notification_options": "Notification Options",
"notemplatesavailable": "No templates available to add.",
"notespresets": "Notes Presets",
+ "jump_to_section": "Jump to section",
"notifications": {
"followers": "Notifications"
},
@@ -769,11 +835,22 @@
"qbo_departmentid": "QBO Department ID",
"qbo_usa": "QBO USA Compatibility",
"rbac": "Role Based Access Control",
+ "rbac_options": "Role Based Access Control Options",
"responsibilitycenters": {
"costs": "Cost Centers",
+ "default_tax_setup": "Default Tax Setup",
+ "invoices": "Invoices",
"profits": "Profit Centers",
+ "quickbooks_qbd": "QuickBooks / QBD",
+ "quickbooks_us": "QuickBooks US",
"sales_tax_codes": "Sales Tax Codes",
"tax_accounts": "Tax Accounts",
+ "tax_rate_short": "Rate",
+ "tax_surcharge_short": "Surcharge",
+ "tax_threshold_short": "Threshold",
+ "tax_tier_card": "Tier {{typeNumIterator}}",
+ "tax_tier_short": "Tier",
+ "tax_type_card": "Tax Type {{typeNum}}",
"title": "Responsibility Centers",
"ttl_adjustment": "Subtotal Adjustment Account",
"ttl_tax_adjustment": "Tax Adjustment Account"
@@ -781,6 +858,9 @@
"roguard": {
"title": "RO Guard"
},
+ "autoemail": "Auto Email",
+ "jobcosting": "Job Costing",
+ "localmediaserver": "Local Media Server",
"romepay": "Rome Pay",
"scheduling": "SMART Scheduling",
"scoreboardsetup": "Scoreboard Setup",
@@ -788,6 +868,7 @@
"shopinfo": "Shop Information",
"shoprates": "Shop Rates",
"speedprint": "Speed Print Configuration",
+ "speedprint_configurations": "Speed Print Configurations",
"ssbuckets": "Job Size Definitions",
"systemsettings": "System Settings",
"task-presets": "Task Presets",
@@ -811,7 +892,8 @@
"tooltips": {
"md_parts_scan": {
"update_value_tooltip": "Some fields require coded values in order to function properly (e.g. labor and part types). Please reach out to support if you have any questions."
- }
+ },
+ "reset-color": "Reset color"
},
"validation": {
"centermustexist": "The chosen responsibility center does not exist.",
@@ -1179,7 +1261,8 @@
"employee_teams": {
"actions": {
"new": "New Team",
- "newmember": "New Team Member"
+ "newmember": "New Team Member",
+ "save_team": "Save Employee Team"
},
"errors": {
"allocation_total_exact": "Team allocation must total exactly 100%.",
@@ -1197,7 +1280,9 @@
"percentage": "Percent"
},
"labels": {
- "allocation_total": "Allocation Total: {{total}}%"
+ "allocation_total": "Allocation Total: {{total}}%",
+ "members": "Members",
+ "team_options": "Team Options"
},
"options": {
"commission": "Commission",
@@ -1207,9 +1292,11 @@
},
"employees": {
"actions": {
+ "addrate": "Add Rate",
"addvacation": "Add Vacation",
"new": "New Employee",
"newrate": "New Rate",
+ "save_employee": "Save Employee",
"select": "Select Employee"
},
"errors": {
@@ -1241,6 +1328,7 @@
"labels": {
"actions": "Actions",
"active": "Active",
+ "employee_number_short": "Employee #",
"endmustbeafterstart": "End date must be after start date.",
"flat_rate": "Flat Rate",
"inactive": "Inactive",
@@ -1373,6 +1461,7 @@
"beta": "BETA",
"cancel": "Are you sure you want to cancel? Your changes will not be saved.",
"changelog": "Change Log",
+ "click_to_begin": "Click {{action}} to begin",
"clear": "Clear",
"confirmpassword": "Confirm Password",
"created_at": "Created At",
@@ -1918,10 +2007,15 @@
"employee_refinish": "Refinish",
"est_addr1": "Estimator Address",
"est_co_nm": "Estimator Company",
+ "est_co_nm_short": "Company",
"est_ct_fn": "Estimator First Name",
+ "est_ct_fn_short": "First Name",
"est_ct_ln": "Estimator Last Name",
+ "est_ct_ln_short": "Last Name",
"est_ea": "Estimator Email",
+ "est_ea_short": "Email",
"est_ph1": "Estimator Phone #",
+ "est_ph1_short": "Phone #",
"estimate_approved": "Estimate Approved",
"estimate_sent_approval": "Estimate Sent for Approval",
"federal_tax_payable": "Federal Tax Payable",
@@ -1934,9 +2028,13 @@
"ins_co_nm": "Insurance Company Name",
"ins_co_nm_short": "Ins. Co.",
"ins_ct_fn": "Adjuster First Name",
+ "ins_ct_fn_short": "First Name",
"ins_ct_ln": "Adjuster Last Name",
+ "ins_ct_ln_short": "Last Name",
"ins_ea": "Adjuster Email",
+ "ins_ea_short": "Email",
"ins_ph1": "Adjuster Phone #",
+ "ins_ph1_short": "Phone #",
"intake": {
"label": "Label",
"max": "Maximum",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 3f1d15ce6..e888b06ae 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -293,7 +293,23 @@
},
"bodyshop": {
"actions": {
+ "add_adjuster": "",
+ "add_control_number": "",
+ "add_cost_center": "",
+ "add_courtesy_car_rate_preset": "",
+ "add_delivery_checklist_item": "",
+ "add_dms_allocation": "",
+ "add_estimator": "",
+ "add_insurance_company": "",
+ "add_intake_checklist_item": "",
+ "add_jobline_preset": "",
+ "add_messaging_preset": "",
+ "add_note_preset": "",
+ "add_parts_order_comment": "",
+ "add_production_status_color": "",
+ "add_profit_center": "",
"add_task_preset": "",
+ "add_to_email_preset": "",
"addapptcolor": "",
"addbucket": "",
"addpartslocation": "",
@@ -302,11 +318,13 @@
"addtemplate": "",
"newlaborrate": "",
"newsalestaxcode": "",
+ "save_shop_information": "",
"newstatus": "",
"testrender": ""
},
"errors": {
"creatingdefaultview": "",
+ "duplicate_job_status": "",
"duplicate_insurance_company": "",
"loading": "No se pueden cargar los detalles de la tienda. Por favor llame al soporte técnico.",
"saving": "",
@@ -404,6 +422,35 @@
"logo_img_path": "",
"logo_img_path_height": "",
"logo_img_path_width": "",
+ "scoreboard_setup": {
+ "daily_body_target": "",
+ "daily_paint_target": "",
+ "ignore_blocked_days": "",
+ "last_number_working_days": "",
+ "production_target_hours": ""
+ },
+ "system_settings": {
+ "auto_email": {
+ "attach_pdf_to_email": "",
+ "from_emails": "",
+ "parts_order_cc": "",
+ "parts_return_slip_cc": ""
+ },
+ "job_costing": {
+ "paint_hour_split": "",
+ "paint_materials_hourly_cost_rate": "",
+ "prep_hour_split": "",
+ "shop_materials_hourly_cost_rate": "",
+ "target_touch_time": "",
+ "use_paint_scale_data": ""
+ },
+ "local_media_server": {
+ "enabled": "",
+ "http_path": "",
+ "network_path": "",
+ "token": ""
+ }
+ },
"md_categories": "",
"md_ccc_rates": "",
"md_classes": "",
@@ -464,9 +511,13 @@
"use_approvals": ""
},
"messaginglabel": "",
+ "messaginglabel_short": "",
"messagingtext": "",
+ "messagingtext_short": "",
"noteslabel": "",
+ "noteslabel_short": "",
"notestext": "",
+ "notestext_short": "",
"notifications": {
"description": "",
"invalid_followers": "",
@@ -600,12 +651,17 @@
"federal_tax_itc": "",
"gogcode": "",
"gst_override": "",
+ "invoice_federal_tax_rate_short": "",
+ "invoice_local_tax_rate_short": "",
+ "invoice_state_tax_rate_short": "",
"invoiceexemptcode": "",
+ "invoiceexemptcode_short": "",
"item_type": "Item Type",
"item_type_freight": "",
"item_type_gog": "",
"item_type_paint": "",
"itemexemptcode": "",
+ "itemexemptcode_short": "",
"la1": "",
"la2": "",
"la3": "",
@@ -722,6 +778,7 @@
"customtemplates": "",
"defaultcostsmapping": "",
"defaultprofitsmapping": "",
+ "dms_setup": "",
"deliverchecklist": "",
"dms": {
"cdk": {
@@ -738,24 +795,33 @@
},
"emaillater": "",
"employee_teams": "",
+ "employee_options": "",
+ "employee_rates": "",
+ "employee_vacation": "",
"employees": "",
"estimators": "",
"filehandlers": "",
"imexpay": "",
"insurancecos": "",
+ "intake_delivery": "",
"intakechecklist": "",
"intellipay_cash_discount": "",
+ "job_status_options": "",
"jobstatuses": "",
"laborrates": "",
"licensing": "",
"md_parts_scan": "",
"md_ro_guard": "",
+ "md_ro_guard_options": "",
"md_tasks_presets": "",
+ "task_preset_options": "",
"md_to_emails": "",
"md_to_emails_emails": "",
"messagingpresets": "",
+ "notification_options": "",
"notemplatesavailable": "",
"notespresets": "",
+ "jump_to_section": "",
"notifications": {
"followers": ""
},
@@ -769,11 +835,22 @@
"qbo_departmentid": "",
"qbo_usa": "",
"rbac": "",
+ "rbac_options": "",
"responsibilitycenters": {
"costs": "",
+ "default_tax_setup": "",
+ "invoices": "",
"profits": "",
+ "quickbooks_qbd": "",
+ "quickbooks_us": "",
"sales_tax_codes": "",
"tax_accounts": "",
+ "tax_rate_short": "",
+ "tax_surcharge_short": "",
+ "tax_threshold_short": "",
+ "tax_tier_card": "",
+ "tax_tier_short": "",
+ "tax_type_card": "",
"title": "",
"ttl_adjustment": "",
"ttl_tax_adjustment": ""
@@ -781,6 +858,9 @@
"roguard": {
"title": ""
},
+ "autoemail": "",
+ "jobcosting": "",
+ "localmediaserver": "",
"romepay": "",
"scheduling": "",
"scoreboardsetup": "",
@@ -788,6 +868,7 @@
"shopinfo": "",
"shoprates": "",
"speedprint": "",
+ "speedprint_configurations": "",
"ssbuckets": "",
"systemsettings": "",
"task-presets": "",
@@ -811,7 +892,8 @@
"tooltips": {
"md_parts_scan": {
"update_value_tooltip": ""
- }
+ },
+ "reset-color": ""
},
"validation": {
"centermustexist": "",
@@ -1179,7 +1261,8 @@
"employee_teams": {
"actions": {
"new": "",
- "newmember": ""
+ "newmember": "",
+ "save_team": ""
},
"errors": {
"allocation_total_exact": "",
@@ -1197,7 +1280,9 @@
"percentage": ""
},
"labels": {
- "allocation_total": ""
+ "allocation_total": "",
+ "members": "",
+ "team_options": ""
},
"options": {
"commission": "",
@@ -1207,9 +1292,11 @@
},
"employees": {
"actions": {
+ "addrate": "",
"addvacation": "",
"new": "Nuevo empleado",
"newrate": "",
+ "save_employee": "",
"select": ""
},
"errors": {
@@ -1241,6 +1328,7 @@
"labels": {
"actions": "",
"active": "",
+ "employee_number_short": "",
"endmustbeafterstart": "",
"flat_rate": "",
"inactive": "",
@@ -1373,6 +1461,7 @@
"beta": "",
"cancel": "",
"changelog": "",
+ "click_to_begin": "",
"clear": "",
"confirmpassword": "",
"created_at": "",
@@ -1918,10 +2007,15 @@
"employee_refinish": "",
"est_addr1": "Dirección del tasador",
"est_co_nm": "Tasador",
+ "est_co_nm_short": "",
"est_ct_fn": "Nombre del tasador",
+ "est_ct_fn_short": "",
"est_ct_ln": "Apellido del tasador",
+ "est_ct_ln_short": "",
"est_ea": "Correo electrónico del tasador",
+ "est_ea_short": "",
"est_ph1": "Número de teléfono del tasador",
+ "est_ph1_short": "",
"estimate_approved": "",
"estimate_sent_approval": "",
"federal_tax_payable": "Impuesto federal por pagar",
@@ -1934,9 +2028,13 @@
"ins_co_nm": "Nombre de la compañía de seguros",
"ins_co_nm_short": "",
"ins_ct_fn": "Nombre del controlador de archivos",
+ "ins_ct_fn_short": "",
"ins_ct_ln": "Apellido del manejador de archivos",
+ "ins_ct_ln_short": "",
"ins_ea": "Correo electrónico del controlador de archivos",
+ "ins_ea_short": "",
"ins_ph1": "File Handler Phone #",
+ "ins_ph1_short": "",
"intake": {
"label": "",
"max": "",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index c1520a5e3..d428eab8c 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -293,7 +293,23 @@
},
"bodyshop": {
"actions": {
+ "add_adjuster": "",
+ "add_control_number": "",
+ "add_cost_center": "",
+ "add_courtesy_car_rate_preset": "",
+ "add_delivery_checklist_item": "",
+ "add_dms_allocation": "",
+ "add_estimator": "",
+ "add_insurance_company": "",
+ "add_intake_checklist_item": "",
+ "add_jobline_preset": "",
+ "add_messaging_preset": "",
+ "add_note_preset": "",
+ "add_parts_order_comment": "",
+ "add_production_status_color": "",
+ "add_profit_center": "",
"add_task_preset": "",
+ "add_to_email_preset": "",
"addapptcolor": "",
"addbucket": "",
"addpartslocation": "",
@@ -302,11 +318,13 @@
"addtemplate": "",
"newlaborrate": "",
"newsalestaxcode": "",
+ "save_shop_information": "",
"newstatus": "",
"testrender": ""
},
"errors": {
"creatingdefaultview": "",
+ "duplicate_job_status": "",
"duplicate_insurance_company": "",
"loading": "Impossible de charger les détails de la boutique. Veuillez appeler le support technique.",
"saving": "",
@@ -404,6 +422,35 @@
"logo_img_path": "",
"logo_img_path_height": "",
"logo_img_path_width": "",
+ "scoreboard_setup": {
+ "daily_body_target": "",
+ "daily_paint_target": "",
+ "ignore_blocked_days": "",
+ "last_number_working_days": "",
+ "production_target_hours": ""
+ },
+ "system_settings": {
+ "auto_email": {
+ "attach_pdf_to_email": "",
+ "from_emails": "",
+ "parts_order_cc": "",
+ "parts_return_slip_cc": ""
+ },
+ "job_costing": {
+ "paint_hour_split": "",
+ "paint_materials_hourly_cost_rate": "",
+ "prep_hour_split": "",
+ "shop_materials_hourly_cost_rate": "",
+ "target_touch_time": "",
+ "use_paint_scale_data": ""
+ },
+ "local_media_server": {
+ "enabled": "",
+ "http_path": "",
+ "network_path": "",
+ "token": ""
+ }
+ },
"md_categories": "",
"md_ccc_rates": "",
"md_classes": "",
@@ -464,9 +511,13 @@
"use_approvals": ""
},
"messaginglabel": "",
+ "messaginglabel_short": "",
"messagingtext": "",
+ "messagingtext_short": "",
"noteslabel": "",
+ "noteslabel_short": "",
"notestext": "",
+ "notestext_short": "",
"notifications": {
"description": "",
"invalid_followers": "",
@@ -600,12 +651,17 @@
"federal_tax_itc": "",
"gogcode": "",
"gst_override": "",
+ "invoice_federal_tax_rate_short": "",
+ "invoice_local_tax_rate_short": "",
+ "invoice_state_tax_rate_short": "",
"invoiceexemptcode": "",
+ "invoiceexemptcode_short": "",
"item_type": "Item Type",
"item_type_freight": "",
"item_type_gog": "",
"item_type_paint": "",
"itemexemptcode": "",
+ "itemexemptcode_short": "",
"la1": "",
"la2": "",
"la3": "",
@@ -722,6 +778,7 @@
"customtemplates": "",
"defaultcostsmapping": "",
"defaultprofitsmapping": "",
+ "dms_setup": "",
"deliverchecklist": "",
"dms": {
"cdk": {
@@ -738,24 +795,33 @@
},
"emaillater": "",
"employee_teams": "",
+ "employee_options": "",
+ "employee_rates": "",
+ "employee_vacation": "",
"employees": "",
"estimators": "",
"filehandlers": "",
"imexpay": "",
"insurancecos": "",
+ "intake_delivery": "",
"intakechecklist": "",
"intellipay_cash_discount": "",
+ "job_status_options": "",
"jobstatuses": "",
"laborrates": "",
"licensing": "",
"md_parts_scan": "",
"md_ro_guard": "",
+ "md_ro_guard_options": "",
"md_tasks_presets": "",
+ "task_preset_options": "",
"md_to_emails": "",
"md_to_emails_emails": "",
"messagingpresets": "",
+ "notification_options": "",
"notemplatesavailable": "",
"notespresets": "",
+ "jump_to_section": "",
"notifications": {
"followers": ""
},
@@ -769,11 +835,22 @@
"qbo_departmentid": "",
"qbo_usa": "",
"rbac": "",
+ "rbac_options": "",
"responsibilitycenters": {
"costs": "",
+ "default_tax_setup": "",
+ "invoices": "",
"profits": "",
+ "quickbooks_qbd": "",
+ "quickbooks_us": "",
"sales_tax_codes": "",
"tax_accounts": "",
+ "tax_rate_short": "",
+ "tax_surcharge_short": "",
+ "tax_threshold_short": "",
+ "tax_tier_card": "",
+ "tax_tier_short": "",
+ "tax_type_card": "",
"title": "",
"ttl_adjustment": "",
"ttl_tax_adjustment": ""
@@ -781,6 +858,9 @@
"roguard": {
"title": ""
},
+ "autoemail": "",
+ "jobcosting": "",
+ "localmediaserver": "",
"romepay": "",
"scheduling": "",
"scoreboardsetup": "",
@@ -788,6 +868,7 @@
"shopinfo": "",
"shoprates": "",
"speedprint": "",
+ "speedprint_configurations": "",
"ssbuckets": "",
"systemsettings": "",
"task-presets": "",
@@ -811,7 +892,8 @@
"tooltips": {
"md_parts_scan": {
"update_value_tooltip": ""
- }
+ },
+ "reset-color": ""
},
"validation": {
"centermustexist": "",
@@ -1179,7 +1261,8 @@
"employee_teams": {
"actions": {
"new": "",
- "newmember": ""
+ "newmember": "",
+ "save_team": ""
},
"errors": {
"allocation_total_exact": "",
@@ -1197,7 +1280,9 @@
"percentage": ""
},
"labels": {
- "allocation_total": ""
+ "allocation_total": "",
+ "members": "",
+ "team_options": ""
},
"options": {
"commission": "",
@@ -1207,9 +1292,11 @@
},
"employees": {
"actions": {
+ "addrate": "",
"addvacation": "",
"new": "Nouvel employé",
"newrate": "",
+ "save_employee": "",
"select": ""
},
"errors": {
@@ -1241,6 +1328,7 @@
"labels": {
"actions": "",
"active": "",
+ "employee_number_short": "",
"endmustbeafterstart": "",
"flat_rate": "",
"inactive": "",
@@ -1373,6 +1461,7 @@
"beta": "",
"cancel": "",
"changelog": "",
+ "click_to_begin": "",
"clear": "",
"confirmpassword": "",
"created_at": "",
@@ -1918,10 +2007,15 @@
"employee_refinish": "",
"est_addr1": "Adresse de l'évaluateur",
"est_co_nm": "Expert",
+ "est_co_nm_short": "",
"est_ct_fn": "Prénom de l'évaluateur",
+ "est_ct_fn_short": "",
"est_ct_ln": "Nom de l'évaluateur",
+ "est_ct_ln_short": "",
"est_ea": "Courriel de l'évaluateur",
+ "est_ea_short": "",
"est_ph1": "Numéro de téléphone de l'évaluateur",
+ "est_ph1_short": "",
"estimate_approved": "",
"estimate_sent_approval": "",
"federal_tax_payable": "Impôt fédéral à payer",
@@ -1934,9 +2028,13 @@
"ins_co_nm": "Nom de la compagnie d'assurance",
"ins_co_nm_short": "",
"ins_ct_fn": "Prénom du gestionnaire de fichiers",
+ "ins_ct_fn_short": "",
"ins_ct_ln": "Nom du gestionnaire de fichiers",
+ "ins_ct_ln_short": "",
"ins_ea": "Courriel du gestionnaire de fichiers",
+ "ins_ea_short": "",
"ins_ph1": "Numéro de téléphone du gestionnaire de fichiers",
+ "ins_ph1_short": "",
"intake": {
"label": "",
"max": "",
diff --git a/package-lock.json b/package-lock.json
index 0a63c96c5..3354b9ed7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,25 +9,25 @@
"version": "0.2.0",
"license": "UNLICENSED",
"dependencies": {
- "@aws-sdk/client-cloudwatch-logs": "^3.1014.0",
- "@aws-sdk/client-elasticache": "^3.1014.0",
- "@aws-sdk/client-s3": "^3.1014.0",
- "@aws-sdk/client-secrets-manager": "^3.1014.0",
- "@aws-sdk/client-ses": "^3.1014.0",
- "@aws-sdk/client-sqs": "^3.1014.0",
- "@aws-sdk/client-textract": "^3.1014.0",
- "@aws-sdk/credential-provider-node": "^3.972.24",
- "@aws-sdk/lib-storage": "^3.1014.0",
- "@aws-sdk/s3-request-presigner": "^3.1014.0",
+ "@aws-sdk/client-cloudwatch-logs": "^3.1020.0",
+ "@aws-sdk/client-elasticache": "^3.1020.0",
+ "@aws-sdk/client-s3": "^3.1020.0",
+ "@aws-sdk/client-secrets-manager": "^3.1020.0",
+ "@aws-sdk/client-ses": "^3.1020.0",
+ "@aws-sdk/client-sqs": "^3.1020.0",
+ "@aws-sdk/client-textract": "^3.1020.0",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
+ "@aws-sdk/lib-storage": "^3.1020.0",
+ "@aws-sdk/s3-request-presigner": "^3.1020.0",
"@opensearch-project/opensearch": "^2.13.0",
"@socket.io/admin-ui": "^0.5.1",
"@socket.io/redis-adapter": "^8.3.0",
"archiver": "^7.0.1",
"aws4": "^1.13.2",
- "axios": "^1.13.6",
+ "axios": "^1.14.0",
"axios-curlirize": "^2.0.0",
"better-queue": "^3.8.12",
- "bullmq": "^5.71.0",
+ "bullmq": "^5.71.1",
"chart.js": "^4.5.1",
"cloudinary": "^2.9.0",
"compression": "^1.8.1",
@@ -37,10 +37,10 @@
"dinero.js": "^1.9.1",
"dotenv": "^17.3.1",
"express": "^4.21.1",
- "fast-xml-parser": "^5.5.8",
+ "fast-xml-parser": "^5.5.9",
"firebase-admin": "^13.7.0",
"fuse.js": "^7.1.0",
- "graphql": "^16.13.1",
+ "graphql": "^16.13.2",
"graphql-request": "^6.1.0",
"intuit-oauth": "^4.2.2",
"ioredis": "^5.10.1",
@@ -64,7 +64,7 @@
"socket.io": "^4.8.3",
"socket.io-adapter": "^2.5.6",
"ssh2-sftp-client": "^11.0.0",
- "twilio": "^5.13.0",
+ "twilio": "^5.13.1",
"uuid": "^11.1.0",
"winston": "^3.19.0",
"winston-cloudwatch": "^6.3.0",
@@ -82,7 +82,7 @@
"p-limit": "^3.1.0",
"prettier": "^3.8.1",
"supertest": "^7.2.2",
- "vitest": "^4.1.0"
+ "vitest": "^4.1.2"
},
"engines": {
"node": ">=22.13.0",
@@ -292,26 +292,26 @@
}
},
"node_modules/@aws-sdk/client-cloudwatch-logs": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1014.0.tgz",
- "integrity": "sha512-T3TV8Rk4gyv18W5N1r/PeQaAbHTwJMV12JJ9KQEEdY0ZS1Bb/kx9JIPgMMlUjSQ7LeJ8FsdNRXDuAtCt3kCy+Q==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.1020.0.tgz",
+ "integrity": "sha512-ezS+wZbSJYbncXtfO0BOyNdqeRnKPSRPZNq111aydoZoW0Q/FnTiRbISZoMLqOCnwJVOX3EZMGNGpUvVyJ+CGQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-node": "^3.972.24",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/eventstream-serde-browser": "^4.2.12",
"@smithy/eventstream-serde-config-resolver": "^4.3.12",
"@smithy/eventstream-serde-node": "^4.2.12",
@@ -319,21 +319,21 @@
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -345,50 +345,50 @@
}
},
"node_modules/@aws-sdk/client-elasticache": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.1014.0.tgz",
- "integrity": "sha512-1gSai5MxtnmiGt80thfnmcfTWXRtj2vRDhDkSOa348e9MlSfFAttKuvp+bFb92M1FxbM9Dh8wQZxxluuQWu3wA==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.1020.0.tgz",
+ "integrity": "sha512-cuYpuMTjsXXbQrrWuqMCZID+oi4D8w3w8aixdVe4Yri//x++mcebxe+oZGRZlKGWZPKQYg1GpCTm+bu8CWygYA==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-node": "^3.972.24",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
"@smithy/util-utf8": "^4.2.2",
- "@smithy/util-waiter": "^4.2.13",
+ "@smithy/util-waiter": "^4.2.14",
"tslib": "^2.6.2"
},
"engines": {
@@ -396,34 +396,34 @@
}
},
"node_modules/@aws-sdk/client-s3": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1014.0.tgz",
- "integrity": "sha512-0XLrOT4Cm3NEhhiME7l/8LbTXS4KdsbR4dSrY207KNKTcHLLTZ9EXt4ZpgnTfLvWQF3pGP2us4Zi1fYLo0N+Ow==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1020.0.tgz",
+ "integrity": "sha512-ibfxjP5zLUqpujLE0OTgD+jZ3KStx9dTASL7d7Eekw4sv7ZHv1UN6CPDcKnCNXdPzlBWi5Wc5lWJ4sU1M8ygEQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha1-browser": "5.2.0",
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-node": "^3.972.24",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/middleware-bucket-endpoint": "^3.972.8",
"@aws-sdk/middleware-expect-continue": "^3.972.8",
- "@aws-sdk/middleware-flexible-checksums": "^3.974.3",
+ "@aws-sdk/middleware-flexible-checksums": "^3.974.6",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-location-constraint": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-sdk-s3": "^3.972.23",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-sdk-s3": "^3.972.27",
"@aws-sdk/middleware-ssec": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
- "@aws-sdk/signature-v4-multi-region": "^3.996.11",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.15",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/eventstream-serde-browser": "^4.2.12",
"@smithy/eventstream-serde-config-resolver": "^4.3.12",
"@smithy/eventstream-serde-node": "^4.2.12",
@@ -434,27 +434,27 @@
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/md5-js": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
- "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-stream": "^4.5.21",
"@smithy/util-utf8": "^4.2.2",
- "@smithy/util-waiter": "^4.2.13",
+ "@smithy/util-waiter": "^4.2.14",
"tslib": "^2.6.2"
},
"engines": {
@@ -462,45 +462,45 @@
}
},
"node_modules/@aws-sdk/client-secrets-manager": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.1014.0.tgz",
- "integrity": "sha512-XRp6t0AHGxmCWwYqfELxJUiHnOIR5yUyWBNXJjeEp4t9Pzdg86pQw1aXfmfZ4sVdebT06lL9+D0NsP12ztoSlQ==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.1020.0.tgz",
+ "integrity": "sha512-FRQUPEAeRWK/DO/IJWWVQdmfVYifeNQksrToREokbGjJbCD912eNP5szOtqP7kd52QweznXlfLqv3OeTVnP5Ew==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-node": "^3.972.24",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -512,50 +512,50 @@
}
},
"node_modules/@aws-sdk/client-ses": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.1014.0.tgz",
- "integrity": "sha512-HXLdpIDatHAzEHFoiwwcoYQ5Sx6FP1pkjTwvhgW5zQ+4E69/zC7quQ0dzxX8I38Itvyr8Dq/CmNLUM76XErAVw==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.1020.0.tgz",
+ "integrity": "sha512-UfksKJVrZp4esWxF8GuIBCth++jYpGLqkINj0lQaHq/6kz6u6/Md/q8PlTVmLRQo38NCcb9XKg4G0sKOYN7+Hw==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-node": "^3.972.24",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
"@smithy/util-utf8": "^4.2.2",
- "@smithy/util-waiter": "^4.2.13",
+ "@smithy/util-waiter": "^4.2.14",
"tslib": "^2.6.2"
},
"engines": {
@@ -563,47 +563,47 @@
}
},
"node_modules/@aws-sdk/client-sqs": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1014.0.tgz",
- "integrity": "sha512-xZ/yAd5FtpDyeIRRSXlRV7/PC0wC3vUENBEx5h/j06UkrOosoELp7YguC7ecwvKYeO7mvOO4I94iEhfJspp7Dw==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.1020.0.tgz",
+ "integrity": "sha512-DDKv7bucz6usrvOZ+O6f8mCrm5mTD1yOC9rYDjbUmUPP50S0HLCT6ZVqcXlKaucHcO0l9sWBx8K4jrvMTCkfDg==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-node": "^3.972.24",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-sdk-sqs": "^3.972.17",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-sdk-sqs": "^3.972.18",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/md5-js": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -615,45 +615,45 @@
}
},
"node_modules/@aws-sdk/client-textract": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-textract/-/client-textract-3.1014.0.tgz",
- "integrity": "sha512-go4Wsbz6UrrtbsEMT0urj/zESL9CJ36B6cOMf+WxgOr3qUq/40+hLO30BtIN5C9psyAMVGgNi6Wv9abaejuezQ==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-textract/-/client-textract-3.1020.0.tgz",
+ "integrity": "sha512-7aVLbqnrDeom8Zygv04kcDYdwZR450X4pvR1vF4w6LNZxIBjt4VGhZ4I0Tlvri0KV9aeOPy97xDEKwktDGEgBQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-node": "^3.972.24",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -665,19 +665,19 @@
}
},
"node_modules/@aws-sdk/core": {
- "version": "3.973.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.23.tgz",
- "integrity": "sha512-aoJncvD1XvloZ9JLnKqTRL9dBy+Szkryoag9VT+V1TqsuUgIxV9cnBVM/hrDi2vE8bDqLiDR8nirdRcCdtJu0w==",
+ "version": "3.973.26",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.26.tgz",
+ "integrity": "sha512-A/E6n2W42ruU+sfWk+mMUOyVXbsSgGrY3MJ9/0Az5qUdG67y8I6HYzzoAa+e/lzxxl1uCYmEL6BTMi9ZiZnplQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.6",
- "@aws-sdk/xml-builder": "^3.972.15",
- "@smithy/core": "^3.23.12",
+ "@aws-sdk/xml-builder": "^3.972.16",
+ "@smithy/core": "^3.23.13",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/signature-v4": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-middleware": "^4.2.12",
@@ -702,12 +702,12 @@
}
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.972.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.21.tgz",
- "integrity": "sha512-BkAfKq8Bd4shCtec1usNz//urPJF/SZy14qJyxkSaRJQ/Vv1gVh0VZSTmS7aE6aLMELkFV5wHHrS9ZcdG8Kxsg==",
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.24.tgz",
+ "integrity": "sha512-FWg8uFmT6vQM7VuzELzwVo5bzExGaKHdubn0StjgrcU5FvuLExUe+k06kn/40uKv59rYzhez8eFNM4yYE/Yb/w==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
+ "@aws-sdk/core": "^3.973.26",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/types": "^4.13.1",
@@ -718,20 +718,20 @@
}
},
"node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.972.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.23.tgz",
- "integrity": "sha512-4XZ3+Gu5DY8/n8zQFHBgcKTF7hWQl42G6CY9xfXVo2d25FM/lYkpmuzhYopYoPL1ITWkJ2OSBQfYEu5JRfHOhA==",
+ "version": "3.972.26",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.26.tgz",
+ "integrity": "sha512-CY4ppZ+qHYqcXqBVi//sdHST1QK3KzOEiLtpLsc9W2k2vfZPKExGaQIsOwcyvjpjUEolotitmd3mUNY56IwDEA==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
+ "@aws-sdk/core": "^3.973.26",
"@aws-sdk/types": "^3.973.6",
"@smithy/fetch-http-handler": "^5.3.15",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
- "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-stream": "^4.5.21",
"tslib": "^2.6.2"
},
"engines": {
@@ -739,19 +739,19 @@
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.972.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.23.tgz",
- "integrity": "sha512-PZLSmU0JFpNCDFReidBezsgL5ji9jOBry8CnZdw4Jj6d0K2z3Ftnp44NXgADqYx5BLMu/ZHujfeJReaDoV+IwQ==",
+ "version": "3.972.27",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.27.tgz",
+ "integrity": "sha512-Um26EsNSUfVUX0wUXnUA1W3wzKhVy6nviEElsh5lLZUYj9bk6DXOPnpte0gt+WHubcVfVsRk40bbm4KaroTEag==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/credential-provider-env": "^3.972.21",
- "@aws-sdk/credential-provider-http": "^3.972.23",
- "@aws-sdk/credential-provider-login": "^3.972.23",
- "@aws-sdk/credential-provider-process": "^3.972.21",
- "@aws-sdk/credential-provider-sso": "^3.972.23",
- "@aws-sdk/credential-provider-web-identity": "^3.972.23",
- "@aws-sdk/nested-clients": "^3.996.13",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/credential-provider-env": "^3.972.24",
+ "@aws-sdk/credential-provider-http": "^3.972.26",
+ "@aws-sdk/credential-provider-login": "^3.972.27",
+ "@aws-sdk/credential-provider-process": "^3.972.24",
+ "@aws-sdk/credential-provider-sso": "^3.972.27",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.27",
+ "@aws-sdk/nested-clients": "^3.996.17",
"@aws-sdk/types": "^3.973.6",
"@smithy/credential-provider-imds": "^4.2.12",
"@smithy/property-provider": "^4.2.12",
@@ -764,13 +764,13 @@
}
},
"node_modules/@aws-sdk/credential-provider-login": {
- "version": "3.972.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.23.tgz",
- "integrity": "sha512-OmE/pSkbMM3dCj1HdOnZ5kXnKK+R/Yz+kbBugraBecp0pGAs21eEURfQRz+1N2gzIHLVyGIP1MEjk/uSrFsngg==",
+ "version": "3.972.27",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.27.tgz",
+ "integrity": "sha512-t3ehEtHomGZwg5Gixw4fYbYtG9JBnjfAjSDabxhPEu/KLLUp0BB37/APX7MSKXQhX6ZH7pseuACFJ19NrAkNdg==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/nested-clients": "^3.996.13",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/nested-clients": "^3.996.17",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
@@ -783,17 +783,17 @@
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.972.24",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.24.tgz",
- "integrity": "sha512-9Jwi7aps3AfUicJyF5udYadPypPpCwUZ6BSKr/QjRbVCpRVS1wc+1Q6AEZ/qz8J4JraeRd247pSzyMQSIHVebw==",
+ "version": "3.972.28",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.28.tgz",
+ "integrity": "sha512-rren+P6k5rShG5PX61iVi40kKdueyuMLBRTctQbyR5LooO9Ygr5L6R7ilG7RF1957NSH3KC3TU206fZuKwjSpQ==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "^3.972.21",
- "@aws-sdk/credential-provider-http": "^3.972.23",
- "@aws-sdk/credential-provider-ini": "^3.972.23",
- "@aws-sdk/credential-provider-process": "^3.972.21",
- "@aws-sdk/credential-provider-sso": "^3.972.23",
- "@aws-sdk/credential-provider-web-identity": "^3.972.23",
+ "@aws-sdk/credential-provider-env": "^3.972.24",
+ "@aws-sdk/credential-provider-http": "^3.972.26",
+ "@aws-sdk/credential-provider-ini": "^3.972.27",
+ "@aws-sdk/credential-provider-process": "^3.972.24",
+ "@aws-sdk/credential-provider-sso": "^3.972.27",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.27",
"@aws-sdk/types": "^3.973.6",
"@smithy/credential-provider-imds": "^4.2.12",
"@smithy/property-provider": "^4.2.12",
@@ -806,12 +806,12 @@
}
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.972.21",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.21.tgz",
- "integrity": "sha512-nRxbeOJ1E1gVA0lNQezuMVndx+ZcuyaW/RB05pUsznN5BxykSlH6KkZ/7Ca/ubJf3i5N3p0gwNO5zgPSCzj+ww==",
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.24.tgz",
+ "integrity": "sha512-Q2k/XLrFXhEztPHqj4SLCNID3hEPdlhh1CDLBpNnM+1L8fq7P+yON9/9M1IGN/dA5W45v44ylERfXtDAlmMNmw==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
+ "@aws-sdk/core": "^3.973.26",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -823,14 +823,14 @@
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.972.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.23.tgz",
- "integrity": "sha512-APUccADuYPLL0f2htpM8Z4czabSmHOdo4r41W6lKEZdy++cNJ42Radqy6x4TopENzr3hR6WYMyhiuiqtbf/nAA==",
+ "version": "3.972.27",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.27.tgz",
+ "integrity": "sha512-CWXeGjlbBuHcm9appZUgXKP2zHDyTti0/+gXpSFJ2J3CnSwf1KWjicjN0qG2ozkMH6blrrzMrimeIOEYNl238Q==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/nested-clients": "^3.996.13",
- "@aws-sdk/token-providers": "3.1014.0",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/nested-clients": "^3.996.17",
+ "@aws-sdk/token-providers": "3.1020.0",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -842,13 +842,13 @@
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.972.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.23.tgz",
- "integrity": "sha512-H5JNqtIwOu/feInmMMWcK0dL5r897ReEn7n2m16Dd0DPD9gA2Hg8Cq4UDzZ/9OzaLh/uqBM6seixz0U6Fi2Eag==",
+ "version": "3.972.27",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.27.tgz",
+ "integrity": "sha512-CUY4hQIFswdQNEsRGEzGBUKGMK5KpqmNDdu2ROMgI+45PLFS8H0y3Tm7kvM16uvvw3n1pVxk85tnRVUTgtaa1w==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/nested-clients": "^3.996.13",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/nested-clients": "^3.996.17",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -860,14 +860,15 @@
}
},
"node_modules/@aws-sdk/lib-storage": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1014.0.tgz",
- "integrity": "sha512-mM0/YpIEKKQ1hM9n1Q2HhN1ztjk3oNKqFMYP+cZ57FR3XVU4UOw9Npu7gnjfzkNrS7WTDZMe0wCMuDvvtq1Oeg==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.1020.0.tgz",
+ "integrity": "sha512-SvFM+jukgDkCCeszTtGTJ59kAvWeCI5vnBV0eMau4Uj1w0KItwahDVGDo+xQa+r7pp3kolZF1vDmdv37A5+J8A==",
"license": "Apache-2.0",
"dependencies": {
- "@smithy/abort-controller": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/smithy-client": "^4.12.8",
+ "@smithy/types": "^4.13.1",
"buffer": "5.6.0",
"events": "3.3.0",
"stream-browserify": "3.0.0",
@@ -877,7 +878,7 @@
"node": ">=20.0.0"
},
"peerDependencies": {
- "@aws-sdk/client-s3": "^3.1014.0"
+ "@aws-sdk/client-s3": "^3.1020.0"
}
},
"node_modules/@aws-sdk/middleware-bucket-endpoint": {
@@ -914,15 +915,15 @@
}
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.974.3",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.3.tgz",
- "integrity": "sha512-fB7FNLH1+VPUs0QL3PLrHW+DD4gKu6daFgWtyq3R0Y0Lx8DLZPvyGAxCZNFBxH+M2xt9KvBJX6USwjuqvitmCQ==",
+ "version": "3.974.6",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.6.tgz",
+ "integrity": "sha512-YckB8k1ejbyCg/g36gUMFLNzE4W5cERIa4MtsdO+wpTmJEP0+TB7okWIt7d8TDOvnb7SwvxJ21E4TGOBxFpSWQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/crc32": "5.2.0",
"@aws-crypto/crc32c": "5.2.0",
"@aws-crypto/util": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
+ "@aws-sdk/core": "^3.973.26",
"@aws-sdk/crc64-nvme": "^3.972.5",
"@aws-sdk/types": "^3.973.6",
"@smithy/is-array-buffer": "^4.2.2",
@@ -930,7 +931,7 @@
"@smithy/protocol-http": "^5.3.12",
"@smithy/types": "^4.13.1",
"@smithy/util-middleware": "^4.2.12",
- "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-stream": "^4.5.21",
"@smithy/util-utf8": "^4.2.2",
"tslib": "^2.6.2"
},
@@ -982,9 +983,9 @@
}
},
"node_modules/@aws-sdk/middleware-recursion-detection": {
- "version": "3.972.8",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.8.tgz",
- "integrity": "sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA==",
+ "version": "3.972.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.9.tgz",
+ "integrity": "sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.6",
@@ -998,23 +999,23 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.972.23",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.23.tgz",
- "integrity": "sha512-50QgHGPQAb2veqFOmTF1A3GsAklLHZXL47KbY35khIkfbXH5PLvqpEc/gOAEBPj/yFxrlgxz/8mqWcWTNxBkwQ==",
+ "version": "3.972.27",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.27.tgz",
+ "integrity": "sha512-gomO6DZwx+1D/9mbCpcqO5tPBqYBK7DtdgjTIjZ4yvfh/S7ETwAPS0XbJgP2JD8Ycr5CwVrEkV1sFtu3ShXeOw==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
+ "@aws-sdk/core": "^3.973.26",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-arn-parser": "^3.972.3",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/signature-v4": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/util-config-provider": "^4.2.2",
"@smithy/util-middleware": "^4.2.12",
- "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-stream": "^4.5.21",
"@smithy/util-utf8": "^4.2.2",
"tslib": "^2.6.2"
},
@@ -1023,13 +1024,13 @@
}
},
"node_modules/@aws-sdk/middleware-sdk-sqs": {
- "version": "3.972.17",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.17.tgz",
- "integrity": "sha512-LnzPRRoDXGtlFV2G1p2rsY6fRKrbf6Pvvc21KliSLw3+NmQca2+Aa1QIMRbpQvZYedsSqkGYwxe+qvXwQ2uxDw==",
+ "version": "3.972.18",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.972.18.tgz",
+ "integrity": "sha512-BdsGFuBJUX5PnuZkEV6JRB5g/6ts7iGmN3pXwyoiGCCM2HHXrlFqjkBs+iPX7yO884WqYeQJpme7nwn4DzU5xw==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.6",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/util-hex-encoding": "^4.2.2",
"@smithy/util-utf8": "^4.2.2",
@@ -1054,15 +1055,15 @@
}
},
"node_modules/@aws-sdk/middleware-user-agent": {
- "version": "3.972.24",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.24.tgz",
- "integrity": "sha512-dLTWy6IfAMhNiSEvMr07g/qZ54be6pLqlxVblbF6AzafmmGAzMMj8qMoY9B4+YgT+gY9IcuxZslNh03L6PyMCQ==",
+ "version": "3.972.27",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.27.tgz",
+ "integrity": "sha512-TIRLO5UR2+FVUGmhYoAwVkKhcVzywEDX/5LzR9tjy1h8FQAXOtFg2IqgmwvxU7y933rkTn9rl6AdgcAUgQ1/Kg==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
+ "@aws-sdk/core": "^3.973.26",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/protocol-http": "^5.3.12",
"@smithy/types": "^4.13.1",
"@smithy/util-retry": "^4.2.12",
@@ -1073,44 +1074,44 @@
}
},
"node_modules/@aws-sdk/nested-clients": {
- "version": "3.996.13",
- "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.13.tgz",
- "integrity": "sha512-ptZ1HF4yYHNJX8cgFF+8NdYO69XJKZn7ft0/ynV3c0hCbN+89fAbrLS+fqniU2tW8o9Kfqhj8FUh+IPXb2Qsuw==",
+ "version": "3.996.17",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.17.tgz",
+ "integrity": "sha512-7B0HIX0tEFmOSJuWzdHZj1WhMXSryM+h66h96ZkqSncoY7J6wq61KOu4Kr57b/YnJP3J/EeQYVFulgR281h+7A==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "^3.973.23",
+ "@aws-sdk/core": "^3.973.26",
"@aws-sdk/middleware-host-header": "^3.972.8",
"@aws-sdk/middleware-logger": "^3.972.8",
- "@aws-sdk/middleware-recursion-detection": "^3.972.8",
- "@aws-sdk/middleware-user-agent": "^3.972.24",
- "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.9",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
+ "@aws-sdk/region-config-resolver": "^3.972.10",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-endpoints": "^3.996.5",
"@aws-sdk/util-user-agent-browser": "^3.972.8",
- "@aws-sdk/util-user-agent-node": "^3.973.10",
+ "@aws-sdk/util-user-agent-node": "^3.973.13",
"@smithy/config-resolver": "^4.4.13",
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/fetch-http-handler": "^5.3.15",
"@smithy/hash-node": "^4.2.12",
"@smithy/invalid-dependency": "^4.2.12",
"@smithy/middleware-content-length": "^4.2.12",
- "@smithy/middleware-endpoint": "^4.4.27",
- "@smithy/middleware-retry": "^4.4.44",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-endpoint": "^4.4.28",
+ "@smithy/middleware-retry": "^4.4.45",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/url-parser": "^4.2.12",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-body-length-node": "^4.2.3",
- "@smithy/util-defaults-mode-browser": "^4.3.43",
- "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-defaults-mode-browser": "^4.3.44",
+ "@smithy/util-defaults-mode-node": "^4.2.48",
"@smithy/util-endpoints": "^3.3.3",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -1122,9 +1123,9 @@
}
},
"node_modules/@aws-sdk/region-config-resolver": {
- "version": "3.972.9",
- "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.9.tgz",
- "integrity": "sha512-eQ+dFU05ZRC/lC2XpYlYSPlXtX3VT8sn5toxN2Fv7EXlMoA2p9V7vUBKqHunfD4TRLpxUq8Y8Ol/nCqiv327Ng==",
+ "version": "3.972.10",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.10.tgz",
+ "integrity": "sha512-1dq9ToC6e070QvnVhhbAs3bb5r6cQ10gTVc6cyRV5uvQe7P138TV2uG2i6+Yok4bAkVAcx5AqkTEBUvWEtBlsQ==",
"license": "Apache-2.0",
"dependencies": {
"@aws-sdk/types": "^3.973.6",
@@ -1138,17 +1139,17 @@
}
},
"node_modules/@aws-sdk/s3-request-presigner": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.1014.0.tgz",
- "integrity": "sha512-XEcK50lToSoLPrQztKQhONYQW45613H8oEL00mBUd/+OZgk0+3zJ8kSNDsIJioZ3H7Be+yC3CL6a22dZFIKUXQ==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.1020.0.tgz",
+ "integrity": "sha512-13slasDcOC+Dfi252bcB6MCDavfLP11DsAAxROKr3fyvMTWOh/gFZJyE1a5sBhKAQElzMyqlOLvxPp8cyqvEQQ==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/signature-v4-multi-region": "^3.996.11",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.15",
"@aws-sdk/types": "^3.973.6",
"@aws-sdk/util-format-url": "^3.972.8",
- "@smithy/middleware-endpoint": "^4.4.27",
+ "@smithy/middleware-endpoint": "^4.4.28",
"@smithy/protocol-http": "^5.3.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"tslib": "^2.6.2"
},
@@ -1157,12 +1158,12 @@
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.996.11",
- "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.11.tgz",
- "integrity": "sha512-SKgZY7x6AloLUXO20FJGnkKJ3a6CXzNDt6PYs2yqoPzgU0xKWcUoGGJGEBTsfM5eihKW42lbwp+sXzACLbSsaA==",
+ "version": "3.996.15",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.15.tgz",
+ "integrity": "sha512-Ukw2RpqvaL96CjfH/FgfBmy/ZosHBqoHBCFsN61qGg99F33vpntIVii8aNeh65XuOja73arSduskoa4OJea9RQ==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/middleware-sdk-s3": "^3.972.23",
+ "@aws-sdk/middleware-sdk-s3": "^3.972.27",
"@aws-sdk/types": "^3.973.6",
"@smithy/protocol-http": "^5.3.12",
"@smithy/signature-v4": "^5.3.12",
@@ -1174,13 +1175,13 @@
}
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.1014.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1014.0.tgz",
- "integrity": "sha512-gHTHNUoaOGNrSWkl32A7wFsU78jlNTlqMccLu0byUk5CysYYXaxNMIonIVr4YcykC7vgtDS5ABuz83giy6fzJA==",
+ "version": "3.1020.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1020.0.tgz",
+ "integrity": "sha512-T61KA/VKl0zVUubdxigr1ut7SEpwE1/4CIKb14JDLyTAOne2yWKtQE1dDCSHl0UqrZNwW/bTt+EBHfQbslZJdw==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/core": "^3.973.23",
- "@aws-sdk/nested-clients": "^3.996.13",
+ "@aws-sdk/core": "^3.973.26",
+ "@aws-sdk/nested-clients": "^3.996.17",
"@aws-sdk/types": "^3.973.6",
"@smithy/property-provider": "^4.2.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
@@ -1272,12 +1273,12 @@
}
},
"node_modules/@aws-sdk/util-user-agent-node": {
- "version": "3.973.10",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.10.tgz",
- "integrity": "sha512-E99zeTscCc+pTMfsvnfi6foPpKmdD1cZfOC7/P8UUrjsoQdg9VEWPRD+xdFduKnfPXwcvby58AlO9jwwF6U96g==",
+ "version": "3.973.13",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.13.tgz",
+ "integrity": "sha512-s1dCJ0J9WU9UPkT3FFqhKTSquYTkqWXGRaapHFyWwwJH86ZussewhNST5R5TwXVL1VSHq4aJVl9fWK+svaRVCQ==",
"license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/middleware-user-agent": "^3.972.24",
+ "@aws-sdk/middleware-user-agent": "^3.972.27",
"@aws-sdk/types": "^3.973.6",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/types": "^4.13.1",
@@ -1297,9 +1298,9 @@
}
},
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.972.15",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.15.tgz",
- "integrity": "sha512-PxMRlCFNiQnke9YR29vjFQwz4jq+6Q04rOVFeTDR2K7Qpv9h9FOWOxG+zJjageimYbWqE3bTuLjmryWHAWbvaA==",
+ "version": "3.972.16",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.16.tgz",
+ "integrity": "sha512-iu2pyvaqmeatIJLURLqx9D+4jKAdTH20ntzB6BFwjyN7V960r4jK32mx0Zf7YbtOYAbmbtQfDNuL60ONinyw7A==",
"license": "Apache-2.0",
"dependencies": {
"@smithy/types": "^4.13.1",
@@ -1310,6 +1311,26 @@
"node": ">=20.0.0"
}
},
+ "node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser": {
+ "version": "5.5.8",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz",
+ "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "fast-xml-builder": "^1.1.4",
+ "path-expression-matcher": "^1.2.0",
+ "strnum": "^2.2.0"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
"node_modules/@aws/lambda-invoke-store": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz",
@@ -2915,19 +2936,6 @@
"win32"
]
},
- "node_modules/@smithy/abort-controller": {
- "version": "4.2.12",
- "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.12.tgz",
- "integrity": "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q==",
- "license": "Apache-2.0",
- "dependencies": {
- "@smithy/types": "^4.13.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
"node_modules/@smithy/chunked-blob-reader": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.2.tgz",
@@ -2971,9 +2979,9 @@
}
},
"node_modules/@smithy/core": {
- "version": "3.23.12",
- "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.12.tgz",
- "integrity": "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w==",
+ "version": "3.23.13",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.13.tgz",
+ "integrity": "sha512-J+2TT9D6oGsUVXVEMvz8h2EmdVnkBiy2auCie4aSJMvKlzUtO5hqjEzXhoCUkIMo7gAYjbQcN0g/MMSXEhDs1Q==",
"license": "Apache-2.0",
"dependencies": {
"@smithy/protocol-http": "^5.3.12",
@@ -2982,7 +2990,7 @@
"@smithy/util-base64": "^4.3.2",
"@smithy/util-body-length-browser": "^4.2.2",
"@smithy/util-middleware": "^4.2.12",
- "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-stream": "^4.5.21",
"@smithy/util-utf8": "^4.2.2",
"@smithy/uuid": "^1.1.2",
"tslib": "^2.6.2"
@@ -3191,13 +3199,13 @@
}
},
"node_modules/@smithy/middleware-endpoint": {
- "version": "4.4.27",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.27.tgz",
- "integrity": "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA==",
+ "version": "4.4.28",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.28.tgz",
+ "integrity": "sha512-p1gfYpi91CHcs5cBq982UlGlDrxoYUX6XdHSo91cQ2KFuz6QloHosO7Jc60pJiVmkWrKOV8kFYlGFFbQ2WUKKQ==",
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.23.12",
- "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/core": "^3.23.13",
+ "@smithy/middleware-serde": "^4.2.16",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/shared-ini-file-loader": "^4.4.7",
"@smithy/types": "^4.13.1",
@@ -3210,15 +3218,15 @@
}
},
"node_modules/@smithy/middleware-retry": {
- "version": "4.4.44",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.44.tgz",
- "integrity": "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA==",
+ "version": "4.4.45",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.45.tgz",
+ "integrity": "sha512-td1PxpwDIaw5/oP/xIRxBGxJKoF1L4DBAwbZ8wjMuXBYOP/r2ZE/Ocou+mBHx/yk9knFEtDBwhSrYVn+Mz4pHw==",
"license": "Apache-2.0",
"dependencies": {
"@smithy/node-config-provider": "^4.3.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/service-error-classification": "^4.2.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"@smithy/util-middleware": "^4.2.12",
"@smithy/util-retry": "^4.2.12",
@@ -3230,12 +3238,12 @@
}
},
"node_modules/@smithy/middleware-serde": {
- "version": "4.2.15",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.15.tgz",
- "integrity": "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg==",
+ "version": "4.2.16",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.16.tgz",
+ "integrity": "sha512-beqfV+RZ9RSv+sQqor3xroUUYgRFCGRw6niGstPG8zO9LgTl0B0MCucxjmrH/2WwksQN7UUgI7KNANoZv+KALA==",
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.23.12",
+ "@smithy/core": "^3.23.13",
"@smithy/protocol-http": "^5.3.12",
"@smithy/types": "^4.13.1",
"tslib": "^2.6.2"
@@ -3273,12 +3281,11 @@
}
},
"node_modules/@smithy/node-http-handler": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.5.0.tgz",
- "integrity": "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A==",
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.5.1.tgz",
+ "integrity": "sha512-ejjxdAXjkPIs9lyYyVutOGNOraqUE9v/NjGMKwwFrfOM354wfSD8lmlj8hVwUzQmlLLF4+udhfCX9Exnbmvfzw==",
"license": "Apache-2.0",
"dependencies": {
- "@smithy/abort-controller": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/querystring-builder": "^4.2.12",
"@smithy/types": "^4.13.1",
@@ -3386,17 +3393,17 @@
}
},
"node_modules/@smithy/smithy-client": {
- "version": "4.12.7",
- "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.7.tgz",
- "integrity": "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ==",
+ "version": "4.12.8",
+ "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.8.tgz",
+ "integrity": "sha512-aJaAX7vHe5i66smoSSID7t4rKY08PbD8EBU7DOloixvhOozfYWdcSYE4l6/tjkZ0vBZhGjheWzB2mh31sLgCMA==",
"license": "Apache-2.0",
"dependencies": {
- "@smithy/core": "^3.23.12",
- "@smithy/middleware-endpoint": "^4.4.27",
+ "@smithy/core": "^3.23.13",
+ "@smithy/middleware-endpoint": "^4.4.28",
"@smithy/middleware-stack": "^4.2.12",
"@smithy/protocol-http": "^5.3.12",
"@smithy/types": "^4.13.1",
- "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-stream": "^4.5.21",
"tslib": "^2.6.2"
},
"engines": {
@@ -3493,13 +3500,13 @@
}
},
"node_modules/@smithy/util-defaults-mode-browser": {
- "version": "4.3.43",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.43.tgz",
- "integrity": "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ==",
+ "version": "4.3.44",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.44.tgz",
+ "integrity": "sha512-eZg6XzaCbVr2S5cAErU5eGBDaOVTuTo1I65i4tQcHENRcZ8rMWhQy1DaIYUSLyZjsfXvmCqZrstSMYyGFocvHA==",
"license": "Apache-2.0",
"dependencies": {
"@smithy/property-provider": "^4.2.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"tslib": "^2.6.2"
},
@@ -3508,16 +3515,16 @@
}
},
"node_modules/@smithy/util-defaults-mode-node": {
- "version": "4.2.47",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.47.tgz",
- "integrity": "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ==",
+ "version": "4.2.48",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.48.tgz",
+ "integrity": "sha512-FqOKTlqSaoV3nzO55pMs5NBnZX8EhoI0DGmn9kbYeXWppgHD6dchyuj2HLqp4INJDJbSrj6OFYJkAh/WhSzZPg==",
"license": "Apache-2.0",
"dependencies": {
"@smithy/config-resolver": "^4.4.13",
"@smithy/credential-provider-imds": "^4.2.12",
"@smithy/node-config-provider": "^4.3.12",
"@smithy/property-provider": "^4.2.12",
- "@smithy/smithy-client": "^4.12.7",
+ "@smithy/smithy-client": "^4.12.8",
"@smithy/types": "^4.13.1",
"tslib": "^2.6.2"
},
@@ -3579,13 +3586,13 @@
}
},
"node_modules/@smithy/util-stream": {
- "version": "4.5.20",
- "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.20.tgz",
- "integrity": "sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw==",
+ "version": "4.5.21",
+ "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.21.tgz",
+ "integrity": "sha512-KzSg+7KKywLnkoKejRtIBXDmwBfjGvg1U1i/etkC7XSWUyFCoLno1IohV2c74IzQqdhX5y3uE44r/8/wuK+A7Q==",
"license": "Apache-2.0",
"dependencies": {
"@smithy/fetch-http-handler": "^5.3.15",
- "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/node-http-handler": "^4.5.1",
"@smithy/types": "^4.13.1",
"@smithy/util-base64": "^4.3.2",
"@smithy/util-buffer-from": "^4.2.2",
@@ -3623,12 +3630,11 @@
}
},
"node_modules/@smithy/util-waiter": {
- "version": "4.2.13",
- "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.13.tgz",
- "integrity": "sha512-2zdZ9DTHngRtcYxJK1GUDxruNr53kv5W2Lupe0LMU+Imr6ohQg8M2T14MNkj1Y0wS3FFwpgpGQyvuaMF7CiTmQ==",
+ "version": "4.2.14",
+ "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.14.tgz",
+ "integrity": "sha512-2zqq5o/oizvMaFUlNiTyZ7dbgYv1a893aGut2uaxtbzTx/VYYnRxWzDHuD/ftgcw94ffenua+ZNLrbqwUYE+Bg==",
"license": "Apache-2.0",
"dependencies": {
- "@smithy/abort-controller": "^4.2.12",
"@smithy/types": "^4.13.1",
"tslib": "^2.6.2"
},
@@ -3964,31 +3970,31 @@
"license": "MIT"
},
"node_modules/@vitest/expect": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.0.tgz",
- "integrity": "sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.2.tgz",
+ "integrity": "sha512-gbu+7B0YgUJ2nkdsRJrFFW6X7NTP44WlhiclHniUhxADQJH5Szt9mZ9hWnJPJ8YwOK5zUOSSlSvyzRf0u1DSBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.1.0",
"@types/chai": "^5.2.2",
- "@vitest/spy": "4.1.0",
- "@vitest/utils": "4.1.0",
+ "@vitest/spy": "4.1.2",
+ "@vitest/utils": "4.1.2",
"chai": "^6.2.2",
- "tinyrainbow": "^3.0.3"
+ "tinyrainbow": "^3.1.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/mocker": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.0.tgz",
- "integrity": "sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.2.tgz",
+ "integrity": "sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/spy": "4.1.0",
+ "@vitest/spy": "4.1.2",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.21"
},
@@ -3997,7 +4003,7 @@
},
"peerDependencies": {
"msw": "^2.4.9",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"msw": {
@@ -4009,26 +4015,26 @@
}
},
"node_modules/@vitest/pretty-format": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.0.tgz",
- "integrity": "sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.2.tgz",
+ "integrity": "sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "tinyrainbow": "^3.0.3"
+ "tinyrainbow": "^3.1.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/runner": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.0.tgz",
- "integrity": "sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.2.tgz",
+ "integrity": "sha512-Gr+FQan34CdiYAwpGJmQG8PgkyFVmARK8/xSijia3eTFgVfpcpztWLuP6FttGNfPLJhaZVP/euvujeNYar36OQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/utils": "4.1.0",
+ "@vitest/utils": "4.1.2",
"pathe": "^2.0.3"
},
"funding": {
@@ -4036,14 +4042,14 @@
}
},
"node_modules/@vitest/snapshot": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.0.tgz",
- "integrity": "sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.2.tgz",
+ "integrity": "sha512-g7yfUmxYS4mNxk31qbOYsSt2F4m1E02LFqO53Xpzg3zKMhLAPZAjjfyl9e6z7HrW6LvUdTwAQR3HHfLjpko16A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.0",
- "@vitest/utils": "4.1.0",
+ "@vitest/pretty-format": "4.1.2",
+ "@vitest/utils": "4.1.2",
"magic-string": "^0.30.21",
"pathe": "^2.0.3"
},
@@ -4052,9 +4058,9 @@
}
},
"node_modules/@vitest/spy": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.0.tgz",
- "integrity": "sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.2.tgz",
+ "integrity": "sha512-DU4fBnbVCJGNBwVA6xSToNXrkZNSiw59H8tcuUspVMsBDBST4nfvsPsEHDHGtWRRnqBERBQu7TrTKskmjqTXKA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -4062,15 +4068,15 @@
}
},
"node_modules/@vitest/utils": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.0.tgz",
- "integrity": "sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.2.tgz",
+ "integrity": "sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.0",
+ "@vitest/pretty-format": "4.1.2",
"convert-source-map": "^2.0.0",
- "tinyrainbow": "^3.0.3"
+ "tinyrainbow": "^3.1.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
@@ -4505,14 +4511,14 @@
"license": "MIT"
},
"node_modules/axios": {
- "version": "1.13.6",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz",
- "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz",
+ "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
- "proxy-from-env": "^1.1.0"
+ "proxy-from-env": "^2.1.0"
}
},
"node_modules/axios-curlirize": {
@@ -4699,13 +4705,13 @@
}
},
"node_modules/bullmq": {
- "version": "5.71.0",
- "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.71.0.tgz",
- "integrity": "sha512-aeNWh4drsafSKnAJeiNH/nZP/5O8ZdtdMbnOPZmpjXj7NZUP5YC901U3bIH41iZValm7d1i3c34ojv7q31m30w==",
+ "version": "5.71.1",
+ "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.71.1.tgz",
+ "integrity": "sha512-kOBfdcsHmO6wwmIjpersoVdYQ7jkjTgky4Yop0loc7QwSdgxliSzD69U9ijZuRrkyCJwz5p5eqxeGeQkJ0YGZQ==",
"license": "MIT",
"dependencies": {
"cron-parser": "4.9.0",
- "ioredis": "5.9.3",
+ "ioredis": "5.10.1",
"msgpackr": "1.11.5",
"node-abort-controller": "3.1.1",
"semver": "7.7.4",
@@ -4713,36 +4719,6 @@
"uuid": "11.1.0"
}
},
- "node_modules/bullmq/node_modules/@ioredis/commands": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz",
- "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==",
- "license": "MIT"
- },
- "node_modules/bullmq/node_modules/ioredis": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.9.3.tgz",
- "integrity": "sha512-VI5tMCdeoxZWU5vjHWsiE/Su76JGhBvWF1MJnV9ZtGltHk9BmD48oDq8Tj8haZ85aceXZMxLNDQZRVo5QKNgXA==",
- "license": "MIT",
- "dependencies": {
- "@ioredis/commands": "1.5.0",
- "cluster-key-slot": "^1.1.0",
- "debug": "^4.3.4",
- "denque": "^2.1.0",
- "lodash.defaults": "^4.2.0",
- "lodash.isarguments": "^3.1.0",
- "redis-errors": "^1.2.0",
- "redis-parser": "^3.0.0",
- "standard-as-callback": "^2.1.0"
- },
- "engines": {
- "node": ">=12.22.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/ioredis"
- }
- },
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -6588,9 +6564,9 @@
}
},
"node_modules/fast-xml-parser": {
- "version": "5.5.8",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz",
- "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==",
+ "version": "5.5.9",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.9.tgz",
+ "integrity": "sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==",
"funding": [
{
"type": "github",
@@ -6601,7 +6577,7 @@
"dependencies": {
"fast-xml-builder": "^1.1.4",
"path-expression-matcher": "^1.2.0",
- "strnum": "^2.2.0"
+ "strnum": "^2.2.2"
},
"bin": {
"fxparser": "src/cli/cli.js"
@@ -7328,9 +7304,9 @@
"license": "ISC"
},
"node_modules/graphql": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.1.tgz",
- "integrity": "sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==",
+ "version": "16.13.2",
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz",
+ "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==",
"license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
@@ -9642,10 +9618,13 @@
}
},
"node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "license": "MIT"
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
+ "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
},
"node_modules/punycode": {
"version": "2.3.1",
@@ -10945,9 +10924,9 @@
}
},
"node_modules/strnum": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz",
- "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==",
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz",
+ "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==",
"funding": [
{
"type": "github",
@@ -11237,9 +11216,9 @@
"license": "Unlicense"
},
"node_modules/twilio": {
- "version": "5.13.0",
- "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.13.0.tgz",
- "integrity": "sha512-gg32vK+NGejPK7Txrnwp2lGmpihSfc+YW//WsoS+KiTtiEUe4jjRSK5v89dPhene2OHmnQNi+9SM6bVI47iA/g==",
+ "version": "5.13.1",
+ "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.13.1.tgz",
+ "integrity": "sha512-sT+PkhptF4Mf7t8eXFFvPQx4w5VHnBIPXbltGPMFRe+R2GxfRdMuFbuNA/cEm0aQR6LFQOn33+fhClg+TjRVqQ==",
"license": "MIT",
"dependencies": {
"axios": "^1.13.5",
@@ -11600,19 +11579,19 @@
}
},
"node_modules/vitest": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.0.tgz",
- "integrity": "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.2.tgz",
+ "integrity": "sha512-xjR1dMTVHlFLh98JE3i/f/WePqJsah4A0FK9cc8Ehp9Udk0AZk6ccpIZhh1qJ/yxVWRZ+Q54ocnD8TXmkhspGg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/expect": "4.1.0",
- "@vitest/mocker": "4.1.0",
- "@vitest/pretty-format": "4.1.0",
- "@vitest/runner": "4.1.0",
- "@vitest/snapshot": "4.1.0",
- "@vitest/spy": "4.1.0",
- "@vitest/utils": "4.1.0",
+ "@vitest/expect": "4.1.2",
+ "@vitest/mocker": "4.1.2",
+ "@vitest/pretty-format": "4.1.2",
+ "@vitest/runner": "4.1.2",
+ "@vitest/snapshot": "4.1.2",
+ "@vitest/spy": "4.1.2",
+ "@vitest/utils": "4.1.2",
"es-module-lexer": "^2.0.0",
"expect-type": "^1.3.0",
"magic-string": "^0.30.21",
@@ -11623,8 +11602,8 @@
"tinybench": "^2.9.0",
"tinyexec": "^1.0.2",
"tinyglobby": "^0.2.15",
- "tinyrainbow": "^3.0.3",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0",
+ "tinyrainbow": "^3.1.0",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
"why-is-node-running": "^2.3.0"
},
"bin": {
@@ -11640,13 +11619,13 @@
"@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
- "@vitest/browser-playwright": "4.1.0",
- "@vitest/browser-preview": "4.1.0",
- "@vitest/browser-webdriverio": "4.1.0",
- "@vitest/ui": "4.1.0",
+ "@vitest/browser-playwright": "4.1.2",
+ "@vitest/browser-preview": "4.1.2",
+ "@vitest/browser-webdriverio": "4.1.2",
+ "@vitest/ui": "4.1.2",
"happy-dom": "*",
"jsdom": "*",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"@edge-runtime/vm": {
diff --git a/package.json b/package.json
index 622463441..35c2d8f33 100644
--- a/package.json
+++ b/package.json
@@ -18,25 +18,25 @@
"job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js"
},
"dependencies": {
- "@aws-sdk/client-cloudwatch-logs": "^3.1014.0",
- "@aws-sdk/client-elasticache": "^3.1014.0",
- "@aws-sdk/client-s3": "^3.1014.0",
- "@aws-sdk/client-secrets-manager": "^3.1014.0",
- "@aws-sdk/client-ses": "^3.1014.0",
- "@aws-sdk/client-sqs": "^3.1014.0",
- "@aws-sdk/client-textract": "^3.1014.0",
- "@aws-sdk/credential-provider-node": "^3.972.24",
- "@aws-sdk/lib-storage": "^3.1014.0",
- "@aws-sdk/s3-request-presigner": "^3.1014.0",
+ "@aws-sdk/client-cloudwatch-logs": "^3.1020.0",
+ "@aws-sdk/client-elasticache": "^3.1020.0",
+ "@aws-sdk/client-s3": "^3.1020.0",
+ "@aws-sdk/client-secrets-manager": "^3.1020.0",
+ "@aws-sdk/client-ses": "^3.1020.0",
+ "@aws-sdk/client-sqs": "^3.1020.0",
+ "@aws-sdk/client-textract": "^3.1020.0",
+ "@aws-sdk/credential-provider-node": "^3.972.28",
+ "@aws-sdk/lib-storage": "^3.1020.0",
+ "@aws-sdk/s3-request-presigner": "^3.1020.0",
"@opensearch-project/opensearch": "^2.13.0",
"@socket.io/admin-ui": "^0.5.1",
"@socket.io/redis-adapter": "^8.3.0",
"archiver": "^7.0.1",
"aws4": "^1.13.2",
- "axios": "^1.13.6",
+ "axios": "^1.14.0",
"axios-curlirize": "^2.0.0",
"better-queue": "^3.8.12",
- "bullmq": "^5.71.0",
+ "bullmq": "^5.71.1",
"chart.js": "^4.5.1",
"cloudinary": "^2.9.0",
"compression": "^1.8.1",
@@ -46,10 +46,10 @@
"dinero.js": "^1.9.1",
"dotenv": "^17.3.1",
"express": "^4.21.1",
- "fast-xml-parser": "^5.5.8",
+ "fast-xml-parser": "^5.5.9",
"firebase-admin": "^13.7.0",
"fuse.js": "^7.1.0",
- "graphql": "^16.13.1",
+ "graphql": "^16.13.2",
"graphql-request": "^6.1.0",
"intuit-oauth": "^4.2.2",
"ioredis": "^5.10.1",
@@ -73,7 +73,7 @@
"socket.io": "^4.8.3",
"socket.io-adapter": "^2.5.6",
"ssh2-sftp-client": "^11.0.0",
- "twilio": "^5.13.0",
+ "twilio": "^5.13.1",
"uuid": "^11.1.0",
"winston": "^3.19.0",
"winston-cloudwatch": "^6.3.0",
@@ -91,6 +91,6 @@
"p-limit": "^3.1.0",
"prettier": "^3.8.1",
"supertest": "^7.2.2",
- "vitest": "^4.1.0"
+ "vitest": "^4.1.2"
}
}