Merged in feature/IO-3499-React-19-ProductionBoard (pull request #2826)
Feature/IO-3499 React 19 ProductionBoard
This commit is contained in:
220
client/package-lock.json
generated
220
client/package-lock.json
generated
@@ -9,21 +9,21 @@
|
||||
"version": "0.2.1",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-browser": "^2.33.2",
|
||||
"@amplitude/analytics-browser": "^2.33.4",
|
||||
"@ant-design/pro-layout": "^7.22.6",
|
||||
"@apollo/client": "^4.0.13",
|
||||
"@emotion/is-prop-valid": "^1.4.0",
|
||||
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
||||
"@firebase/analytics": "^0.10.19",
|
||||
"@firebase/app": "^0.14.6",
|
||||
"@firebase/app": "^0.14.7",
|
||||
"@firebase/auth": "^1.12.0",
|
||||
"@firebase/firestore": "^4.9.3",
|
||||
"@firebase/firestore": "^4.10.0",
|
||||
"@firebase/messaging": "^0.12.22",
|
||||
"@jsreport/browser-client": "^3.1.0",
|
||||
"@reduxjs/toolkit": "^2.11.2",
|
||||
"@sentry/cli": "^3.1.0",
|
||||
"@sentry/react": "^10.33.0",
|
||||
"@sentry/vite-plugin": "^4.6.1",
|
||||
"@sentry/react": "^10.34.0",
|
||||
"@sentry/vite-plugin": "^4.6.2",
|
||||
"@splitsoftware/splitio-react": "^2.6.1",
|
||||
"@tanem/react-nprogress": "^5.0.56",
|
||||
"antd": "^6.2.0",
|
||||
@@ -51,7 +51,7 @@
|
||||
"normalize-url": "^8.1.1",
|
||||
"object-hash": "^3.0.0",
|
||||
"phone": "^3.1.69",
|
||||
"posthog-js": "^1.321.0",
|
||||
"posthog-js": "^1.322.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"query-string": "^9.3.1",
|
||||
"raf-schd": "^4.0.3",
|
||||
@@ -86,7 +86,6 @@
|
||||
"sass": "^1.97.2",
|
||||
"socket.io-client": "^4.8.3",
|
||||
"styled-components": "^6.3.6",
|
||||
"use-memo-one": "^1.1.3",
|
||||
"vite-plugin-ejs": "^1.7.0",
|
||||
"web-vitals": "^5.1.0"
|
||||
},
|
||||
@@ -112,7 +111,7 @@
|
||||
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
|
||||
"globals": "^17.0.0",
|
||||
"jsdom": "^27.4.0",
|
||||
"memfs": "^4.51.1",
|
||||
"memfs": "^4.52.0",
|
||||
"os-browserify": "^0.3.0",
|
||||
"playwright": "^1.57.0",
|
||||
"react-error-overlay": "^6.1.0",
|
||||
@@ -121,7 +120,7 @@
|
||||
"vite": "^7.3.1",
|
||||
"vite-plugin-babel": "^1.4.1",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-node-polyfills": "^0.24.0",
|
||||
"vite-plugin-node-polyfills": "^0.25.0",
|
||||
"vite-plugin-pwa": "^1.2.0",
|
||||
"vite-plugin-style-import": "^2.0.0",
|
||||
"vitest": "^4.0.17",
|
||||
@@ -149,17 +148,17 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@amplitude/analytics-browser": {
|
||||
"version": "2.33.2",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.33.2.tgz",
|
||||
"integrity": "sha512-TOVa3oqHQqKJbceMix+fucUvaAe70Mq3eMK2lANz3GHrry/xrzuc/M8HpxdSwDbR1XG6BGKrd4vHREc945z56g==",
|
||||
"version": "2.33.4",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.33.4.tgz",
|
||||
"integrity": "sha512-5oeZ3fsxbXiE6S7Jq/bsYn10DJ+IPSY1dC08PO2kD9cfaviWtXVrehSwThitEZGKHGs4NeJXCGS1xAhOLR2g0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-core": "2.35.1",
|
||||
"@amplitude/plugin-autocapture-browser": "1.18.4",
|
||||
"@amplitude/plugin-network-capture-browser": "1.7.4",
|
||||
"@amplitude/plugin-page-url-enrichment-browser": "0.5.10",
|
||||
"@amplitude/plugin-page-view-tracking-browser": "2.6.7",
|
||||
"@amplitude/plugin-web-vitals-browser": "1.1.5",
|
||||
"@amplitude/analytics-core": "2.36.0",
|
||||
"@amplitude/plugin-autocapture-browser": "1.18.6",
|
||||
"@amplitude/plugin-network-capture-browser": "1.7.6",
|
||||
"@amplitude/plugin-page-url-enrichment-browser": "0.5.12",
|
||||
"@amplitude/plugin-page-view-tracking-browser": "2.6.9",
|
||||
"@amplitude/plugin-web-vitals-browser": "1.1.7",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
@@ -170,9 +169,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@amplitude/analytics-core": {
|
||||
"version": "2.35.1",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.35.1.tgz",
|
||||
"integrity": "sha512-ZChD4oUtpbO6W5YhWZ0G9BbqVOx7DoX1+cPyAMFwFkglH6JrZCrKvUTrukhVpVB+wkLRRK1ZviN0PzP6mDaifw==",
|
||||
"version": "2.36.0",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.36.0.tgz",
|
||||
"integrity": "sha512-VPkqVK7PZBwkatD22Xu0kshtLeM8bd6KjCsFcnje0FA/LHgixYw1O4ihWpPlUzDNMIXSb2+opN3SkINImmBOnQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-connector": "^1.6.4",
|
||||
@@ -181,52 +180,52 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-autocapture-browser": {
|
||||
"version": "1.18.4",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-autocapture-browser/-/plugin-autocapture-browser-1.18.4.tgz",
|
||||
"integrity": "sha512-D4BzLjTjT7+Q2TEA0US9THlKPDpukcyIkjknsa9jRhWyLhirnwKEnf5w3WhX+g2psfnq+zY0UjCboQ+WCDL0Zw==",
|
||||
"version": "1.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-autocapture-browser/-/plugin-autocapture-browser-1.18.6.tgz",
|
||||
"integrity": "sha512-8oZ0jGHjs9Sm98L7l2X5nVjT/qAv+ezk/eibYdHiwA10haHRjXc+v4cFuGeboQkSd87gWvD4LyA7iamVUUak/Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-core": "2.35.1",
|
||||
"@amplitude/analytics-core": "2.36.0",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-network-capture-browser": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-network-capture-browser/-/plugin-network-capture-browser-1.7.4.tgz",
|
||||
"integrity": "sha512-en86lEWMNkQOPm64yYnBjOI3qyHxAmhKZF+zgxdxwHM4vOQ8M1ySxVitCyd0GJiLmdEHEWj0PWgPAVkkj7BjBQ==",
|
||||
"version": "1.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-network-capture-browser/-/plugin-network-capture-browser-1.7.6.tgz",
|
||||
"integrity": "sha512-FJMdpeOV9e4+TYUfUTSIuBuBU4dLRwB7Qq/tFbFHEogAH8NFcsYKxe0rAWmTqMTmKxb2SHTIEC35D+aWVJzWCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-core": "2.35.1",
|
||||
"@amplitude/analytics-core": "2.36.0",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-page-url-enrichment-browser": {
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-page-url-enrichment-browser/-/plugin-page-url-enrichment-browser-0.5.10.tgz",
|
||||
"integrity": "sha512-lgp2uwz2UPXxJypYMgiQ5yHhoTIQ6QaZQu8yq//9sogkMkDt0ClybTYwRk3N1q/XVS1cR79vT68gtvzdLD62Lg==",
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-page-url-enrichment-browser/-/plugin-page-url-enrichment-browser-0.5.12.tgz",
|
||||
"integrity": "sha512-FMPaY+apoyULJSzTMdz2UQ0c8Ry3J/m1yD9sjsRy2VGhbXyLFV5zrfcHkiIZAtDHy2sVpsv130j1eGZIK2aqZw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-core": "2.35.1",
|
||||
"@amplitude/analytics-core": "2.36.0",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-page-view-tracking-browser": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.6.7.tgz",
|
||||
"integrity": "sha512-cSiKOAJkgqI/h3+rjVXVvegrK2cma9XPxtWnBvShGbmVzh+ekIUrKktUFLsmxxFzkY94VVsVWiSGovQsKa8RuA==",
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.6.9.tgz",
|
||||
"integrity": "sha512-LfV+4t8V7Kq6TKecaggC2rOszE9sVTs73xPok1UXGvlvVkY+KaEc9ngkansBOKCfCU7inNaIMlGRj1YZDrEjjA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-core": "2.35.1",
|
||||
"@amplitude/analytics-core": "2.36.0",
|
||||
"tslib": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@amplitude/plugin-web-vitals-browser": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-web-vitals-browser/-/plugin-web-vitals-browser-1.1.5.tgz",
|
||||
"integrity": "sha512-6tcaSi5nM5pd6/bcMl90+LSR4cCsqFLP2SG9RUy+bHQN/DCh+Nzq1X+5a1St+MqX8Qr6s4q6YHbkIUcEMHo+Zg==",
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@amplitude/plugin-web-vitals-browser/-/plugin-web-vitals-browser-1.1.7.tgz",
|
||||
"integrity": "sha512-n1zOsE1RFE3y2IN1OUKTZYQnR7NZMATarHjBsf/tJ+6fQ2g5QDwyTRLzBHmdUcsLe559+ek9QTtIhXmbBOXR3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-core": "2.35.1",
|
||||
"@amplitude/analytics-core": "2.36.0",
|
||||
"tslib": "^2.4.1",
|
||||
"web-vitals": "5.1.0"
|
||||
}
|
||||
@@ -3360,9 +3359,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@firebase/app": {
|
||||
"version": "0.14.6",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.6.tgz",
|
||||
"integrity": "sha512-4uyt8BOrBsSq6i4yiOV/gG6BnnrvTeyymlNcaN/dKvyU1GoolxAafvIvaNP1RCGPlNab3OuE4MKUQuv2lH+PLQ==",
|
||||
"version": "0.14.7",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.7.tgz",
|
||||
"integrity": "sha512-o3ZfnOx0AWBD5n/36p2zPoB0rDDxQP8H/A60zDLvvfRLtW8b3LfCyV97GKpJaAVV1JMMl/BC89EDzMyzxFZxTw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/component": "0.7.0",
|
||||
@@ -3413,9 +3412,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@firebase/firestore": {
|
||||
"version": "4.9.3",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.9.3.tgz",
|
||||
"integrity": "sha512-RVuvhcQzs1sD5Osr2naQS71H0bQMbSnib16uOWAKk3GaKb/WBPyCYSr2Ry7MqlxDP/YhwknUxECL07lw9Rq1nA==",
|
||||
"version": "4.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.10.0.tgz",
|
||||
"integrity": "sha512-fgF6EbpoagGWh5Vwfu/7/jYgBFwUCwTlPNVF/aSjHcoEDRXpRsIqVfAFTp1LD+dWAUcAKEK3h+osk8spMJXtxA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@firebase/component": "0.7.0",
|
||||
@@ -4565,9 +4564,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/types": {
|
||||
"version": "1.321.0",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.321.0.tgz",
|
||||
"integrity": "sha512-dNxsez/AqV3dt/UO6h5aJ+qBj7Tj0a17hqc9zE1XvvlXxpVFuk0EFsSlxtrBNumWWxh29jINw0x0YitrozNqIQ==",
|
||||
"version": "1.322.0",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.322.0.tgz",
|
||||
"integrity": "sha512-oaGT0yshq1hdulGXzIYGPmv8TiRPBdNMlrdrAJRTkT+t7LcRRIfNGZ8VCvgXvRAKKfe0KSobl8SkJm+TJ1qX6Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
@@ -6334,88 +6333,88 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@sentry-internal/browser-utils": {
|
||||
"version": "10.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.33.0.tgz",
|
||||
"integrity": "sha512-nDJFHAfiFifBfJB0OF6DV6BIsIV5uah4lDsV4UBAgPBf+YAHclO10y1gi2U/JMh58c+s4lXi9p+PI1TFXZ0c6w==",
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.34.0.tgz",
|
||||
"integrity": "sha512-0YNr60rGHyedmwkO0lbDBjNx2KAmT3kWamjaqu7Aw+jsESoPLgt+fzaTVvUBvkftBDui2PeTSzXm/nqzssctYg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/core": "10.33.0"
|
||||
"@sentry/core": "10.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/feedback": {
|
||||
"version": "10.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.33.0.tgz",
|
||||
"integrity": "sha512-sN/VLWtEf0BeV6w6wldIpTxUQxNVc9o9tjLRQa8je1ZV2FCgXA124Iff/zsowsz82dLqtg7qp6GA5zYXVq+JMA==",
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.34.0.tgz",
|
||||
"integrity": "sha512-wgGnq+iNxsFSOe9WX/FOvtoItSTjgLJJ4dQkVYtcVM6WGBVIg4wgNYfECCnRNztUTPzpZHLjC9r+4Pym451DDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/core": "10.33.0"
|
||||
"@sentry/core": "10.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/replay": {
|
||||
"version": "10.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.33.0.tgz",
|
||||
"integrity": "sha512-UOU9PYxuXnPop3HoQ3l4Q7SZUXJC3Vmfm0Adgad8U03UcrThWIHYc5CxECSrVzfDFNOT7w9o7HQgRAgWxBPMXg==",
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.34.0.tgz",
|
||||
"integrity": "sha512-Vmea0GcOg57z/S1bVSj3saFcRvDqdLzdy4wd9fQMpMgy5OCbTlo7lxVUndKzbcZnanma6zF6VxwnWER1WuN9RA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry-internal/browser-utils": "10.33.0",
|
||||
"@sentry/core": "10.33.0"
|
||||
"@sentry-internal/browser-utils": "10.34.0",
|
||||
"@sentry/core": "10.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/replay-canvas": {
|
||||
"version": "10.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.33.0.tgz",
|
||||
"integrity": "sha512-MTmP6uoAVzw4CCPeqCgCLsRSiOfGLxgyMFjGTCW3E7t62MJ9S0H5sLsQ34sHxXUa1gFU9UNAjEvRRpZ0JvWrPw==",
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.34.0.tgz",
|
||||
"integrity": "sha512-XWH/9njtgMD+LLWjc4KKgBpb+dTCkoUEIFDxcvzG/87d+jirmzf0+r8EfpLwKG+GrqNiiGRV39zIqu0SfPl+cw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry-internal/replay": "10.33.0",
|
||||
"@sentry/core": "10.33.0"
|
||||
"@sentry-internal/replay": "10.34.0",
|
||||
"@sentry/core": "10.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/babel-plugin-component-annotate": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.6.1.tgz",
|
||||
"integrity": "sha512-aSIk0vgBqv7PhX6/Eov+vlI4puCE0bRXzUG5HdCsHBpAfeMkI8Hva6kSOusnzKqs8bf04hU7s3Sf0XxGTj/1AA==",
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.6.2.tgz",
|
||||
"integrity": "sha512-6VTjLJXtIHKwxMmThtZKwi1+hdklLNzlbYH98NhbH22/Vzb/c6BlSD2b5A0NGN9vFB807rD4x4tuP+Su7BxQXQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/browser": {
|
||||
"version": "10.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.33.0.tgz",
|
||||
"integrity": "sha512-iWiPjik9zetM84jKfk01UveW1J0+X7w8XmJ8+IrhTyNDBVUWCRJWD8FrksiN1dRSg5mFWgfMRzKMz27hAScRwg==",
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.34.0.tgz",
|
||||
"integrity": "sha512-8WCsAXli5Z+eIN8dMY8KGQjrS3XgUp1np/pjdeWNrVPVR8q8XpS34qc+f+y/LFrYQC9bs2Of5aIBwRtDCIvRsg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry-internal/browser-utils": "10.33.0",
|
||||
"@sentry-internal/feedback": "10.33.0",
|
||||
"@sentry-internal/replay": "10.33.0",
|
||||
"@sentry-internal/replay-canvas": "10.33.0",
|
||||
"@sentry/core": "10.33.0"
|
||||
"@sentry-internal/browser-utils": "10.34.0",
|
||||
"@sentry-internal/feedback": "10.34.0",
|
||||
"@sentry-internal/replay": "10.34.0",
|
||||
"@sentry-internal/replay-canvas": "10.34.0",
|
||||
"@sentry/core": "10.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/bundler-plugin-core": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.6.1.tgz",
|
||||
"integrity": "sha512-WPeRbnMXm927m4Kr69NTArPfI+p5/34FHftdCRI3LFPMyhZDzz6J3wLy4hzaVUgmMf10eLzmq2HGEMvpQmdynA==",
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.6.2.tgz",
|
||||
"integrity": "sha512-JkOc3JkVzi/fbXsFp8R9uxNKmBrPRaU4Yu4y1i3ihWfugqymsIYaN0ixLENZbGk2j4xGHIk20PAJzBJqBMTHew==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.18.5",
|
||||
"@sentry/babel-plugin-component-annotate": "4.6.1",
|
||||
"@sentry/babel-plugin-component-annotate": "4.6.2",
|
||||
"@sentry/cli": "^2.57.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"find-up": "^5.0.0",
|
||||
@@ -6811,22 +6810,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/core": {
|
||||
"version": "10.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.33.0.tgz",
|
||||
"integrity": "sha512-ehH1VSUclIHZKEZVdv+klofsFIh8FFzqA6AAV23RtLepptzA8wqQzUGraEuSN25sYcNmYJ0jti5U0Ys+WZv5Dw==",
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.34.0.tgz",
|
||||
"integrity": "sha512-4FFpYBMf0VFdPcsr4grDYDOR87mRu6oCfb51oQjU/Pndmty7UgYo0Bst3LEC/8v0SpytBtzXq+Wx/fkwulBesg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/react": {
|
||||
"version": "10.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.33.0.tgz",
|
||||
"integrity": "sha512-iMdC2Iw54ibAccatJ5TjoLlIy3VotFteied7JFvOudgj1/2eBBeWthRobZ5p6/nAOpj4p9vJk0DeLrc012sd2g==",
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.34.0.tgz",
|
||||
"integrity": "sha512-LDpg9WDrEwo6lr/YOAA54id/g5D1PGKEIiOGxqRZbBVyjzrsquwzhSG2CMqnp+YO6lz/r96LWuqm2cvfpht2zA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/browser": "10.33.0",
|
||||
"@sentry/core": "10.33.0"
|
||||
"@sentry/browser": "10.34.0",
|
||||
"@sentry/core": "10.34.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -6836,12 +6835,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/vite-plugin": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.6.1.tgz",
|
||||
"integrity": "sha512-Qvys1y3o8/bfL3ikrHnJS9zxdjt0z3POshdBl3967UcflrTqBmnGNkcVk53SlmtJWIfh85fgmrLvGYwZ2YiqNg==",
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.6.2.tgz",
|
||||
"integrity": "sha512-hK9N50LlTaPlb2P1r87CFupU7MJjvtrp+Js96a2KDdiP8ViWnw4Gsa/OvA0pkj2wAFXFeBQMLS6g/SktTKG54w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sentry/bundler-plugin-core": "4.6.1",
|
||||
"@sentry/bundler-plugin-core": "4.6.2",
|
||||
"unplugin": "1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -13178,9 +13177,9 @@
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/memfs": {
|
||||
"version": "4.51.1",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-4.51.1.tgz",
|
||||
"integrity": "sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ==",
|
||||
"version": "4.52.0",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-4.52.0.tgz",
|
||||
"integrity": "sha512-dG5ZY1wUCPWhtl4M2mlc7Wx4OrMGtiI79axnScxwDoPR/25biQYrYm21OpKyZcnKv8pvWaX95SRtZgecZ84gFg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -14699,9 +14698,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/posthog-js": {
|
||||
"version": "1.321.0",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.321.0.tgz",
|
||||
"integrity": "sha512-IFdm/iBoFHltHwdZ/qjtni4RAtFCU6NEt6QTNOzBcuAk5srAFQBb7o+8MxryGON7EXLKCbAA6hueksHFB/WY/A==",
|
||||
"version": "1.322.0",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.322.0.tgz",
|
||||
"integrity": "sha512-vNNcWp2NpFMX8nqf06uZ49OzGjj9tqh1F25ls9YegXCeCIpT37sYPSFI4GiyQAaunUXd1IR2L5iWK/zGGhVESA==",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
@@ -14710,7 +14709,7 @@
|
||||
"@opentelemetry/resources": "^2.2.0",
|
||||
"@opentelemetry/sdk-logs": "^0.208.0",
|
||||
"@posthog/core": "1.9.1",
|
||||
"@posthog/types": "1.321.0",
|
||||
"@posthog/types": "1.322.0",
|
||||
"core-js": "^3.38.1",
|
||||
"dompurify": "^3.3.1",
|
||||
"fflate": "^0.4.8",
|
||||
@@ -17941,15 +17940,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/use-memo-one": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz",
|
||||
"integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-sync-external-store": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
|
||||
@@ -18161,14 +18151,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-node-polyfills": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.24.0.tgz",
|
||||
"integrity": "sha512-GA9QKLH+vIM8NPaGA+o2t8PDfFUl32J8rUp1zQfMKVJQiNkOX4unE51tR6ppl6iKw5yOrDAdSH7r/UIFLCVhLw==",
|
||||
"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==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/plugin-inject": "^5.0.5",
|
||||
"node-stdlib-browser": "^1.2.0"
|
||||
"node-stdlib-browser": "^1.3.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/davidmyersdev"
|
||||
|
||||
@@ -8,21 +8,21 @@
|
||||
"private": true,
|
||||
"proxy": "http://localhost:4000",
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-browser": "^2.33.2",
|
||||
"@amplitude/analytics-browser": "^2.33.4",
|
||||
"@ant-design/pro-layout": "^7.22.6",
|
||||
"@apollo/client": "^4.0.13",
|
||||
"@emotion/is-prop-valid": "^1.4.0",
|
||||
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
||||
"@firebase/analytics": "^0.10.19",
|
||||
"@firebase/app": "^0.14.6",
|
||||
"@firebase/app": "^0.14.7",
|
||||
"@firebase/auth": "^1.12.0",
|
||||
"@firebase/firestore": "^4.9.3",
|
||||
"@firebase/firestore": "^4.10.0",
|
||||
"@firebase/messaging": "^0.12.22",
|
||||
"@jsreport/browser-client": "^3.1.0",
|
||||
"@reduxjs/toolkit": "^2.11.2",
|
||||
"@sentry/cli": "^3.1.0",
|
||||
"@sentry/react": "^10.33.0",
|
||||
"@sentry/vite-plugin": "^4.6.1",
|
||||
"@sentry/react": "^10.34.0",
|
||||
"@sentry/vite-plugin": "^4.6.2",
|
||||
"@splitsoftware/splitio-react": "^2.6.1",
|
||||
"@tanem/react-nprogress": "^5.0.56",
|
||||
"antd": "^6.2.0",
|
||||
@@ -50,7 +50,7 @@
|
||||
"normalize-url": "^8.1.1",
|
||||
"object-hash": "^3.0.0",
|
||||
"phone": "^3.1.69",
|
||||
"posthog-js": "^1.321.0",
|
||||
"posthog-js": "^1.322.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"query-string": "^9.3.1",
|
||||
"raf-schd": "^4.0.3",
|
||||
@@ -85,7 +85,6 @@
|
||||
"sass": "^1.97.2",
|
||||
"socket.io-client": "^4.8.3",
|
||||
"styled-components": "^6.3.6",
|
||||
"use-memo-one": "^1.1.3",
|
||||
"vite-plugin-ejs": "^1.7.0",
|
||||
"web-vitals": "^5.1.0"
|
||||
},
|
||||
@@ -154,7 +153,7 @@
|
||||
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
|
||||
"globals": "^17.0.0",
|
||||
"jsdom": "^27.4.0",
|
||||
"memfs": "^4.51.1",
|
||||
"memfs": "^4.52.0",
|
||||
"os-browserify": "^0.3.0",
|
||||
"playwright": "^1.57.0",
|
||||
"react-error-overlay": "^6.1.0",
|
||||
@@ -163,7 +162,7 @@
|
||||
"vite": "^7.3.1",
|
||||
"vite-plugin-babel": "^1.4.1",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-node-polyfills": "^0.24.0",
|
||||
"vite-plugin-node-polyfills": "^0.25.0",
|
||||
"vite-plugin-pwa": "^1.2.0",
|
||||
"vite-plugin-style-import": "^2.0.0",
|
||||
"vitest": "^4.0.17",
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
} from "@ant-design/icons";
|
||||
import { Card, Col, Row, Space, Tooltip } from "antd";
|
||||
import Dinero from "dinero.js";
|
||||
import { memo, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
@@ -45,7 +44,7 @@ const getContrastYIQ = (bgColor, isDarkMode = document.documentElement.getAttrib
|
||||
|
||||
const findEmployeeById = (employees, id) => employees.find((e) => e.id === id);
|
||||
|
||||
const EllipsesToolTip = memo(({ title, children, kiosk }) => {
|
||||
function EllipsesToolTip({ title, children, kiosk }) {
|
||||
if (kiosk || !title) {
|
||||
return <div className="ellipses no-select">{children}</div>;
|
||||
}
|
||||
@@ -54,9 +53,7 @@ const EllipsesToolTip = memo(({ title, children, kiosk }) => {
|
||||
<div className="ellipses">{children}</div>
|
||||
</Tooltip>
|
||||
);
|
||||
});
|
||||
|
||||
EllipsesToolTip.displayName = "EllipsesToolTip";
|
||||
}
|
||||
|
||||
const OwnerNameToolTip = ({ metadata, cardSettings }) =>
|
||||
cardSettings?.ownr_nm && (
|
||||
@@ -330,47 +327,47 @@ const PartsReceivedComponent = ({ metadata, cardSettings, card }) =>
|
||||
export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings }) {
|
||||
const { t } = useTranslation();
|
||||
const { metadata } = card;
|
||||
const employees = useMemo(() => bodyshop.employees, [bodyshop.employees]);
|
||||
const { employee_body, employee_prep, employee_refinish, employee_csr } = useMemo(() => {
|
||||
return {
|
||||
employee_body: metadata?.employee_body && findEmployeeById(employees, metadata.employee_body),
|
||||
employee_prep: metadata?.employee_prep && findEmployeeById(employees, metadata.employee_prep),
|
||||
employee_refinish: metadata?.employee_refinish && findEmployeeById(employees, metadata.employee_refinish),
|
||||
employee_csr: metadata?.employee_csr && findEmployeeById(employees, metadata.employee_csr)
|
||||
};
|
||||
}, [metadata, employees]);
|
||||
const pastDueAlert = useMemo(() => {
|
||||
if (!metadata?.scheduled_completion) return null;
|
||||
const employees = bodyshop.employees;
|
||||
|
||||
const employee_body = metadata?.employee_body && findEmployeeById(employees, metadata.employee_body);
|
||||
const employee_prep = metadata?.employee_prep && findEmployeeById(employees, metadata.employee_prep);
|
||||
const employee_refinish = metadata?.employee_refinish && findEmployeeById(employees, metadata.employee_refinish);
|
||||
const employee_csr = metadata?.employee_csr && findEmployeeById(employees, metadata.employee_csr);
|
||||
|
||||
let pastDueAlert = null;
|
||||
if (metadata?.scheduled_completion) {
|
||||
const completionDate = dayjs(metadata.scheduled_completion);
|
||||
if (dayjs().isSameOrAfter(completionDate, "day")) return "production-completion-past";
|
||||
if (dayjs().add(1, "day").isSame(completionDate, "day")) return "production-completion-soon";
|
||||
return null;
|
||||
}, [metadata?.scheduled_completion]);
|
||||
const totalHrs = useMemo(() => {
|
||||
return metadata?.labhrs && metadata?.larhrs
|
||||
if (dayjs().isSameOrAfter(completionDate, "day")) {
|
||||
pastDueAlert = "production-completion-past";
|
||||
} else if (dayjs().add(1, "day").isSame(completionDate, "day")) {
|
||||
pastDueAlert = "production-completion-soon";
|
||||
}
|
||||
}
|
||||
|
||||
const totalHrs =
|
||||
metadata?.labhrs && metadata?.larhrs
|
||||
? metadata.labhrs.aggregate.sum.mod_lb_hrs + metadata.larhrs.aggregate.sum.mod_lb_hrs
|
||||
: 0;
|
||||
}, [metadata?.labhrs, metadata?.larhrs]);
|
||||
const bgColor = useMemo(() => cardColor(bodyshop.ssbuckets, totalHrs), [bodyshop.ssbuckets, totalHrs]);
|
||||
const contrastYIQ = useMemo(() => getContrastYIQ(bgColor), [bgColor]);
|
||||
const isBodyEmpty = useMemo(() => {
|
||||
return !(
|
||||
cardSettings?.ownr_nm ||
|
||||
cardSettings?.model_info ||
|
||||
cardSettings?.ins_co_nm ||
|
||||
cardSettings?.clm_no ||
|
||||
cardSettings?.employeeassignments ||
|
||||
cardSettings?.actual_in ||
|
||||
cardSettings?.scheduled_completion ||
|
||||
cardSettings?.ats ||
|
||||
cardSettings?.sublets ||
|
||||
cardSettings?.production_note ||
|
||||
cardSettings?.partsstatus ||
|
||||
cardSettings?.estimator ||
|
||||
cardSettings?.subtotal ||
|
||||
cardSettings?.tasks
|
||||
);
|
||||
}, [cardSettings]);
|
||||
|
||||
const bgColor = cardColor(bodyshop.ssbuckets, totalHrs);
|
||||
const contrastYIQ = getContrastYIQ(bgColor);
|
||||
|
||||
const isBodyEmpty = !(
|
||||
cardSettings?.ownr_nm ||
|
||||
cardSettings?.model_info ||
|
||||
cardSettings?.ins_co_nm ||
|
||||
cardSettings?.clm_no ||
|
||||
cardSettings?.employeeassignments ||
|
||||
cardSettings?.actual_in ||
|
||||
cardSettings?.scheduled_completion ||
|
||||
cardSettings?.ats ||
|
||||
cardSettings?.sublets ||
|
||||
cardSettings?.production_note ||
|
||||
cardSettings?.partsstatus ||
|
||||
cardSettings?.estimator ||
|
||||
cardSettings?.subtotal ||
|
||||
cardSettings?.tasks
|
||||
);
|
||||
|
||||
const headerContent = (
|
||||
<div className="header-content-container">
|
||||
|
||||
@@ -2,9 +2,7 @@ import { SyncOutlined } from "@ant-design/icons";
|
||||
import { PageHeader } from "@ant-design/pro-layout";
|
||||
import { useApolloClient } from "@apollo/client/react";
|
||||
import { Button, Skeleton, Space } from "antd";
|
||||
import cloneDeep from "lodash/cloneDeep";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
@@ -74,17 +72,11 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
title: `${lane.title} (${lane.cards.length})`
|
||||
}));
|
||||
|
||||
setBoardLanes((prevBoardLanes) => {
|
||||
const deepClonedData = cloneDeep(newBoardData);
|
||||
if (!isEqual(prevBoardLanes, deepClonedData)) {
|
||||
return deepClonedData;
|
||||
}
|
||||
return prevBoardLanes;
|
||||
});
|
||||
setBoardLanes(newBoardData);
|
||||
setIsMoving(false);
|
||||
}, [data, bodyshop.md_ro_statuses, filter, statuses, associationSettings?.kanban_settings]);
|
||||
|
||||
const getCardByID = useCallback((data, cardId) => {
|
||||
const getCardByID = (data, cardId) => {
|
||||
for (const lane of data.lanes) {
|
||||
for (const card of lane.cards) {
|
||||
if (card.id === cardId) {
|
||||
@@ -93,102 +85,96 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, []);
|
||||
};
|
||||
|
||||
const onDragEnd = useCallback(
|
||||
async ({ type, source, destination, draggableId }) => {
|
||||
logImEXEvent("kanban_drag_end");
|
||||
const onDragEnd = async ({ type, source, destination, draggableId }) => {
|
||||
logImEXEvent("kanban_drag_end");
|
||||
|
||||
if (!type || type !== "lane" || !source || !destination || isMoving) return;
|
||||
if (!type || type !== "lane" || !source || !destination || isMoving) return;
|
||||
|
||||
setIsMoving(true);
|
||||
setIsMoving(true);
|
||||
|
||||
const targetLane = boardLanes.lanes.find((lane) => lane.id === destination.droppableId);
|
||||
const sourceLane = boardLanes.lanes.find((lane) => lane.id === source.droppableId);
|
||||
const targetLane = boardLanes.lanes.find((lane) => lane.id === destination.droppableId);
|
||||
const sourceLane = boardLanes.lanes.find((lane) => lane.id === source.droppableId);
|
||||
|
||||
if (!targetLane || !sourceLane) {
|
||||
setIsMoving(false);
|
||||
console.error("Invalid source or destination lane");
|
||||
return;
|
||||
}
|
||||
if (!targetLane || !sourceLane) {
|
||||
setIsMoving(false);
|
||||
console.error("Invalid source or destination lane");
|
||||
return;
|
||||
}
|
||||
|
||||
const sameColumnTransfer = source.droppableId === destination.droppableId;
|
||||
const sourceCard = getCardByID(boardLanes, draggableId);
|
||||
const sameColumnTransfer = source.droppableId === destination.droppableId;
|
||||
const sourceCard = getCardByID(boardLanes, draggableId);
|
||||
|
||||
const movedCardWillBeFirst = destination.index === 0;
|
||||
const movedCardWillBeLast = destination.index >= targetLane.cards.length - 1;
|
||||
const movedCardWillBeFirst = destination.index === 0;
|
||||
const movedCardWillBeLast = destination.index >= targetLane.cards.length - 1;
|
||||
|
||||
const lastCardInTargetLane = targetLane.cards[targetLane.cards.length - 1];
|
||||
const oldChildCard = sourceLane.cards[source.index + 1];
|
||||
const lastCardInTargetLane = targetLane.cards[targetLane.cards.length - 1];
|
||||
const oldChildCard = sourceLane.cards[source.index + 1];
|
||||
|
||||
const newChildCard = movedCardWillBeLast
|
||||
? null
|
||||
: targetLane.cards[
|
||||
sameColumnTransfer
|
||||
? source.index < destination.index
|
||||
? destination.index + 1
|
||||
: destination.index
|
||||
const newChildCard = movedCardWillBeLast
|
||||
? null
|
||||
: targetLane.cards[
|
||||
sameColumnTransfer
|
||||
? source.index < destination.index
|
||||
? destination.index + 1
|
||||
: destination.index
|
||||
];
|
||||
: destination.index
|
||||
];
|
||||
|
||||
const oldChildCardNewParent = oldChildCard ? sourceCard.metadata.kanbanparent : null;
|
||||
const oldChildCardNewParent = oldChildCard ? sourceCard.metadata.kanbanparent : null;
|
||||
|
||||
let movedCardNewKanbanParent;
|
||||
if (movedCardWillBeFirst) {
|
||||
movedCardNewKanbanParent = "-1";
|
||||
} else if (movedCardWillBeLast) {
|
||||
movedCardNewKanbanParent = lastCardInTargetLane.id;
|
||||
} else if (newChildCard) {
|
||||
movedCardNewKanbanParent = newChildCard.metadata.kanbanparent;
|
||||
} else {
|
||||
console.error("==> !!!!!!Couldn't find a parent.!!!! <==");
|
||||
}
|
||||
let movedCardNewKanbanParent;
|
||||
if (movedCardWillBeFirst) {
|
||||
movedCardNewKanbanParent = "-1";
|
||||
} else if (movedCardWillBeLast) {
|
||||
movedCardNewKanbanParent = lastCardInTargetLane.id;
|
||||
} else if (newChildCard) {
|
||||
movedCardNewKanbanParent = newChildCard.metadata.kanbanparent;
|
||||
} else {
|
||||
console.error("==> !!!!!!Couldn't find a parent.!!!! <==");
|
||||
}
|
||||
|
||||
const newChildCardNewParent = newChildCard ? draggableId : null;
|
||||
const newChildCardNewParent = newChildCard ? draggableId : null;
|
||||
|
||||
try {
|
||||
const update = await client.mutate({
|
||||
mutation: generate_UPDATE_JOB_KANBAN(
|
||||
oldChildCard ? oldChildCard.id : null,
|
||||
oldChildCardNewParent,
|
||||
draggableId,
|
||||
movedCardNewKanbanParent,
|
||||
targetLane.id,
|
||||
newChildCard ? newChildCard.id : null,
|
||||
newChildCardNewParent
|
||||
)
|
||||
});
|
||||
try {
|
||||
const update = await client.mutate({
|
||||
mutation: generate_UPDATE_JOB_KANBAN(
|
||||
oldChildCard ? oldChildCard.id : null,
|
||||
oldChildCardNewParent,
|
||||
draggableId,
|
||||
movedCardNewKanbanParent,
|
||||
targetLane.id,
|
||||
newChildCard ? newChildCard.id : null,
|
||||
newChildCardNewParent
|
||||
)
|
||||
});
|
||||
|
||||
insertAuditTrail({
|
||||
jobid: draggableId,
|
||||
operation: AuditTrailMapping.jobstatuschange(targetLane.id),
|
||||
type: "jobstatuschange"
|
||||
});
|
||||
insertAuditTrail({
|
||||
jobid: draggableId,
|
||||
operation: AuditTrailMapping.jobstatuschange(targetLane.id),
|
||||
type: "jobstatuschange"
|
||||
});
|
||||
|
||||
if (update.errors) {
|
||||
notification.error({
|
||||
title: t("production.errors.boardupdate", {
|
||||
message: JSON.stringify(update.errors)
|
||||
})
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (update.errors) {
|
||||
notification.error({
|
||||
title: t("production.errors.boardupdate", {
|
||||
message: error.message
|
||||
message: JSON.stringify(update.errors)
|
||||
})
|
||||
});
|
||||
} finally {
|
||||
setIsMoving(false);
|
||||
}
|
||||
},
|
||||
[boardLanes, client, getCardByID, isMoving, t, insertAuditTrail, notification]
|
||||
);
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
title: t("production.errors.boardupdate", {
|
||||
message: error.message
|
||||
})
|
||||
});
|
||||
} finally {
|
||||
setIsMoving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const cardSettings = useMemo(() => {
|
||||
const kanbanSettings = associationSettings?.kanban_settings;
|
||||
return mergeWithDefaults(kanbanSettings);
|
||||
}, [associationSettings?.kanban_settings]);
|
||||
const cardSettings = mergeWithDefaults(associationSettings?.kanban_settings);
|
||||
|
||||
const handleSettingsChange = () => {
|
||||
setFilter(defaultFilters);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useApolloClient, useQuery, useSubscription } from "@apollo/client/react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
@@ -35,13 +35,10 @@ function ProductionBoardKanbanContainer({ bodyshop, currentUser, subscriptionTyp
|
||||
splitKey: bodyshop && bodyshop.imexshopid
|
||||
});
|
||||
|
||||
const combinedStatuses = useMemo(
|
||||
() => [
|
||||
...bodyshop.md_ro_statuses.production_statuses,
|
||||
...(bodyshop.md_ro_statuses.additional_board_statuses || [])
|
||||
],
|
||||
[bodyshop.md_ro_statuses.production_statuses, bodyshop.md_ro_statuses.additional_board_statuses]
|
||||
);
|
||||
const combinedStatuses = [
|
||||
...bodyshop.md_ro_statuses.production_statuses,
|
||||
...(bodyshop.md_ro_statuses.additional_board_statuses || [])
|
||||
];
|
||||
|
||||
const { refetch, loading, data } = useQuery(QUERY_JOBS_IN_PRODUCTION, {
|
||||
pollInterval: 3600000,
|
||||
@@ -168,9 +165,7 @@ function ProductionBoardKanbanContainer({ bodyshop, currentUser, subscriptionTyp
|
||||
};
|
||||
}, [subscriptionEnabled, socket, bodyshop, client, refetch]);
|
||||
|
||||
const filteredAssociationSettings = useMemo(() => {
|
||||
return associationSettings?.associations[0] || null;
|
||||
}, [associationSettings?.associations]);
|
||||
const filteredAssociationSettings = associationSettings?.associations[0] || null;
|
||||
|
||||
return (
|
||||
<ProductionBoardKanbanComponent
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useMemo } from "react";
|
||||
import { Card, Statistic } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import PropTypes from "prop-types";
|
||||
@@ -68,128 +67,85 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
||||
return value;
|
||||
};
|
||||
|
||||
const totalHrs = useMemo(() => {
|
||||
if (!cardSettings.totalHrs) return null;
|
||||
const total = calculateTotal(data, "labhrs", "mod_lb_hrs") + calculateTotal(data, "larhrs", "mod_lb_hrs");
|
||||
return parseFloat(total.toFixed(2));
|
||||
}, [data, cardSettings.totalHrs]);
|
||||
const totalHrs = cardSettings.totalHrs
|
||||
? parseFloat((calculateTotal(data, "labhrs", "mod_lb_hrs") + calculateTotal(data, "larhrs", "mod_lb_hrs")).toFixed(2))
|
||||
: null;
|
||||
|
||||
const totalLAB = useMemo(() => {
|
||||
if (!cardSettings.totalLAB) return null;
|
||||
const total = calculateTotal(data, "labhrs", "mod_lb_hrs");
|
||||
return parseFloat(total.toFixed(2));
|
||||
}, [data, cardSettings.totalLAB]);
|
||||
const totalLAB = cardSettings.totalLAB
|
||||
? parseFloat(calculateTotal(data, "labhrs", "mod_lb_hrs").toFixed(2))
|
||||
: null;
|
||||
|
||||
const totalLAR = useMemo(() => {
|
||||
if (!cardSettings.totalLAR) return null;
|
||||
const total = calculateTotal(data, "larhrs", "mod_lb_hrs");
|
||||
return parseFloat(total.toFixed(2));
|
||||
}, [data, cardSettings.totalLAR]);
|
||||
const totalLAR = cardSettings.totalLAR
|
||||
? parseFloat(calculateTotal(data, "larhrs", "mod_lb_hrs").toFixed(2))
|
||||
: null;
|
||||
|
||||
const jobsInProduction = useMemo(
|
||||
() => (cardSettings.jobsInProduction ? data.length : null),
|
||||
[data, cardSettings.jobsInProduction]
|
||||
);
|
||||
const jobsInProduction = cardSettings.jobsInProduction ? data.length : null;
|
||||
|
||||
const totalAmountInProduction = useMemo(() => {
|
||||
if (!cardSettings.totalAmountInProduction) return null;
|
||||
const total = calculateTotalAmount(data, "job_totals");
|
||||
return total.toFormat("$0,0.00");
|
||||
}, [data, cardSettings.totalAmountInProduction]);
|
||||
const totalAmountInProduction = cardSettings.totalAmountInProduction
|
||||
? calculateTotalAmount(data, "job_totals").toFormat("$0,0.00")
|
||||
: null;
|
||||
|
||||
const totalAmountOnBoard = useMemo(() => {
|
||||
if (!reducerData || !cardSettings.totalAmountOnBoard) return null;
|
||||
const total = calculateReducerTotalAmount(reducerData.lanes, "job_totals");
|
||||
return total.toFormat("$0,0.00");
|
||||
}, [reducerData, cardSettings.totalAmountOnBoard]);
|
||||
const totalAmountOnBoard = reducerData && cardSettings.totalAmountOnBoard
|
||||
? calculateReducerTotalAmount(reducerData.lanes, "job_totals").toFormat("$0,0.00")
|
||||
: null;
|
||||
|
||||
const totalHrsOnBoard = useMemo(() => {
|
||||
if (!reducerData || !cardSettings.totalHrsOnBoard) return null;
|
||||
const total =
|
||||
calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs") +
|
||||
calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs");
|
||||
return parseFloat(total.toFixed(2));
|
||||
}, [reducerData, cardSettings.totalHrsOnBoard]);
|
||||
const totalHrsOnBoard = reducerData && cardSettings.totalHrsOnBoard
|
||||
? parseFloat((
|
||||
calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs") +
|
||||
calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs")
|
||||
).toFixed(2))
|
||||
: null;
|
||||
|
||||
const totalLABOnBoard = useMemo(() => {
|
||||
if (!reducerData || !cardSettings.totalLABOnBoard) return null;
|
||||
const total = calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs");
|
||||
return parseFloat(total.toFixed(2));
|
||||
}, [reducerData, cardSettings.totalLABOnBoard]);
|
||||
const totalLABOnBoard = reducerData && cardSettings.totalLABOnBoard
|
||||
? parseFloat(calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs").toFixed(2))
|
||||
: null;
|
||||
|
||||
const totalLAROnBoard = useMemo(() => {
|
||||
if (!reducerData || !cardSettings.totalLAROnBoard) return null;
|
||||
const total = calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs");
|
||||
return parseFloat(total.toFixed(2));
|
||||
}, [reducerData, cardSettings.totalLAROnBoard]);
|
||||
const totalLAROnBoard = reducerData && cardSettings.totalLAROnBoard
|
||||
? parseFloat(calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs").toFixed(2))
|
||||
: null;
|
||||
|
||||
const jobsOnBoard = useMemo(
|
||||
() =>
|
||||
reducerData && cardSettings.jobsOnBoard
|
||||
? reducerData.lanes.reduce((acc, lane) => acc + lane.cards.length, 0)
|
||||
: null,
|
||||
[reducerData, cardSettings.jobsOnBoard]
|
||||
);
|
||||
const jobsOnBoard = reducerData && cardSettings.jobsOnBoard
|
||||
? reducerData.lanes.reduce((acc, lane) => acc + lane.cards.length, 0)
|
||||
: null;
|
||||
|
||||
const tasksInProduction = useMemo(() => {
|
||||
if (!data || !cardSettings.tasksInProduction) return null;
|
||||
return data.reduce((acc, item) => acc + (item.tasks_aggregate?.aggregate?.count || 0), 0);
|
||||
}, [data, cardSettings.tasksInProduction]);
|
||||
const tasksInProduction = cardSettings.tasksInProduction
|
||||
? data.reduce((acc, item) => acc + (item.tasks_aggregate?.aggregate?.count || 0), 0)
|
||||
: null;
|
||||
|
||||
const tasksOnBoard = useMemo(() => {
|
||||
if (!reducerData || !cardSettings.tasksOnBoard) return null;
|
||||
return reducerData.lanes.reduce((acc, lane) => {
|
||||
return (
|
||||
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata.tasks_aggregate?.aggregate?.count || 0), 0)
|
||||
);
|
||||
}, 0);
|
||||
}, [reducerData, cardSettings.tasksOnBoard]);
|
||||
const tasksOnBoard = reducerData && cardSettings.tasksOnBoard
|
||||
? reducerData.lanes.reduce((acc, lane) => {
|
||||
return (
|
||||
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata.tasks_aggregate?.aggregate?.count || 0), 0)
|
||||
);
|
||||
}, 0)
|
||||
: null;
|
||||
|
||||
const statistics = useMemo(
|
||||
() =>
|
||||
mergeStatistics(statisticsItems, [
|
||||
{ id: 0, value: totalHrs, type: StatisticType.HOURS },
|
||||
{ id: 1, value: totalAmountInProduction, type: StatisticType.AMOUNT },
|
||||
{ id: 2, value: totalLAB, type: StatisticType.HOURS },
|
||||
{ id: 3, value: totalLAR, type: StatisticType.HOURS },
|
||||
{ id: 4, value: jobsInProduction, type: StatisticType.JOBS },
|
||||
{ id: 5, value: totalHrsOnBoard, type: StatisticType.HOURS },
|
||||
{ id: 6, value: totalAmountOnBoard, type: StatisticType.AMOUNT },
|
||||
{ id: 7, value: totalLABOnBoard, type: StatisticType.HOURS },
|
||||
{ id: 8, value: totalLAROnBoard, type: StatisticType.HOURS },
|
||||
{ id: 9, value: jobsOnBoard, type: StatisticType.JOBS },
|
||||
{ id: 10, value: tasksOnBoard, type: StatisticType.TASKS },
|
||||
{ id: 11, value: tasksInProduction, type: StatisticType.TASKS }
|
||||
]),
|
||||
[
|
||||
totalHrs,
|
||||
totalAmountInProduction,
|
||||
totalLAB,
|
||||
totalLAR,
|
||||
jobsInProduction,
|
||||
totalHrsOnBoard,
|
||||
totalAmountOnBoard,
|
||||
totalLABOnBoard,
|
||||
totalLAROnBoard,
|
||||
jobsOnBoard,
|
||||
tasksOnBoard,
|
||||
tasksInProduction
|
||||
]
|
||||
);
|
||||
const statistics = mergeStatistics(statisticsItems, [
|
||||
{ id: 0, value: totalHrs, type: StatisticType.HOURS },
|
||||
{ id: 1, value: totalAmountInProduction, type: StatisticType.AMOUNT },
|
||||
{ id: 2, value: totalLAB, type: StatisticType.HOURS },
|
||||
{ id: 3, value: totalLAR, type: StatisticType.HOURS },
|
||||
{ id: 4, value: jobsInProduction, type: StatisticType.JOBS },
|
||||
{ id: 5, value: totalHrsOnBoard, type: StatisticType.HOURS },
|
||||
{ id: 6, value: totalAmountOnBoard, type: StatisticType.AMOUNT },
|
||||
{ id: 7, value: totalLABOnBoard, type: StatisticType.HOURS },
|
||||
{ id: 8, value: totalLAROnBoard, type: StatisticType.HOURS },
|
||||
{ id: 9, value: jobsOnBoard, type: StatisticType.JOBS },
|
||||
{ id: 10, value: tasksOnBoard, type: StatisticType.TASKS },
|
||||
{ id: 11, value: tasksInProduction, type: StatisticType.TASKS }
|
||||
]);
|
||||
|
||||
const sortedStatistics = useMemo(() => {
|
||||
const statisticsMap = new Map(statistics.map((stat) => [stat.id, stat]));
|
||||
const statisticsMap = new Map(statistics.map((stat) => [stat.id, stat]));
|
||||
|
||||
return (
|
||||
cardSettings?.statisticsOrder ? cardSettings.statisticsOrder : defaultKanbanSettings.statisticsOrder
|
||||
).reduce((sorted, orderId) => {
|
||||
const value = statisticsMap.get(orderId);
|
||||
if (value?.value) {
|
||||
sorted.push(value);
|
||||
}
|
||||
return sorted;
|
||||
}, []);
|
||||
}, [statistics, cardSettings.statisticsOrder]);
|
||||
const sortedStatistics = (
|
||||
cardSettings?.statisticsOrder ? cardSettings.statisticsOrder : defaultKanbanSettings.statisticsOrder
|
||||
).reduce((sorted, orderId) => {
|
||||
const value = statisticsMap.get(orderId);
|
||||
if (value?.value) {
|
||||
sorted.push(value);
|
||||
}
|
||||
return sorted;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", gap: "5px", flexWrap: "wrap", marginBottom: "5px" }}>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { memo } from "react";
|
||||
|
||||
const ItemWrapper = memo(({ children, ...props }) => (
|
||||
<div {...props} className="item-wrapper">
|
||||
{children}
|
||||
</div>
|
||||
));
|
||||
|
||||
ItemWrapper.displayName = "ItemWrapper";
|
||||
function ItemWrapper({ children, ...props }) {
|
||||
return (
|
||||
<div {...props} className="item-wrapper">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ItemWrapper;
|
||||
|
||||
@@ -1,38 +1,34 @@
|
||||
import { BoardContainer } from "../index";
|
||||
import { useMemo } from "react";
|
||||
import { StyleHorizontal, StyleVertical } from "../styles/Base.js";
|
||||
import { cardSizesVertical } from "../styles/Globals.js";
|
||||
|
||||
const Board = ({ orientation, cardSettings, ...additionalProps }) => {
|
||||
const OrientationStyle = useMemo(
|
||||
() => (orientation === "horizontal" ? StyleHorizontal : StyleVertical),
|
||||
[orientation]
|
||||
);
|
||||
const OrientationStyle = orientation === "horizontal" ? StyleHorizontal : StyleVertical;
|
||||
|
||||
const gridItemWidth = useMemo(() => {
|
||||
switch (cardSettings?.cardSize) {
|
||||
case "small":
|
||||
return cardSizesVertical.small;
|
||||
case "large":
|
||||
return cardSizesVertical.large;
|
||||
case "medium":
|
||||
return cardSizesVertical.medium;
|
||||
default:
|
||||
return cardSizesVertical.small;
|
||||
}
|
||||
}, [cardSettings?.cardSize]);
|
||||
let gridItemWidth;
|
||||
switch (cardSettings?.cardSize) {
|
||||
case "small":
|
||||
gridItemWidth = cardSizesVertical.small;
|
||||
break;
|
||||
case "large":
|
||||
gridItemWidth = cardSizesVertical.large;
|
||||
break;
|
||||
case "medium":
|
||||
gridItemWidth = cardSizesVertical.medium;
|
||||
break;
|
||||
default:
|
||||
gridItemWidth = cardSizesVertical.small;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<OrientationStyle {...{ gridItemWidth }}>
|
||||
<BoardContainer
|
||||
orientation={orientation}
|
||||
cardSettings={cardSettings}
|
||||
{...additionalProps}
|
||||
className="react-trello-board"
|
||||
/>
|
||||
</OrientationStyle>
|
||||
</>
|
||||
<OrientationStyle {...{ gridItemWidth }}>
|
||||
<BoardContainer
|
||||
orientation={orientation}
|
||||
cardSettings={cardSettings}
|
||||
{...additionalProps}
|
||||
className="react-trello-board"
|
||||
/>
|
||||
</OrientationStyle>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { DragDropContext } from "../dnd/lib";
|
||||
import PropTypes from "prop-types";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import Lane from "./Lane";
|
||||
import { PopoverWrapper } from "react-popopo";
|
||||
import * as actions from "../../../../redux/trello/trello.actions.js";
|
||||
@@ -37,7 +36,6 @@ const BoardContainer = ({
|
||||
orientation = "horizontal",
|
||||
cardSettings = {},
|
||||
eventBusHandle,
|
||||
reducerData,
|
||||
queryData
|
||||
}) => {
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
@@ -50,24 +48,10 @@ const BoardContainer = ({
|
||||
const currentReducerData = useSelector((state) => (state.trello.lanes ? state.trello : {}));
|
||||
const { setDragTime, getLastDragTime } = useDragMap();
|
||||
|
||||
const wireEventBus = useCallback(() => {
|
||||
const wireEventBus = () => {
|
||||
const eventBus = {
|
||||
publish: (event) => {
|
||||
switch (event.type) {
|
||||
// case "ADD_CARD":
|
||||
// return dispatch(actions.addCard({ laneId: event.laneId, card: event.card }));
|
||||
// case "REMOVE_CARD":
|
||||
// return dispatch(actions.removeCard({ laneId: event.laneId, cardId: event.cardId }));
|
||||
// case "REFRESH_BOARD":
|
||||
// return dispatch(actions.loadBoard(event.data));
|
||||
// case "UPDATE_CARDS":
|
||||
// return dispatch(actions.updateCards({ laneId: event.laneId, cards: event.cards }));
|
||||
// case "UPDATE_CARD":
|
||||
// return dispatch(actions.updateCard({ laneId: event.laneId, updatedCard: event.card }));
|
||||
// case "UPDATE_LANES":
|
||||
// return dispatch(actions.updateLanes(event.lanes));
|
||||
// case "UPDATE_LANE":
|
||||
// return dispatch(actions.updateLane(event.lane));
|
||||
case "MOVE_CARD":
|
||||
return dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
@@ -84,66 +68,30 @@ const BoardContainer = ({
|
||||
}
|
||||
};
|
||||
eventBusHandle(eventBus);
|
||||
}, [dispatch, eventBusHandle]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(actions.loadBoard(data));
|
||||
if (eventBusHandle) {
|
||||
wireEventBus();
|
||||
}
|
||||
}, [data, eventBusHandle, dispatch, wireEventBus]);
|
||||
}, [data, eventBusHandle, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEqual(currentReducerData, reducerData)) {
|
||||
onDataChange(currentReducerData);
|
||||
}
|
||||
}, [currentReducerData, reducerData, onDataChange]);
|
||||
onDataChange(currentReducerData);
|
||||
}, [currentReducerData, onDataChange]);
|
||||
|
||||
const onDragStart = useCallback(() => {
|
||||
const onDragStart = () => {
|
||||
setIsDragging(true);
|
||||
}, []);
|
||||
};
|
||||
|
||||
const onLaneDrag = useCallback(
|
||||
async ({ draggableId, type, source, reason, mode, destination, combine }) => {
|
||||
setIsDragging(false);
|
||||
const onLaneDrag = async ({ draggableId, type, source, reason, mode, destination, combine }) => {
|
||||
setIsDragging(false);
|
||||
|
||||
// Validate drag type and source
|
||||
if (type !== "lane" || !source) {
|
||||
// Invalid drag type or missing source, attempt to revert if possible
|
||||
if (source) {
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: source.droppableId,
|
||||
toLaneId: source.droppableId,
|
||||
cardId: draggableId,
|
||||
index: source.index
|
||||
})
|
||||
);
|
||||
}
|
||||
setIsProcessing(false);
|
||||
try {
|
||||
await onDragEnd({ draggableId, type, source, reason, mode, destination, combine });
|
||||
} catch (err) {
|
||||
console.error("Error in onLaneDrag for invalid drag type or source", err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
setDragTime(source.droppableId);
|
||||
setIsProcessing(true);
|
||||
|
||||
// Handle valid drop to a different lane or position
|
||||
if (destination && !isEqual(source, destination)) {
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: source.droppableId,
|
||||
toLaneId: destination.droppableId,
|
||||
cardId: draggableId,
|
||||
index: destination.index
|
||||
})
|
||||
);
|
||||
} else {
|
||||
// Same-lane drop or no destination, revert to original position
|
||||
// Validate drag type and source
|
||||
if (type !== "lane" || !source) {
|
||||
// Invalid drag type or missing source, attempt to revert if possible
|
||||
if (source) {
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: source.droppableId,
|
||||
@@ -153,26 +101,57 @@ const BoardContainer = ({
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
setIsProcessing(false);
|
||||
try {
|
||||
await onDragEnd({ draggableId, type, source, reason, mode, destination, combine });
|
||||
} catch (err) {
|
||||
console.error("Error in onLaneDrag", err);
|
||||
// Ensure revert on error
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: source.droppableId,
|
||||
toLaneId: source.droppableId,
|
||||
cardId: draggableId,
|
||||
index: source.index
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
setIsProcessing(false);
|
||||
console.error("Error in onLaneDrag for invalid drag type or source", err);
|
||||
}
|
||||
},
|
||||
[dispatch, onDragEnd, setDragTime]
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setDragTime(source.droppableId);
|
||||
setIsProcessing(true);
|
||||
|
||||
// Handle valid drop to a different lane or position
|
||||
if (destination && (source.droppableId !== destination.droppableId || source.index !== destination.index)) {
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: source.droppableId,
|
||||
toLaneId: destination.droppableId,
|
||||
cardId: draggableId,
|
||||
index: destination.index
|
||||
})
|
||||
);
|
||||
} else {
|
||||
// Same-lane drop or no destination, revert to original position
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: source.droppableId,
|
||||
toLaneId: source.droppableId,
|
||||
cardId: draggableId,
|
||||
index: source.index
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await onDragEnd({ draggableId, type, source, reason, mode, destination, combine });
|
||||
} catch (err) {
|
||||
console.error("Error in onLaneDrag", err);
|
||||
// Ensure revert on error
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: source.droppableId,
|
||||
toLaneId: source.droppableId,
|
||||
cardId: draggableId,
|
||||
index: source.index
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
setIsProcessing(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useMemo, useRef, useState } from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { bindActionCreators } from "redux";
|
||||
import { connect } from "react-redux";
|
||||
@@ -64,185 +64,162 @@ const Lane = ({
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const laneRef = useRef(null);
|
||||
|
||||
const sortedCards = useMemo(() => {
|
||||
if (!cards) return [];
|
||||
if (!laneSortFunction) return cards;
|
||||
return [...cards].sort(laneSortFunction);
|
||||
}, [cards, laneSortFunction]);
|
||||
let sortedCards = cards || [];
|
||||
if (laneSortFunction && cards) {
|
||||
sortedCards = [...cards].sort(laneSortFunction);
|
||||
}
|
||||
|
||||
const toggleLaneCollapsed = useCallback(() => {
|
||||
const toggleLaneCollapsed = () => {
|
||||
setCollapsed((prevCollapsed) => !prevCollapsed);
|
||||
}, []);
|
||||
};
|
||||
|
||||
const renderDraggable = useCallback(
|
||||
(index, card) => {
|
||||
if (!card) {
|
||||
console.log("null card");
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Draggable draggableId={card.id} index={index} key={card.id} isDragDisabled={isProcessing}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
ref={provided.innerRef}
|
||||
style={provided.draggableProps.style}
|
||||
className={`item ${snapshot.isDragging ? "is-dragging" : ""}`}
|
||||
key={card.id}
|
||||
>
|
||||
<SizeMemoryWrapper
|
||||
maxHeight={maxCardHeight}
|
||||
setMaxHeight={setMaxCardHeight}
|
||||
maxWidth={maxCardWidth}
|
||||
setMaxWidth={setMaxCardWidth}
|
||||
>
|
||||
<ProductionBoardCard
|
||||
technician={technician}
|
||||
bodyshop={bodyshop}
|
||||
cardSettings={cardSettings}
|
||||
key={card.id}
|
||||
card={card}
|
||||
style={{ minHeight: maxCardHeight, minWidth: maxCardWidth }}
|
||||
className="react-trello-card"
|
||||
/>
|
||||
</SizeMemoryWrapper>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
},
|
||||
[isProcessing, technician, bodyshop, cardSettings, maxCardHeight, setMaxCardHeight, maxCardWidth, setMaxCardWidth]
|
||||
);
|
||||
|
||||
const renderDroppable = useCallback(
|
||||
(provided, renderedCards) => {
|
||||
const Component = orientation === "vertical" ? VirtuosoGrid : Virtuoso;
|
||||
const FinalComponent = collapsed ? "div" : Component;
|
||||
const commonProps = {
|
||||
data: renderedCards,
|
||||
customScrollParent: laneRef.current
|
||||
};
|
||||
|
||||
const verticalProps = {
|
||||
...commonProps,
|
||||
listClassName: "grid-container",
|
||||
itemClassName: "grid-item",
|
||||
components: {
|
||||
List: ListComponent,
|
||||
Item: ItemComponent
|
||||
},
|
||||
itemContent: (index, item) => <ItemWrapper>{renderDraggable(index, item)}</ItemWrapper>,
|
||||
overscan: { main: 10, reverse: 10 },
|
||||
// Ensure a minimum height for empty lanes to allow dropping
|
||||
style: renderedCards.length === 0 ? { minHeight: "5px" } : {}
|
||||
};
|
||||
|
||||
const horizontalProps = {
|
||||
...commonProps,
|
||||
components: { Item: HeightPreservingItem },
|
||||
overscan: { main: 3, reverse: 3 },
|
||||
itemContent: (index, item) => renderDraggable(index, item),
|
||||
style: {
|
||||
minWidth: maxCardWidth,
|
||||
minHeight: maxLaneHeight
|
||||
}
|
||||
};
|
||||
|
||||
const componentProps = orientation === "vertical" ? verticalProps : horizontalProps;
|
||||
|
||||
const finalComponentProps = collapsed
|
||||
? orientation === "horizontal"
|
||||
? {
|
||||
style: {
|
||||
height: maxLaneHeight
|
||||
}
|
||||
}
|
||||
: {}
|
||||
: componentProps;
|
||||
|
||||
// Always render placeholder for empty lanes in vertical mode to ensure droppable area
|
||||
const shouldRenderPlaceholder = orientation === "vertical" ? collapsed || renderedCards.length === 0 : collapsed;
|
||||
|
||||
return (
|
||||
<HeightMemoryWrapper
|
||||
itemKey={objectHash({
|
||||
id,
|
||||
orientation,
|
||||
cardSettings,
|
||||
cardLength: renderedCards?.length
|
||||
})}
|
||||
maxHeight={maxLaneHeight}
|
||||
setMaxHeight={setMaxLaneHeight}
|
||||
override={orientation !== "horizontal" && (collapsed || !renderedCards.length)}
|
||||
>
|
||||
const renderDraggable = (index, card) => {
|
||||
if (!card) {
|
||||
console.log("null card");
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Draggable draggableId={card.id} index={index} key={card.id} isDragDisabled={isProcessing}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
ref={laneRef}
|
||||
style={{ height: "100%", width: "100%" }}
|
||||
className={`react-trello-lane ${collapsed ? "lane-collapsed" : ""}`}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
ref={provided.innerRef}
|
||||
style={provided.draggableProps.style}
|
||||
className={`item ${snapshot.isDragging ? "is-dragging" : ""}`}
|
||||
key={card.id}
|
||||
>
|
||||
<div {...provided.droppableProps} ref={provided.innerRef} style={{ ...provided.droppableProps.style }}>
|
||||
<FinalComponent {...finalComponentProps} />
|
||||
{shouldRenderPlaceholder && provided.placeholder}
|
||||
</div>
|
||||
</div>
|
||||
</HeightMemoryWrapper>
|
||||
);
|
||||
},
|
||||
[orientation, collapsed, renderDraggable, maxLaneHeight, setMaxLaneHeight, maxCardWidth, id, cardSettings]
|
||||
);
|
||||
|
||||
const renderDragContainer = useCallback(
|
||||
() => (
|
||||
<Droppable
|
||||
droppableId={id}
|
||||
index={index}
|
||||
type="lane"
|
||||
direction={orientation === "horizontal" ? "vertical" : "grid"}
|
||||
mode="virtual"
|
||||
renderClone={(provided, snapshot, rubric) => {
|
||||
const card = sortedCards[rubric.source.index];
|
||||
return (
|
||||
<div
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
ref={provided.innerRef}
|
||||
style={{
|
||||
...provided.draggableProps.style,
|
||||
minHeight: maxCardHeight,
|
||||
minWidth: maxCardWidth
|
||||
}}
|
||||
className={`clone ${snapshot.isDragging ? "is-dragging" : ""}`}
|
||||
key={card.id}
|
||||
<SizeMemoryWrapper
|
||||
maxHeight={maxCardHeight}
|
||||
setMaxHeight={setMaxCardHeight}
|
||||
maxWidth={maxCardWidth}
|
||||
setMaxWidth={setMaxCardWidth}
|
||||
>
|
||||
<ProductionBoardCard
|
||||
technician={technician}
|
||||
bodyshop={bodyshop}
|
||||
cardSettings={cardSettings}
|
||||
key={card.id}
|
||||
className="react-trello-card"
|
||||
card={card}
|
||||
clone={false}
|
||||
style={{ minHeight: maxCardHeight, minWidth: maxCardWidth }}
|
||||
className="react-trello-card"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</SizeMemoryWrapper>
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
};
|
||||
|
||||
const renderDroppable = (provided, renderedCards) => {
|
||||
const Component = orientation === "vertical" ? VirtuosoGrid : Virtuoso;
|
||||
const FinalComponent = collapsed ? "div" : Component;
|
||||
const commonProps = {
|
||||
data: renderedCards,
|
||||
customScrollParent: laneRef.current
|
||||
};
|
||||
|
||||
const verticalProps = {
|
||||
...commonProps,
|
||||
listClassName: "grid-container",
|
||||
itemClassName: "grid-item",
|
||||
components: {
|
||||
List: ListComponent,
|
||||
Item: ItemComponent
|
||||
},
|
||||
itemContent: (index, item) => <ItemWrapper>{renderDraggable(index, item)}</ItemWrapper>,
|
||||
overscan: { main: 10, reverse: 10 },
|
||||
style: renderedCards.length === 0 ? { minHeight: "5px" } : {}
|
||||
};
|
||||
|
||||
const horizontalProps = {
|
||||
...commonProps,
|
||||
components: { Item: HeightPreservingItem },
|
||||
overscan: { main: 3, reverse: 3 },
|
||||
itemContent: (index, item) => renderDraggable(index, item),
|
||||
style: {
|
||||
minWidth: maxCardWidth,
|
||||
minHeight: maxLaneHeight
|
||||
}
|
||||
};
|
||||
|
||||
const componentProps = orientation === "vertical" ? verticalProps : horizontalProps;
|
||||
|
||||
const finalComponentProps = collapsed
|
||||
? orientation === "horizontal"
|
||||
? {
|
||||
style: {
|
||||
height: maxLaneHeight
|
||||
}
|
||||
}
|
||||
: {}
|
||||
: componentProps;
|
||||
|
||||
const shouldRenderPlaceholder = orientation === "vertical" ? collapsed || renderedCards.length === 0 : collapsed;
|
||||
|
||||
return (
|
||||
<HeightMemoryWrapper
|
||||
itemKey={objectHash({
|
||||
id,
|
||||
orientation,
|
||||
cardSettings,
|
||||
cardLength: renderedCards?.length
|
||||
})}
|
||||
maxHeight={maxLaneHeight}
|
||||
setMaxHeight={setMaxLaneHeight}
|
||||
override={orientation !== "horizontal" && (collapsed || !renderedCards.length)}
|
||||
>
|
||||
{(provided) => renderDroppable(provided, sortedCards)}
|
||||
</Droppable>
|
||||
),
|
||||
[
|
||||
id,
|
||||
index,
|
||||
orientation,
|
||||
renderDroppable,
|
||||
sortedCards,
|
||||
technician,
|
||||
bodyshop,
|
||||
cardSettings,
|
||||
maxCardHeight,
|
||||
maxCardWidth
|
||||
]
|
||||
<div
|
||||
ref={laneRef}
|
||||
style={{ height: "100%", width: "100%" }}
|
||||
className={`react-trello-lane ${collapsed ? "lane-collapsed" : ""}`}
|
||||
>
|
||||
<div {...provided.droppableProps} ref={provided.innerRef} style={{ ...provided.droppableProps.style }}>
|
||||
<FinalComponent {...finalComponentProps} />
|
||||
{shouldRenderPlaceholder && provided.placeholder}
|
||||
</div>
|
||||
</div>
|
||||
</HeightMemoryWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const renderDragContainer = () => (
|
||||
<Droppable
|
||||
droppableId={id}
|
||||
index={index}
|
||||
type="lane"
|
||||
direction={orientation === "horizontal" ? "vertical" : "grid"}
|
||||
mode="virtual"
|
||||
renderClone={(provided, snapshot, rubric) => {
|
||||
const card = sortedCards[rubric.source.index];
|
||||
return (
|
||||
<div
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
ref={provided.innerRef}
|
||||
style={{
|
||||
...provided.draggableProps.style,
|
||||
minHeight: maxCardHeight,
|
||||
minWidth: maxCardWidth
|
||||
}}
|
||||
className={`clone ${snapshot.isDragging ? "is-dragging" : ""}`}
|
||||
key={card.id}
|
||||
>
|
||||
<ProductionBoardCard
|
||||
technician={technician}
|
||||
bodyshop={bodyshop}
|
||||
cardSettings={cardSettings}
|
||||
key={card.id}
|
||||
className="react-trello-card"
|
||||
card={card}
|
||||
clone={false}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
>
|
||||
{(provided) => renderDroppable(provided, sortedCards)}
|
||||
</Droppable>
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useEffect } from "react";
|
||||
import { useMemo } from "use-memo-one";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import createRegistry from "./create-registry";
|
||||
|
||||
export default function useRegistry() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { bindActionCreators } from "redux";
|
||||
import { Provider } from "react-redux";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { invariant } from "../../invariant";
|
||||
import createStore from "../../state/create-store";
|
||||
import createDimensionMarshal from "../../state/dimension-marshal/dimension-marshal";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useMemo } from "use-memo-one";
|
||||
import { useMemo } from "react";
|
||||
|
||||
let count = 0;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useCallback, useRef, useMemo } from "react";
|
||||
import getStyle from "./get-style";
|
||||
import useDraggablePublisher from "../use-draggable-publisher/use-draggable-publisher";
|
||||
import AppContext from "../context/app-context";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import ReactDOM from "react-dom";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import React, { useContext, useRef } from "react";
|
||||
import React, { useCallback, useContext, useMemo, useRef } from "react";
|
||||
import { invariant } from "../../invariant";
|
||||
import useDroppablePublisher from "../use-droppable-publisher";
|
||||
import Placeholder from "../placeholder";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useCallback } from "use-memo-one";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { transitions } from "../../animation";
|
||||
import { noSpacing } from "../../state/spacing";
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { warning } from "../../dev-warning";
|
||||
import getBodyElement from "../get-body-element";
|
||||
import visuallyHidden from "../visually-hidden-style";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo, useRef } from "react";
|
||||
import { invariant } from "../../invariant";
|
||||
import makeDimension from "./get-dimension";
|
||||
import useLayoutEffect from "../use-isomorphic-layout-effect";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo, useRef } from "react";
|
||||
import rafSchedule from "raf-schd";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { invariant } from "../../invariant";
|
||||
import checkForNestedScrollContainers from "./check-for-nested-scroll-container";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useCallback, useMemo, useRef } from "react";
|
||||
import { dragHandle as dragHandleAttr } from "../data-attributes";
|
||||
import useLayoutEffect from "../use-isomorphic-layout-effect";
|
||||
import findDragHandle from "../get-elements/find-drag-handle";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useEffect } from "react";
|
||||
import { useMemo } from "use-memo-one";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import getBodyElement from "../get-body-element";
|
||||
import useUniqueId from "../use-unique-id";
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useCallback, useMemo, useRef } from "react";
|
||||
import { invariant } from "../../../invariant";
|
||||
import * as keyCodes from "../../key-codes";
|
||||
import bindEvents from "../../event-bindings/bind-events";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useCallback, useMemo, useRef } from "react";
|
||||
import { invariant } from "../../../invariant";
|
||||
import bindEvents from "../../event-bindings/bind-events";
|
||||
import * as keyCodes from "../../key-codes";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useCallback, useMemo, useRef } from "react";
|
||||
import { invariant } from "../../../invariant";
|
||||
import bindEvents from "../../event-bindings/bind-events";
|
||||
import * as keyCodes from "../../key-codes";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import rafSchd from "raf-schd";
|
||||
import { useState } from "react";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { invariant } from "../../invariant";
|
||||
import create from "./lock";
|
||||
import canStartDrag from "../../state/can-start-drag";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback, useMemo, useRef } from "react";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { useCallback, useMemo } from "use-memo-one";
|
||||
import { invariant } from "../../invariant";
|
||||
import getStyles from "./get-styles";
|
||||
import { prefix } from "../data-attributes";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useMemo } from "use-memo-one";
|
||||
import { useMemo } from "react";
|
||||
|
||||
let count = 0;
|
||||
const defaults = {
|
||||
|
||||
@@ -51,7 +51,9 @@ export default defineConfig(({ command, mode }) => {
|
||||
const enableReactCompiler =
|
||||
process.env.VITE_ENABLE_COMPILER_IN_DEV || (isBuild && (mode === "production" || isTestBuild));
|
||||
|
||||
console.log(enableReactCompiler ? "React Compiler enabled" : "React Compiler disabled");
|
||||
logger.info(
|
||||
enableReactCompiler ? chalk.green.bold("React Compiler enabled") : chalk.yellow.bold("React Compiler disabled")
|
||||
);
|
||||
|
||||
return {
|
||||
base: "/",
|
||||
@@ -121,17 +123,7 @@ export default defineConfig(({ command, mode }) => {
|
||||
enableReactCompiler
|
||||
? {
|
||||
babel: {
|
||||
plugins: [
|
||||
[
|
||||
"babel-plugin-react-compiler",
|
||||
{
|
||||
// Exclude third-party drag-and-drop library from compilation
|
||||
sources: (filename) => {
|
||||
return !filename.includes("trello-board/dnd");
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
plugins: [["babel-plugin-react-compiler"]]
|
||||
}
|
||||
}
|
||||
: undefined
|
||||
@@ -221,7 +213,6 @@ export default defineConfig(({ command, mode }) => {
|
||||
|
||||
build: {
|
||||
sourcemap: true,
|
||||
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
|
||||
Reference in New Issue
Block a user