Bug Fixes:
- Zone Selection Panel moves to the bottom when the bottom panel is hidden. - Zone Selection Panel gets hidden by 3D widgets when switching zones. - Template image not rendering on the Template page despite being saved.
This commit is contained in:
commit
2ce930a6f5
|
@ -29,7 +29,6 @@
|
||||||
"chartjs-plugin-annotation": "^3.1.0",
|
"chartjs-plugin-annotation": "^3.1.0",
|
||||||
"glob": "^11.0.0",
|
"glob": "^11.0.0",
|
||||||
"gsap": "^3.12.5",
|
"gsap": "^3.12.5",
|
||||||
"html2canvas": "^1.4.1",
|
|
||||||
"leva": "^0.10.0",
|
"leva": "^0.10.0",
|
||||||
"mqtt": "^5.10.4",
|
"mqtt": "^5.10.4",
|
||||||
"postprocessing": "^6.36.4",
|
"postprocessing": "^6.36.4",
|
||||||
|
@ -2020,7 +2019,7 @@
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/trace-mapping": "0.3.9"
|
"@jridgewell/trace-mapping": "0.3.9"
|
||||||
},
|
},
|
||||||
|
@ -2032,7 +2031,7 @@
|
||||||
"version": "0.3.9",
|
"version": "0.3.9",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.0.3",
|
"@jridgewell/resolve-uri": "^3.0.3",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||||
|
@ -4135,6 +4134,26 @@
|
||||||
"url": "https://github.com/sponsors/gregberge"
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@testing-library/dom": {
|
||||||
|
"version": "10.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
|
||||||
|
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.10.4",
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"@types/aria-query": "^5.0.1",
|
||||||
|
"aria-query": "5.3.0",
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"dom-accessibility-api": "^0.5.9",
|
||||||
|
"lz-string": "^1.5.0",
|
||||||
|
"pretty-format": "^27.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@testing-library/jest-dom": {
|
"node_modules/@testing-library/jest-dom": {
|
||||||
"version": "5.17.0",
|
"version": "5.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
|
||||||
|
@ -4246,25 +4265,25 @@
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||||
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node12": {
|
"node_modules/@tsconfig/node12": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node14": {
|
"node_modules/@tsconfig/node14": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node16": {
|
"node_modules/@tsconfig/node16": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@turf/along": {
|
"node_modules/@turf/along": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
|
@ -8028,15 +8047,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
},
|
},
|
||||||
"node_modules/base64-arraybuffer": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
@ -9007,7 +9017,7 @@
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/cross-env": {
|
"node_modules/cross-env": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
|
@ -9092,15 +9102,6 @@
|
||||||
"postcss": "^8.4"
|
"postcss": "^8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/css-line-break": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"utrie": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/css-loader": {
|
"node_modules/css-loader": {
|
||||||
"version": "6.11.0",
|
"version": "6.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz",
|
||||||
|
@ -9884,7 +9885,7 @@
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.3.1"
|
"node": ">=0.3.1"
|
||||||
}
|
}
|
||||||
|
@ -12488,19 +12489,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/html2canvas": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
|
||||||
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"css-line-break": "^2.1.0",
|
|
||||||
"text-segmentation": "^1.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
|
||||||
|
@ -15247,7 +15235,7 @@
|
||||||
"version": "1.3.6",
|
"version": "1.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/makeerror": {
|
"node_modules/makeerror": {
|
||||||
"version": "1.0.12",
|
"version": "1.0.12",
|
||||||
|
@ -20446,15 +20434,6 @@
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/text-segmentation": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"utrie": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/text-table": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
@ -20715,7 +20694,7 @@
|
||||||
"version": "10.9.2",
|
"version": "10.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cspotcode/source-map-support": "^0.8.0",
|
"@cspotcode/source-map-support": "^0.8.0",
|
||||||
"@tsconfig/node10": "^1.0.7",
|
"@tsconfig/node10": "^1.0.7",
|
||||||
|
@ -20758,7 +20737,7 @@
|
||||||
"version": "8.3.4",
|
"version": "8.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.11.0"
|
"acorn": "^8.11.0"
|
||||||
},
|
},
|
||||||
|
@ -20770,7 +20749,7 @@
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.0",
|
||||||
|
@ -21241,15 +21220,6 @@
|
||||||
"node": ">= 0.4.0"
|
"node": ">= 0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/utrie": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"base64-arraybuffer": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
"version": "9.0.1",
|
"version": "9.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
@ -21266,7 +21236,7 @@
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/v8-to-istanbul": {
|
"node_modules/v8-to-istanbul": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
|
@ -22325,7 +22295,7 @@
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
"chartjs-plugin-annotation": "^3.1.0",
|
"chartjs-plugin-annotation": "^3.1.0",
|
||||||
"glob": "^11.0.0",
|
"glob": "^11.0.0",
|
||||||
"gsap": "^3.12.5",
|
"gsap": "^3.12.5",
|
||||||
"html2canvas": "^1.4.1",
|
|
||||||
"leva": "^0.10.0",
|
"leva": "^0.10.0",
|
||||||
"mqtt": "^5.10.4",
|
"mqtt": "^5.10.4",
|
||||||
"postprocessing": "^6.36.4",
|
"postprocessing": "^6.36.4",
|
||||||
|
|
|
@ -166,6 +166,7 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`
|
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setmeasurements(response.data.Data.measurements);
|
setmeasurements(response.data.Data.measurements);
|
||||||
setDuration(response.data.Data.duration);
|
setDuration(response.data.Data.duration);
|
||||||
|
|
|
@ -129,6 +129,7 @@ const Assets: React.FC = () => {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const res = await getCategoryAsset(asset);
|
const res = await getCategoryAsset(asset);
|
||||||
|
console.log('res: ', res);
|
||||||
setCategoryAssets(res);
|
setCategoryAssets(res);
|
||||||
setFiltereredAssets(res);
|
setFiltereredAssets(res);
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
|
@ -191,7 +192,7 @@ const Assets: React.FC = () => {
|
||||||
onPointerDown={() =>
|
onPointerDown={() =>
|
||||||
setSelectedItem({
|
setSelectedItem({
|
||||||
name: asset.filename,
|
name: asset.filename,
|
||||||
id: asset.modelfileID,
|
id: asset.AssetID,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -88,22 +88,22 @@ const Templates = () => {
|
||||||
return (
|
return (
|
||||||
<div className="template-list">
|
<div className="template-list">
|
||||||
{templates.map((template, index) => (
|
{templates.map((template, index) => (
|
||||||
<div key={template.id} className="template-item">
|
<div
|
||||||
|
key={template.id}
|
||||||
|
className="template-item"
|
||||||
|
onClick={() => handleLoadTemplate(template)}
|
||||||
|
>
|
||||||
{template?.snapshot && (
|
{template?.snapshot && (
|
||||||
<div className="template-image-container">
|
<div className="template-image-container">
|
||||||
<img
|
<img
|
||||||
src={template.snapshot}
|
src={template.snapshot}
|
||||||
alt={`${template.name} preview`}
|
alt={`${template.name} preview`}
|
||||||
className="template-image"
|
className="template-image"
|
||||||
onClick={() => handleLoadTemplate(template)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="template-details">
|
<div className="template-details">
|
||||||
<div
|
<div className="template-name">
|
||||||
onClick={() => handleLoadTemplate(template)}
|
|
||||||
className="template-name"
|
|
||||||
>
|
|
||||||
{/* {`Template ${index + 1}`} */}
|
{/* {`Template ${index + 1}`} */}
|
||||||
<RenameInput value={`Template ${index + 1}`} />
|
<RenameInput value={`Template ${index + 1}`} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -104,7 +104,7 @@ const ProgressBarWidget = ({
|
||||||
|
|
||||||
const Widgets2D = () => {
|
const Widgets2D = () => {
|
||||||
return (
|
return (
|
||||||
<div className="widget2D">
|
<div className="widget2D widgets-wrapper">
|
||||||
<div className="chart-container">
|
<div className="chart-container">
|
||||||
{chartTypes.map((type, index) => {
|
{chartTypes.map((type, index) => {
|
||||||
const widgetTitle = `Widget ${index + 1}`;
|
const widgetTitle = `Widget ${index + 1}`;
|
||||||
|
|
|
@ -12,22 +12,21 @@ const Widgets3D = () => {
|
||||||
];
|
];
|
||||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="widgets-container widget3D">
|
<div className="widgets-container widgets-wrapper widget3D">
|
||||||
{widgets?.map((widget, index) => (
|
{widgets?.map((widget, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className="widget-item"
|
className="widget-item"
|
||||||
draggable
|
draggable
|
||||||
onDragStart={(e) => {
|
onDragStart={(e) => {
|
||||||
let name = widget.name
|
let name = widget.name;
|
||||||
let crt = e.target
|
let crt = e.target;
|
||||||
if (crt instanceof HTMLElement) {
|
if (crt instanceof HTMLElement) {
|
||||||
const widget = crt.cloneNode(true) as HTMLElement;
|
const widget = crt.cloneNode(true) as HTMLElement;
|
||||||
e.dataTransfer.setDragImage(widget, 0, 0)
|
e.dataTransfer.setDragImage(widget, 0, 0);
|
||||||
e.dataTransfer.effectAllowed = "move"
|
e.dataTransfer.effectAllowed = "move";
|
||||||
e.dataTransfer.setData("text/plain", "ui-" + name)
|
e.dataTransfer.setData("text/plain", "ui-" + name);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onPointerDown={() => {
|
onPointerDown={() => {
|
||||||
|
@ -42,7 +41,7 @@ const Widgets3D = () => {
|
||||||
className="widget-image"
|
className="widget-image"
|
||||||
src={widget.img}
|
src={widget.img}
|
||||||
alt={widget.name}
|
alt={widget.name}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -1,32 +1,128 @@
|
||||||
import React, { useRef, useMemo, useCallback, useState } from "react";
|
import React, { useRef, useMemo, useCallback, useState } from "react";
|
||||||
import { InfoIcon } from "../../../icons/ExportCommonIcons";
|
import { InfoIcon, AddIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
|
||||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
import {
|
import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
|
||||||
useSelectedActionSphere,
|
|
||||||
useSimulationStates,
|
|
||||||
useSocketStore
|
|
||||||
} from "../../../../store/store";
|
|
||||||
import * as Types from '../../../../types/world/worldTypes';
|
import * as Types from '../../../../types/world/worldTypes';
|
||||||
import LabeledButton from "../../../ui/inputs/LabledButton";
|
|
||||||
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
|
||||||
|
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||||
|
|
||||||
|
interface ConnectedModel {
|
||||||
|
modelUUID: string;
|
||||||
|
modelName: string;
|
||||||
|
points: {
|
||||||
|
uuid: string;
|
||||||
|
position: [number, number, number];
|
||||||
|
index?: number;
|
||||||
|
}[];
|
||||||
|
triggers?: {
|
||||||
|
uuid: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
isUsed: boolean;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
const ArmBotMechanics: React.FC = () => {
|
const ArmBotMechanics: React.FC = () => {
|
||||||
const { selectedActionSphere } = useSelectedActionSphere();
|
const { selectedActionSphere } = useSelectedActionSphere();
|
||||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
const { simulationStates, setSimulationStates } = useSimulationStates();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const [selectedTrigger, setSelectedTrigger] = useState<string | null>(null);
|
const [selectedProcessIndex, setSelectedProcessIndex] = useState<number | null>(null);
|
||||||
|
const actionsContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const propertiesContainerRef = useRef<HTMLDivElement>(null);
|
// Get connected models and their triggers
|
||||||
|
const connectedModels = useMemo<ConnectedModel[]>(() => {
|
||||||
// Get connected models for dropdowns
|
|
||||||
const connectedModels = useMemo(() => {
|
|
||||||
if (!selectedActionSphere?.points?.uuid) return [];
|
if (!selectedActionSphere?.points?.uuid) return [];
|
||||||
|
|
||||||
|
const armBotPaths = simulationStates.filter(
|
||||||
|
(path): path is Types.ArmBotEventsSchema => path.type === "ArmBot"
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentPoint = armBotPaths.find(
|
||||||
|
(path) => path.points.uuid === selectedActionSphere.points.uuid
|
||||||
|
)?.points;
|
||||||
|
|
||||||
|
if (!currentPoint?.connections?.targets) return [];
|
||||||
|
|
||||||
|
return currentPoint.connections.targets.reduce<ConnectedModel[]>((acc, target) => {
|
||||||
|
const connectedModel = simulationStates.find(
|
||||||
|
(model) => model.modeluuid === target.modelUUID
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!connectedModel) return acc;
|
||||||
|
|
||||||
|
let triggers: { uuid: string; name: string; type: string; isUsed: boolean }[] = [];
|
||||||
|
let points: { uuid: string; position: [number, number, number] }[] = [];
|
||||||
|
|
||||||
|
if (connectedModel.type === "Conveyor") {
|
||||||
|
const conveyor = connectedModel as Types.ConveyorEventsSchema;
|
||||||
|
|
||||||
|
const connectedPointUUIDs = currentPoint?.connections?.targets
|
||||||
|
.filter(t => t.modelUUID === connectedModel.modeluuid)
|
||||||
|
.map(t => t.pointUUID) || [];
|
||||||
|
|
||||||
|
points = conveyor.points
|
||||||
|
.map((point, idx) => ({
|
||||||
|
uuid: point.uuid,
|
||||||
|
position: point.position,
|
||||||
|
index: idx
|
||||||
|
}))
|
||||||
|
.filter(point => connectedPointUUIDs.includes(point.uuid));
|
||||||
|
|
||||||
|
|
||||||
|
triggers = conveyor.points.flatMap(p => p.triggers?.filter(t => t.isUsed) || []);
|
||||||
|
}
|
||||||
|
else if (connectedModel.type === "StaticMachine") {
|
||||||
|
const staticMachine = connectedModel as Types.StaticMachineEventsSchema;
|
||||||
|
|
||||||
|
points = [{
|
||||||
|
uuid: staticMachine.points.uuid,
|
||||||
|
position: staticMachine.points.position
|
||||||
|
}];
|
||||||
|
|
||||||
|
triggers = staticMachine.points.triggers ?
|
||||||
|
[{
|
||||||
|
uuid: staticMachine.points.triggers.uuid,
|
||||||
|
name: staticMachine.points.triggers.name,
|
||||||
|
type: staticMachine.points.triggers.type,
|
||||||
|
isUsed: true // StaticMachine triggers are always considered used
|
||||||
|
}] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!acc.some(m => m.modelUUID === connectedModel.modeluuid)) {
|
||||||
|
acc.push({
|
||||||
|
modelUUID: connectedModel.modeluuid,
|
||||||
|
modelName: connectedModel.modelName,
|
||||||
|
points,
|
||||||
|
triggers
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
}, [selectedActionSphere, simulationStates]);
|
}, [selectedActionSphere, simulationStates]);
|
||||||
|
|
||||||
// Get triggers only from connected models
|
// Get triggers from connected models
|
||||||
const connectedTriggers = useMemo(() => {
|
const connectedTriggers = useMemo(() => {
|
||||||
}, [connectedModels, simulationStates]);
|
return connectedModels.flatMap(model =>
|
||||||
|
(model.triggers || []).map(trigger => ({
|
||||||
|
...trigger,
|
||||||
|
displayName: `${model.modelName} - ${trigger.name}`,
|
||||||
|
modelUUID: model.modelUUID
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}, [connectedModels]);
|
||||||
|
|
||||||
|
// Get all points from connected models
|
||||||
|
const connectedPoints = useMemo(() => {
|
||||||
|
return connectedModels.flatMap(model =>
|
||||||
|
model.points.map(point => ({
|
||||||
|
...point,
|
||||||
|
displayName: `${model.modelName} - Point${typeof point.index === 'number' ? ` ${point.index}` : ''}`,
|
||||||
|
modelUUID: model.modelUUID
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}, [connectedModels]);
|
||||||
|
|
||||||
|
|
||||||
const { selectedPoint } = useMemo(() => {
|
const { selectedPoint } = useMemo(() => {
|
||||||
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null };
|
if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null };
|
||||||
|
@ -45,77 +141,148 @@ const ArmBotMechanics: React.FC = () => {
|
||||||
}, [selectedActionSphere, simulationStates]);
|
}, [selectedActionSphere, simulationStates]);
|
||||||
|
|
||||||
const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => {
|
const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => {
|
||||||
// if (!updatedPath) return;
|
if (!updatedPath) return;
|
||||||
// const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
// const organization = email ? email.split("@")[1].split(".")[0] : "";
|
const organization = email ? email.split("@")[1].split(".")[0] : "";
|
||||||
|
|
||||||
// const data = {
|
const data = {
|
||||||
// organization: organization,
|
organization: organization,
|
||||||
// modeluuid: updatedPath.modeluuid,
|
modeluuid: updatedPath.modeluuid,
|
||||||
// eventData: { type: "ArmBot", points: updatedPath.points }
|
eventData: { type: "ArmBot", points: updatedPath.points }
|
||||||
// }
|
}
|
||||||
|
console.log('data: ', data);
|
||||||
|
|
||||||
// socket.emit('v2:model-asset:updateEventData', data);
|
socket.emit('v2:model-asset:updateEventData', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// const handleActionUpdate = useCallback((updatedAction: Partial<Types.ArmBotEventsSchema['points']['actions']>) => {
|
const handleActionUpdate = useCallback((updatedAction: Partial<Types.ArmBotEventsSchema['points']['actions']>) => {
|
||||||
// if (!selectedActionSphere?.points?.uuid) return;
|
if (!selectedActionSphere?.points?.uuid || !selectedPoint) return;
|
||||||
|
|
||||||
// const updatedPaths = simulationStates.map((path) => {
|
const updatedPaths = simulationStates.map((path) => {
|
||||||
// return path;
|
if (path.type === "ArmBot" && path.points.uuid === selectedActionSphere.points.uuid) {
|
||||||
// });
|
return {
|
||||||
|
...path,
|
||||||
|
points: {
|
||||||
|
...path.points,
|
||||||
|
actions: {
|
||||||
|
...path.points.actions,
|
||||||
|
...updatedAction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
});
|
||||||
|
|
||||||
// const updatedPath = updatedPaths.find(
|
const updatedPath = updatedPaths.find(
|
||||||
// (path): path is Types.ArmBotEventsSchema =>
|
(path): path is Types.ArmBotEventsSchema =>
|
||||||
// path.type === "ArmBot" &&
|
path.type === "ArmBot" &&
|
||||||
// path.points.uuid === selectedActionSphere.points.uuid
|
path.points.uuid === selectedActionSphere.points.uuid
|
||||||
// );
|
);
|
||||||
// updateBackend(updatedPath);
|
updateBackend(updatedPath);
|
||||||
|
|
||||||
// setSimulationStates(updatedPaths);
|
setSimulationStates(updatedPaths);
|
||||||
// }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]);
|
}, [selectedActionSphere?.points?.uuid, selectedPoint, simulationStates, setSimulationStates]);
|
||||||
|
|
||||||
// const handleSpeedChange = useCallback((speed: number) => {
|
const handleSpeedChange = useCallback((speed: number) => {
|
||||||
// handleActionUpdate({ speed });
|
handleActionUpdate({ speed });
|
||||||
// }, [handleActionUpdate]);
|
}, [handleActionUpdate]);
|
||||||
|
|
||||||
// const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => {
|
const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => {
|
||||||
// handleActionUpdate({ processes });
|
handleActionUpdate({ processes });
|
||||||
// }, [handleActionUpdate]);
|
}, [handleActionUpdate]);
|
||||||
|
|
||||||
// const handleTriggerSelect = useCallback((displayName: string) => {
|
const handleAddProcess = useCallback(() => {
|
||||||
// const selected = connectedTriggers.find(t => t.displayName === displayName);
|
if (!selectedPoint) return;
|
||||||
// setSelectedTrigger(selected?.uuid || null);
|
|
||||||
// }, [connectedTriggers]);
|
|
||||||
|
|
||||||
// const handleStartPointSelect = useCallback((pointUUID: string) => {
|
const newProcess: any = {
|
||||||
// if (!selectedTrigger || !selectedPoint) return;
|
triggerId: "",
|
||||||
|
startPoint: "",
|
||||||
|
endPoint: ""
|
||||||
|
};
|
||||||
|
|
||||||
// const updatedProcesses = selectedPoint.actions.processes?.map(process =>
|
const updatedProcesses = selectedPoint.actions.processes ? [...selectedPoint.actions.processes, newProcess] : [newProcess];
|
||||||
// process.triggerId === selectedTrigger
|
|
||||||
// ? { ...process, startPoint: pointUUID }
|
|
||||||
// : process
|
|
||||||
// ) || [];
|
|
||||||
|
|
||||||
// handleProcessChange(updatedProcesses);
|
handleProcessChange(updatedProcesses);
|
||||||
// }, [selectedTrigger, selectedPoint, handleProcessChange]);
|
setSelectedProcessIndex(updatedProcesses.length - 1);
|
||||||
|
}, [selectedPoint, handleProcessChange]);
|
||||||
|
|
||||||
// const handleEndPointSelect = useCallback((pointUUID: string) => {
|
const handleDeleteProcess = useCallback((index: number) => {
|
||||||
// if (!selectedTrigger || !selectedPoint) return;
|
if (!selectedPoint?.actions.processes) return;
|
||||||
|
|
||||||
// const updatedProcesses = selectedPoint.actions.processes?.map(process =>
|
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||||
// process.triggerId === selectedTrigger
|
updatedProcesses.splice(index, 1);
|
||||||
// ? { ...process, endPoint: pointUUID }
|
|
||||||
// : process
|
|
||||||
// ) || [];
|
|
||||||
|
|
||||||
// handleProcessChange(updatedProcesses);
|
handleProcessChange(updatedProcesses);
|
||||||
// }, [selectedTrigger, selectedPoint, handleProcessChange]);
|
|
||||||
|
|
||||||
// const getCurrentProcess = useCallback(() => {
|
// Reset selection if deleting the currently selected process
|
||||||
// if (!selectedTrigger || !selectedPoint) return null;
|
if (selectedProcessIndex === index) {
|
||||||
// return selectedPoint.actions.processes?.find(p => p.triggerId === selectedTrigger);
|
setSelectedProcessIndex(null);
|
||||||
// }, [selectedTrigger, selectedPoint]);
|
} else if (selectedProcessIndex !== null && selectedProcessIndex > index) {
|
||||||
|
// Adjust selection index if needed
|
||||||
|
setSelectedProcessIndex(selectedProcessIndex - 1);
|
||||||
|
}
|
||||||
|
}, [selectedPoint, selectedProcessIndex, handleProcessChange]);
|
||||||
|
|
||||||
|
const handleTriggerSelect = useCallback((displayName: string, index: number) => {
|
||||||
|
const selected = connectedTriggers.find(t => t.displayName === displayName);
|
||||||
|
if (!selected || !selectedPoint?.actions.processes) return;
|
||||||
|
|
||||||
|
const oldProcess = selectedPoint.actions.processes[index];
|
||||||
|
|
||||||
|
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||||
|
|
||||||
|
// Only reset start/end if new trigger invalidates them (your logic can expand this)
|
||||||
|
updatedProcesses[index] = {
|
||||||
|
...oldProcess,
|
||||||
|
triggerId: selected.uuid,
|
||||||
|
startPoint: oldProcess.startPoint || "", // preserve if exists
|
||||||
|
endPoint: oldProcess.endPoint || "" // preserve if exists
|
||||||
|
};
|
||||||
|
|
||||||
|
handleProcessChange(updatedProcesses);
|
||||||
|
}, [connectedTriggers, selectedPoint, handleProcessChange]);
|
||||||
|
|
||||||
|
const handleStartPointSelect = useCallback((displayName: string, index: number) => {
|
||||||
|
if (!selectedPoint?.actions.processes) return;
|
||||||
|
|
||||||
|
const point = connectedPoints.find(p => p.displayName === displayName);
|
||||||
|
if (!point) return;
|
||||||
|
|
||||||
|
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||||
|
updatedProcesses[index] = {
|
||||||
|
...updatedProcesses[index],
|
||||||
|
startPoint: point.uuid
|
||||||
|
};
|
||||||
|
|
||||||
|
handleProcessChange(updatedProcesses);
|
||||||
|
}, [selectedPoint, connectedPoints, handleProcessChange]);
|
||||||
|
|
||||||
|
const handleEndPointSelect = useCallback((displayName: string, index: number) => {
|
||||||
|
if (!selectedPoint?.actions.processes) return;
|
||||||
|
|
||||||
|
const point = connectedPoints.find(p => p.displayName === displayName);
|
||||||
|
if (!point) return;
|
||||||
|
|
||||||
|
const updatedProcesses = [...selectedPoint.actions.processes];
|
||||||
|
updatedProcesses[index] = {
|
||||||
|
...updatedProcesses[index],
|
||||||
|
endPoint: point.uuid
|
||||||
|
};
|
||||||
|
|
||||||
|
handleProcessChange(updatedProcesses);
|
||||||
|
}, [selectedPoint, connectedPoints, handleProcessChange]);
|
||||||
|
|
||||||
|
const getProcessByIndex = useCallback((index: number) => {
|
||||||
|
if (!selectedPoint?.actions.processes || index >= selectedPoint.actions.processes.length) return null;
|
||||||
|
return selectedPoint.actions.processes[index];
|
||||||
|
}, [selectedPoint]);
|
||||||
|
|
||||||
|
const getFilteredTriggerOptions = (currentIndex: number) => {
|
||||||
|
const usedTriggerUUIDs = selectedPoint?.actions.processes?.filter((_, i) => i !== currentIndex).map(p => p.triggerId).filter(Boolean) ?? [];
|
||||||
|
|
||||||
|
return connectedTriggers.filter(trigger => !usedTriggerUUIDs.includes(trigger.uuid)).map(trigger => trigger.displayName);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
|
<div className="machine-mechanics-container" key={selectedPoint?.uuid}>
|
||||||
|
@ -124,10 +291,10 @@ const ArmBotMechanics: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="machine-mechanics-content-container">
|
<div className="machine-mechanics-content-container">
|
||||||
<div className="selected-properties-container" ref={propertiesContainerRef}>
|
<div className="selected-properties-container">
|
||||||
<div className="properties-header">ArmBot Properties</div>
|
<div className="properties-header">ArmBot Properties</div>
|
||||||
|
|
||||||
{/* {selectedPoint && (
|
{selectedPoint && (
|
||||||
<>
|
<>
|
||||||
<InputWithDropDown
|
<InputWithDropDown
|
||||||
key={`speed-${selectedPoint.uuid}`}
|
key={`speed-${selectedPoint.uuid}`}
|
||||||
|
@ -136,36 +303,90 @@ const ArmBotMechanics: React.FC = () => {
|
||||||
onChange={(value) => handleSpeedChange(parseInt(value))}
|
onChange={(value) => handleSpeedChange(parseInt(value))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<LabledDropdown
|
<div className="actions">
|
||||||
key={`trigger-select-${selectedPoint.uuid}`}
|
<div className="header">
|
||||||
label="Select Trigger"
|
<div className="header-value">Processes</div>
|
||||||
defaultOption={connectedTriggers.find(t => t.uuid === selectedTrigger)?.displayName || ''}
|
<div className="add-button" onClick={handleAddProcess}>
|
||||||
onSelect={handleTriggerSelect}
|
<AddIcon /> Add
|
||||||
options={connectedTriggers.map(trigger => trigger.displayName)}
|
</div>
|
||||||
/>
|
</div>
|
||||||
|
<div
|
||||||
|
className="lists-main-container"
|
||||||
|
ref={actionsContainerRef}
|
||||||
|
style={{ height: "120px" }}
|
||||||
|
>
|
||||||
|
<div className="list-container">
|
||||||
|
{selectedPoint.actions.processes?.map((process, index) => (
|
||||||
|
<div
|
||||||
|
key={`process-${index}`}
|
||||||
|
className={`list-item ${selectedProcessIndex === index ? "active" : ""}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="value"
|
||||||
|
onClick={() => setSelectedProcessIndex(index)}
|
||||||
|
>
|
||||||
|
Process {index + 1}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="remove-button"
|
||||||
|
onClick={() => handleDeleteProcess(index)}
|
||||||
|
>
|
||||||
|
<RemoveIcon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="resize-icon"
|
||||||
|
id="action-resize"
|
||||||
|
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
|
||||||
|
>
|
||||||
|
<ResizeHeightIcon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{selectedTrigger && (
|
{selectedProcessIndex !== null && (
|
||||||
<>
|
<div className="process-configuration">
|
||||||
<LabledDropdown
|
<LabledDropdown
|
||||||
key={`start-point-${selectedTrigger}`}
|
key={`trigger-select-${selectedProcessIndex}`}
|
||||||
|
label="Select Trigger"
|
||||||
|
defaultOption={
|
||||||
|
connectedTriggers.find(t =>
|
||||||
|
t.uuid === getProcessByIndex(selectedProcessIndex)?.triggerId
|
||||||
|
)?.displayName || 'Select a trigger'
|
||||||
|
}
|
||||||
|
onSelect={(value) => handleTriggerSelect(value, selectedProcessIndex)}
|
||||||
|
options={getFilteredTriggerOptions(selectedProcessIndex)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LabledDropdown
|
||||||
|
key={`start-point-${selectedProcessIndex}`}
|
||||||
label="Start Point"
|
label="Start Point"
|
||||||
defaultOption={getCurrentProcess()?.startPoint || ''}
|
defaultOption={
|
||||||
onSelect={handleStartPointSelect}
|
connectedPoints.find(p =>
|
||||||
options={connectedModels.map((model, index) => `${model.modelName} [${index}]`)}
|
p.uuid === getProcessByIndex(selectedProcessIndex)?.startPoint
|
||||||
|
)?.displayName || 'Select start point'
|
||||||
|
}
|
||||||
|
onSelect={(value) => handleStartPointSelect(value, selectedProcessIndex)}
|
||||||
|
options={connectedPoints.map(point => point.displayName)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<LabledDropdown
|
<LabledDropdown
|
||||||
key={`end-point-${selectedTrigger}`}
|
key={`end-point-${selectedProcessIndex}`}
|
||||||
label="End Point"
|
label="End Point"
|
||||||
defaultOption={getCurrentProcess()?.endPoint || ''}
|
defaultOption={
|
||||||
onSelect={handleEndPointSelect}
|
connectedPoints.find(p =>
|
||||||
options={connectedModels.map((model, index) => `${model.modelName} [${index}]`)}
|
p.uuid === getProcessByIndex(selectedProcessIndex)?.endPoint
|
||||||
|
)?.displayName || 'Select end point'
|
||||||
|
}
|
||||||
|
onSelect={(value) => handleEndPointSelect(value, selectedProcessIndex)}
|
||||||
|
options={connectedPoints.map(point => point.displayName)}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)} */}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="footer">
|
<div className="footer">
|
||||||
|
|
|
@ -647,7 +647,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
setSelectedItem({ type: "action", item: action })
|
setSelectedItem({ type: "action", item: action })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<input type="radio" name="action" id="action" defaultChecked={action.isUsed} />
|
<input type="radio" name="action" id="action" checked={action.isUsed} readOnly />
|
||||||
<RenameInput value={action.name} />
|
<RenameInput value={action.name} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -696,7 +696,7 @@ const ConveyorMechanics: React.FC = () => {
|
||||||
setSelectedItem({ type: "trigger", item: trigger })
|
setSelectedItem({ type: "trigger", item: trigger })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<input type="radio" name="trigger" id="trigger" defaultChecked={trigger.isUsed} />
|
<input type="radio" name="trigger" id="trigger" checked={trigger.isUsed} readOnly />
|
||||||
<RenameInput value={trigger.name} />
|
<RenameInput value={trigger.name} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
|
||||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||||
import Vector3Input from "../customInput/Vector3Input";
|
import Vector3Input from "../customInput/Vector3Input";
|
||||||
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
||||||
import { useEditPosition, usezonePosition, usezoneTarget } from "../../../../store/store";
|
import { useEditPosition, usezonePosition, useZones, usezoneTarget } from "../../../../store/store";
|
||||||
import { zoneCameraUpdate } from "../../../../services/realTimeVisulization/zoneData/zoneCameraUpdation";
|
import { zoneCameraUpdate } from "../../../../services/realTimeVisulization/zoneData/zoneCameraUpdation";
|
||||||
|
|
||||||
const ZoneProperties: React.FC = () => {
|
const ZoneProperties: React.FC = () => {
|
||||||
|
@ -10,6 +10,7 @@ const ZoneProperties: React.FC = () => {
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
const { zonePosition, setZonePosition } = usezonePosition();
|
const { zonePosition, setZonePosition } = usezonePosition();
|
||||||
const { zoneTarget, setZoneTarget } = usezoneTarget();
|
const { zoneTarget, setZoneTarget } = usezoneTarget();
|
||||||
|
const { zones, setZones } = useZones();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setZonePosition(selectedZone.zoneViewPortPosition)
|
setZonePosition(selectedZone.zoneViewPortPosition)
|
||||||
|
@ -31,11 +32,11 @@ const ZoneProperties: React.FC = () => {
|
||||||
if (response.message === "updated successfully") {
|
if (response.message === "updated successfully") {
|
||||||
setEdit(false);
|
setEdit(false);
|
||||||
} else {
|
} else {
|
||||||
console.log("Not updated Camera Position and Target");
|
console.log(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error in handleSetView:", error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,17 +44,32 @@ const ZoneProperties: React.FC = () => {
|
||||||
setEdit(!Edit); // This will toggle the `Edit` state correctly
|
setEdit(!Edit); // This will toggle the `Edit` state correctly
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleZoneNameChange(newName: string) {
|
async function handleZoneNameChange(newName: string) {
|
||||||
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
const zonesdata = {
|
||||||
|
zoneId: selectedZone.zoneId,
|
||||||
|
zoneName: newName
|
||||||
|
};
|
||||||
|
// Call your API to update the zone
|
||||||
|
let response = await zoneCameraUpdate(zonesdata, organization);
|
||||||
|
console.log('response: ', response);
|
||||||
|
if (response.message === "updated successfully") {
|
||||||
|
setZones((prevZones: any[]) =>
|
||||||
|
prevZones.map((zone) =>
|
||||||
|
zone.zoneId === selectedZone.zoneId
|
||||||
|
? { ...zone, zoneName: newName }
|
||||||
|
: zone
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
console.log(response?.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleVectorChange(key: "zoneViewPortTarget" | "zoneViewPortPosition", newValue: [number, number, number]) {
|
function handleVectorChange(key: "zoneViewPortTarget" | "zoneViewPortPosition", newValue: [number, number, number]) {
|
||||||
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
|
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
}, [selectedZone]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="zone-properties-container">
|
<div className="zone-properties-container">
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
} from "../../icons/RealTimeVisulationIcons";
|
} from "../../icons/RealTimeVisulationIcons";
|
||||||
import { AddIcon } from "../../icons/ExportCommonIcons";
|
import { AddIcon } from "../../icons/ExportCommonIcons";
|
||||||
import { useSocketStore } from "../../../store/store";
|
import { useSocketStore } from "../../../store/store";
|
||||||
|
import { clearPanel } from "../../../services/realTimeVisulization/zoneData/clearPanel";
|
||||||
|
import { lockPanel } from "../../../services/realTimeVisulization/zoneData/lockPanel";
|
||||||
|
|
||||||
// Define the type for `Side`
|
// Define the type for `Side`
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
@ -88,8 +90,10 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to toggle lock/unlock a panel
|
// Function to toggle lock/unlock a panel
|
||||||
const toggleLockPanel = (side: Side) => {
|
const toggleLockPanel = async (side: Side) => {
|
||||||
console.log("side: ", side);
|
// console.log('side: ', side);
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
||||||
//add api
|
//add api
|
||||||
const newLockedPanels = selectedZone.lockedPanels.includes(side)
|
const newLockedPanels = selectedZone.lockedPanels.includes(side)
|
||||||
? selectedZone.lockedPanels.filter((panel) => panel !== side)
|
? selectedZone.lockedPanels.filter((panel) => panel !== side)
|
||||||
|
@ -100,29 +104,70 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
lockedPanels: newLockedPanels,
|
lockedPanels: newLockedPanels,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the selectedZone state
|
let lockedPanel = {
|
||||||
|
organization: organization,
|
||||||
|
lockedPanel: newLockedPanels,
|
||||||
|
zoneId: selectedZone.zoneId,
|
||||||
|
};
|
||||||
|
if (visualizationSocket) {
|
||||||
|
visualizationSocket.emit("v2:viz-panel:locked", lockedPanel);
|
||||||
|
}
|
||||||
|
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
|
// let response = await lockPanel(selectedZone.zoneId, organization, newLockedPanels)
|
||||||
|
// console.log('response: ', response);
|
||||||
|
// if (response.message === 'locked panel updated successfully') {
|
||||||
|
// // Update the selectedZone state
|
||||||
|
// setSelectedZone(updatedZone);
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to clean all widgets from a panel
|
// Function to clean all widgets from a panel
|
||||||
const cleanPanel = (side: Side) => {
|
const cleanPanel = async (side: Side) => {
|
||||||
//add api
|
//add api
|
||||||
console.log("side: ", side);
|
// console.log('side: ', side);
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
||||||
|
|
||||||
|
let clearPanel = {
|
||||||
|
organization: organization,
|
||||||
|
panelName: side,
|
||||||
|
zoneId: selectedZone.zoneId,
|
||||||
|
};
|
||||||
|
if (visualizationSocket) {
|
||||||
|
visualizationSocket.emit("v2:viz-panel:clear", clearPanel);
|
||||||
|
}
|
||||||
const cleanedWidgets = selectedZone.widgets.filter(
|
const cleanedWidgets = selectedZone.widgets.filter(
|
||||||
(widget) => widget.panel !== side
|
(widget) => widget.panel !== side
|
||||||
);
|
);
|
||||||
|
|
||||||
const updatedZone = {
|
const updatedZone = {
|
||||||
...selectedZone,
|
...selectedZone,
|
||||||
widgets: cleanedWidgets,
|
widgets: cleanedWidgets,
|
||||||
};
|
};
|
||||||
// Update the selectedZone state
|
// Update the selectedZone state
|
||||||
|
// console.log('updatedZone: ', updatedZone);
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
|
|
||||||
|
// let response = await clearPanel(selectedZone.zoneId, organization, side)
|
||||||
|
// console.log('response: ', response);
|
||||||
|
// if (response.message === 'PanelWidgets cleared successfully') {
|
||||||
|
|
||||||
|
// const cleanedWidgets = selectedZone.widgets.filter(
|
||||||
|
// (widget) => widget.panel !== side
|
||||||
|
// );
|
||||||
|
// const updatedZone = {
|
||||||
|
// ...selectedZone,
|
||||||
|
// widgets: cleanedWidgets,
|
||||||
|
// };
|
||||||
|
// // Update the selectedZone state
|
||||||
|
// setSelectedZone(updatedZone);
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to handle "+" button click
|
// Function to handle "+" button click
|
||||||
const handlePlusButtonClick = async (side: Side) => {
|
const handlePlusButtonClick = async (side: Side) => {
|
||||||
if (selectedZone.activeSides.includes(side)) {
|
if (selectedZone.activeSides.includes(side)) {
|
||||||
|
console.log("open");
|
||||||
// Panel already exists: Remove widgets from that side and update activeSides
|
// Panel already exists: Remove widgets from that side and update activeSides
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
||||||
|
|
|
@ -13,6 +13,10 @@ import { get3dWidgetZoneData } from "../../../services/realTimeVisulization/zone
|
||||||
// Define the type for `Side`
|
// Define the type for `Side`
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
interface HiddenPanels {
|
||||||
|
[zoneId: string]: Side[];
|
||||||
|
}
|
||||||
|
|
||||||
interface DisplayZoneProps {
|
interface DisplayZoneProps {
|
||||||
zonesData: {
|
zonesData: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
|
@ -59,12 +63,15 @@ interface DisplayZoneProps {
|
||||||
}[];
|
}[];
|
||||||
}>
|
}>
|
||||||
>;
|
>;
|
||||||
|
hiddenPanels: HiddenPanels; // Updated prop type
|
||||||
|
setHiddenPanels: React.Dispatch<React.SetStateAction<HiddenPanels>>; // Updated prop type
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisplayZone: React.FC<DisplayZoneProps> = ({
|
const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
zonesData,
|
zonesData,
|
||||||
selectedZone,
|
selectedZone,
|
||||||
setSelectedZone,
|
setSelectedZone,
|
||||||
|
hiddenPanels,
|
||||||
}) => {
|
}) => {
|
||||||
// Ref for the container element
|
// Ref for the container element
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
@ -73,9 +80,9 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
// State to track overflow visibility
|
// State to track overflow visibility
|
||||||
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
||||||
const [showRightArrow, setShowRightArrow] = useState(false);
|
const [showRightArrow, setShowRightArrow] = useState(false);
|
||||||
const { floatingWidget, setFloatingWidget } = useFloatingWidget()
|
const { floatingWidget, setFloatingWidget } = useFloatingWidget();
|
||||||
|
|
||||||
const{setSelectedChartId}=useWidgetStore()
|
const { setSelectedChartId } = useWidgetStore();
|
||||||
|
|
||||||
// Function to calculate overflow state
|
// Function to calculate overflow state
|
||||||
const updateOverflowState = useCallback(() => {
|
const updateOverflowState = useCallback(() => {
|
||||||
|
@ -152,7 +159,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
if (selectedZone?.zoneId === zoneId) {
|
if (selectedZone?.zoneId === zoneId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSelectedChartId(null)
|
setSelectedChartId(null);
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
let response = await getSelect2dZoneData(zoneId, organization);
|
let response = await getSelect2dZoneData(zoneId, organization);
|
||||||
|
@ -178,15 +185,18 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
zoneViewPortTarget: response.viewPortCenter || {},
|
zoneViewPortTarget: response.viewPortCenter || {},
|
||||||
zoneViewPortPosition: response.viewPortposition || {},
|
zoneViewPortPosition: response.viewPortposition || {},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className={`zone-wrapper ${selectedZone?.activeSides?.includes("bottom") ? "bottom" : ""}`}
|
className={`zone-wrapper ${
|
||||||
|
selectedZone?.activeSides?.includes("bottom") &&
|
||||||
|
!hiddenPanels[selectedZone.zoneId]?.includes("bottom")
|
||||||
|
? "bottom"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
{/* Left Arrow */}
|
{/* Left Arrow */}
|
||||||
{showLeftArrow && (
|
{showLeftArrow && (
|
||||||
|
@ -206,8 +216,12 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
{Object.keys(zonesData).map((zoneName, index) => (
|
{Object.keys(zonesData).map((zoneName, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""}`}
|
className={`zone ${
|
||||||
onClick={() => handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)}
|
selectedZone.zoneName === zoneName ? "active" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() =>
|
||||||
|
handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{zoneName}
|
{zoneName}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -49,7 +49,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const zones = useDroppedObjectsStore((state) => state.zones);
|
const zones = useDroppedObjectsStore((state) => state.zones);
|
||||||
console.log('zones: ', zones);
|
|
||||||
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
||||||
const updateObjectPosition = useDroppedObjectsStore(
|
const updateObjectPosition = useDroppedObjectsStore(
|
||||||
(state) => state.updateObjectPosition
|
(state) => state.updateObjectPosition
|
||||||
|
@ -568,6 +568,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
left: leftPosition,
|
left: leftPosition,
|
||||||
right: rightPosition,
|
right: rightPosition,
|
||||||
bottom: bottomPosition,
|
bottom: bottomPosition,
|
||||||
|
pointerEvents: isPlaying ? "none" : "auto",
|
||||||
}}
|
}}
|
||||||
onPointerDown={(event) => {
|
onPointerDown={(event) => {
|
||||||
setSelectedChartId(obj);
|
setSelectedChartId(obj);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import DisplayZone from "./DisplayZone";
|
||||||
import Scene from "../../../modules/scene/scene";
|
import Scene from "../../../modules/scene/scene";
|
||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
|
|
||||||
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
|
import { useDroppedObjectsStore, useFloatingWidget } from "../../../store/useDroppedObjectsStore";
|
||||||
import {
|
import {
|
||||||
useAsset3dWidget,
|
useAsset3dWidget,
|
||||||
useSocketStore,
|
useSocketStore,
|
||||||
|
@ -73,9 +73,8 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
||||||
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
||||||
|
|
||||||
const [floatingWidgets, setFloatingWidgets] = useState<
|
// const [floatingWidgets, setFloatingWidgets] = useState<Record<string, { zoneName: string; zoneId: string; objects: any[] }>>({});
|
||||||
Record<string, { zoneName: string; zoneId: string; objects: any[] }>
|
const { floatingWidget, setFloatingWidget } = useFloatingWidget()
|
||||||
>({});
|
|
||||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
||||||
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
|
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
@ -135,7 +134,6 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
|
|
||||||
const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
|
const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
|
@ -181,6 +179,25 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-float:add", addFloatingWidget);
|
visualizationSocket.emit("v2:viz-float:add", addFloatingWidget);
|
||||||
}
|
}
|
||||||
|
useDroppedObjectsStore
|
||||||
|
.getState()
|
||||||
|
.addObject(selectedZone.zoneName, newObject);
|
||||||
|
|
||||||
|
//I need to console here objects based on selectedZone.zoneId
|
||||||
|
// Console the objects after adding
|
||||||
|
const droppedObjectsStore = useDroppedObjectsStore.getState();
|
||||||
|
const currentZone = droppedObjectsStore.zones[selectedZone.zoneName];
|
||||||
|
|
||||||
|
if (currentZone && currentZone.zoneId === selectedZone.zoneId) {
|
||||||
|
console.log(
|
||||||
|
`Objects for Zone ID: ${selectedZone.zoneId}`,
|
||||||
|
currentZone.objects
|
||||||
|
);
|
||||||
|
setFloatingWidget(currentZone.objects)
|
||||||
|
} else {
|
||||||
|
console.warn("Zone not found or mismatched zoneId");
|
||||||
|
}
|
||||||
|
|
||||||
// let response = await addingFloatingWidgets(
|
// let response = await addingFloatingWidgets(
|
||||||
// selectedZone.zoneId,
|
// selectedZone.zoneId,
|
||||||
// organization,
|
// organization,
|
||||||
|
@ -188,24 +205,12 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
// );
|
// );
|
||||||
// Add the dropped object to the zone if the API call is successful
|
// Add the dropped object to the zone if the API call is successful
|
||||||
// if (response.message === "FloatWidget created successfully") {
|
// if (response.message === "FloatWidget created successfully") {
|
||||||
useDroppedObjectsStore
|
|
||||||
.getState()
|
|
||||||
.addObject(selectedZone.zoneName, newObject);
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Update floating widgets state
|
// Update floating widgets state
|
||||||
setFloatingWidgets((prevWidgets) => ({
|
|
||||||
...prevWidgets,
|
} catch (error) { }
|
||||||
[selectedZone.zoneName]: {
|
|
||||||
...prevWidgets[selectedZone.zoneName],
|
|
||||||
zoneName: selectedZone.zoneName,
|
|
||||||
zoneId: selectedZone.zoneId,
|
|
||||||
objects: [
|
|
||||||
...(prevWidgets[selectedZone.zoneName]?.objects || []),
|
|
||||||
newObject,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} catch (error) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -289,6 +294,8 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
zonesData={zonesData}
|
zonesData={zonesData}
|
||||||
selectedZone={selectedZone}
|
selectedZone={selectedZone}
|
||||||
setSelectedZone={setSelectedZone}
|
setSelectedZone={setSelectedZone}
|
||||||
|
hiddenPanels={hiddenPanels}
|
||||||
|
setHiddenPanels={setHiddenPanels}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!isPlaying && selectedZone?.zoneName !== "" && (
|
{!isPlaying && selectedZone?.zoneName !== "" && (
|
||||||
|
|
|
@ -12,25 +12,66 @@ export default function ZoneAssets() {
|
||||||
if (!zoneAssetId) return
|
if (!zoneAssetId) return
|
||||||
console.log('zoneAssetId: ', zoneAssetId);
|
console.log('zoneAssetId: ', zoneAssetId);
|
||||||
let AssetMesh = scene.getObjectByProperty("uuid", zoneAssetId.id);
|
let AssetMesh = scene.getObjectByProperty("uuid", zoneAssetId.id);
|
||||||
if (!AssetMesh) return;
|
if (AssetMesh) {
|
||||||
|
const bbox = new THREE.Box3().setFromObject(AssetMesh);
|
||||||
|
const size = bbox.getSize(new THREE.Vector3());
|
||||||
|
const center = bbox.getCenter(new THREE.Vector3());
|
||||||
|
|
||||||
const bbox = new THREE.Box3().setFromObject(AssetMesh);
|
const front = new THREE.Vector3(0, 0, 1);
|
||||||
const size = bbox.getSize(new THREE.Vector3());
|
AssetMesh.localToWorld(front);
|
||||||
const center = bbox.getCenter(new THREE.Vector3());
|
front.sub(AssetMesh.position).normalize();
|
||||||
|
|
||||||
const front = new THREE.Vector3(0, 0, 1);
|
const distance = Math.max(size.x, size.y, size.z) * 2;
|
||||||
AssetMesh.localToWorld(front);
|
const newPosition = center.clone().addScaledVector(front, distance);
|
||||||
front.sub(AssetMesh.position).normalize();
|
|
||||||
|
|
||||||
const distance = Math.max(size.x, size.y, size.z) * 2;
|
controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
|
||||||
const newPosition = center.clone().addScaledVector(front, distance);
|
controls.setTarget(center.x, center.y, center.z, true);
|
||||||
|
controls.fitToBox(AssetMesh, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
||||||
|
|
||||||
controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
|
setSelectedFloorItem(AssetMesh);
|
||||||
controls.setTarget(center.x, center.y, center.z, true);
|
} else {
|
||||||
controls.fitToBox(AssetMesh, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
console.log('zoneAssetId: ', zoneAssetId)
|
||||||
|
if (Array.isArray(zoneAssetId.position) && zoneAssetId.position.length >= 3) {
|
||||||
|
let selectedAssetPosition = [
|
||||||
|
zoneAssetId.position[0],
|
||||||
|
10,
|
||||||
|
zoneAssetId.position[2]
|
||||||
|
];
|
||||||
|
console.log('selectedAssetPosition: ', selectedAssetPosition);
|
||||||
|
let selectedAssetTarget = [
|
||||||
|
zoneAssetId.position[0],
|
||||||
|
zoneAssetId.position[1],
|
||||||
|
zoneAssetId.position[2]
|
||||||
|
];
|
||||||
|
console.log('selectedAssetTarget: ', selectedAssetTarget);
|
||||||
|
const setCam = async () => {
|
||||||
|
await controls?.setLookAt(...selectedAssetPosition, ...selectedAssetTarget, true);
|
||||||
|
setTimeout(() => {
|
||||||
|
let AssetMesh = scene.getObjectByProperty("uuid", zoneAssetId.id);
|
||||||
|
if (AssetMesh) {
|
||||||
|
const bbox = new THREE.Box3().setFromObject(AssetMesh);
|
||||||
|
const size = bbox.getSize(new THREE.Vector3());
|
||||||
|
const center = bbox.getCenter(new THREE.Vector3());
|
||||||
|
|
||||||
setSelectedFloorItem(AssetMesh);
|
const front = new THREE.Vector3(0, 0, 1);
|
||||||
|
AssetMesh.localToWorld(front);
|
||||||
|
front.sub(AssetMesh.position).normalize();
|
||||||
|
|
||||||
|
const distance = Math.max(size.x, size.y, size.z) * 2;
|
||||||
|
const newPosition = center.clone().addScaledVector(front, distance);
|
||||||
|
|
||||||
|
controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
|
||||||
|
controls.setTarget(center.x, center.y, center.z, true);
|
||||||
|
controls.fitToBox(AssetMesh, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
||||||
|
|
||||||
|
setSelectedFloorItem(AssetMesh);
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
|
||||||
|
};
|
||||||
|
setCam();
|
||||||
|
}
|
||||||
|
}
|
||||||
}, [zoneAssetId, scene, controls])
|
}, [zoneAssetId, scene, controls])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { AddIcon, ArrowIcon, FocusIcon } from "../../icons/ExportCommonIcons";
|
||||||
import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect";
|
import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect";
|
||||||
import { useFloorItems, useZones } from "../../../store/store";
|
import { useFloorItems, useZones } from "../../../store/store";
|
||||||
import { useSelectedZoneStore } from "../../../store/useZoneStore";
|
import { useSelectedZoneStore } from "../../../store/useZoneStore";
|
||||||
|
import { getZone2dData } from "../../../services/realTimeVisulization/zoneData/getZoneData";
|
||||||
|
|
||||||
interface DropDownListProps {
|
interface DropDownListProps {
|
||||||
value?: string; // Value to display in the DropDownList
|
value?: string; // Value to display in the DropDownList
|
||||||
|
@ -52,10 +53,10 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
||||||
interface ZoneData {
|
interface ZoneData {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
assets: { id: string; name: string; position?: [] ;rotation?:{}}[];
|
assets: { id: string; name: string; position?: []; rotation?: {} }[];
|
||||||
}
|
}
|
||||||
const [zoneDataList, setZoneDataList] = useState<ZoneData[]>([]);
|
const [zoneDataList, setZoneDataList] = useState<ZoneData[]>([]);
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { floorItems } = useFloorItems();
|
||||||
|
|
||||||
const isPointInsidePolygon = (point: [number, number], polygon: [number, number][]) => {
|
const isPointInsidePolygon = (point: [number, number], polygon: [number, number][]) => {
|
||||||
let inside = false;
|
let inside = false;
|
||||||
|
@ -70,9 +71,9 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
||||||
}
|
}
|
||||||
return inside;
|
return inside;
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
const updatedZoneList: ZoneData[] = zones.map((zone: Zone) => {
|
useEffect(() => {
|
||||||
|
const updatedZoneList: ZoneData[] = zones?.map((zone: Zone) => {
|
||||||
const polygon2D = zone.points.map((p: [number, number, number]) => [p[0], p[2]]) as [number, number][];
|
const polygon2D = zone.points.map((p: [number, number, number]) => [p[0], p[2]]) as [number, number][];
|
||||||
|
|
||||||
const assetsInZone = floorItems
|
const assetsInZone = floorItems
|
||||||
|
@ -84,7 +85,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
||||||
id: item.modeluuid,
|
id: item.modeluuid,
|
||||||
name: item.modelname,
|
name: item.modelname,
|
||||||
position: item.position,
|
position: item.position,
|
||||||
rotation:item.rotation
|
rotation: item.rotation
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -96,9 +97,6 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
||||||
setZoneDataList(updatedZoneList);
|
setZoneDataList(updatedZoneList);
|
||||||
}, [zones, floorItems]);
|
}, [zones, floorItems]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dropdown-list-container">
|
<div className="dropdown-list-container">
|
||||||
<div className="head">
|
<div className="head">
|
||||||
|
|
|
@ -13,7 +13,9 @@ import {
|
||||||
RmoveIcon,
|
RmoveIcon,
|
||||||
} from "../../icons/ExportCommonIcons";
|
} from "../../icons/ExportCommonIcons";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useThree } from "@react-three/fiber";
|
||||||
import { useZoneAssetId } from "../../../store/store";
|
import { useFloorItems, useZoneAssetId } from "../../../store/store";
|
||||||
|
import { zoneCameraUpdate } from "../../../services/realTimeVisulization/zoneData/zoneCameraUpdation";
|
||||||
|
import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
||||||
|
|
||||||
interface Asset {
|
interface Asset {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -38,11 +40,12 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||||
const { activeModule, setActiveModule } = useModuleStore();
|
const { activeModule, setActiveModule } = useModuleStore();
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
||||||
|
|
||||||
const { setSubModule } = useSubModuleStore();
|
const { setSubModule } = useSubModuleStore();
|
||||||
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>(
|
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
useSelectedZoneStore.getState().setSelectedZone({
|
useSelectedZoneStore.getState().setSelectedZone({
|
||||||
|
@ -67,7 +70,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||||
async function handleSelectZone(id: string) {
|
async function handleSelectZone(id: string) {
|
||||||
try {
|
try {
|
||||||
if (selectedZone?.zoneId === id) {
|
if (selectedZone?.zoneId === id) {
|
||||||
console.log("Zone is already selected:", selectedZone.zoneName);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,19 +92,52 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||||
zoneViewPortPosition: response?.viewPortposition || [],
|
zoneViewPortPosition: response?.viewPortposition || [],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Zone selected:", response?.zoneName);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error selecting zone:", error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function handleAssetClick(asset: Asset) {
|
function handleAssetClick(asset: Asset) {
|
||||||
setZoneAssetId(asset)
|
setZoneAssetId(asset)
|
||||||
}
|
}
|
||||||
|
async function handleZoneNameChange(newName: string) {
|
||||||
|
//zone apiiiiii
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
let zonesdata = {
|
||||||
|
zoneId: selectedZone.zoneId,
|
||||||
|
zoneName: newName
|
||||||
|
};
|
||||||
|
let response = await zoneCameraUpdate(zonesdata, organization);
|
||||||
|
if (response.message === "updated successfully") {
|
||||||
|
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function handleZoneAssetName(newName: string) {
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
|
if (zoneAssetId?.id) {
|
||||||
|
let response = await setFloorItemApi(organization, zoneAssetId.id, newName)
|
||||||
|
console.log('response: ', response);
|
||||||
|
setFloorItems((prevFloorItems: any[]) =>
|
||||||
|
prevFloorItems.map((floorItems) =>
|
||||||
|
floorItems.modeluuid === zoneAssetId.id
|
||||||
|
? { ...floorItems, modelname: response.modelname }
|
||||||
|
: floorItems
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('newName: ', newName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{items.length > 0 ? (
|
{items?.length > 0 ? (
|
||||||
<ul className="list-wrapper">
|
<ul className="list-wrapper">
|
||||||
{items.map((item) => (
|
{items?.map((item) => (
|
||||||
<React.Fragment key={`zone-${item.id}`}>
|
<React.Fragment key={`zone-${item.id}`}>
|
||||||
<li className="list-container">
|
<li className="list-container">
|
||||||
<div className="list-item">
|
<div className="list-item">
|
||||||
|
@ -110,7 +146,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||||
className="value"
|
className="value"
|
||||||
onClick={() => handleSelectZone(item.id)}
|
onClick={() => handleSelectZone(item.id)}
|
||||||
>
|
>
|
||||||
<RenameInput value={item.name} />
|
<RenameInput value={item.name} onRename={handleZoneNameChange} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="options-container">
|
<div className="options-container">
|
||||||
|
@ -147,8 +183,8 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||||
className="list-container asset-item"
|
className="list-container asset-item"
|
||||||
>
|
>
|
||||||
<div className="list-item">
|
<div className="list-item">
|
||||||
<div className="value" onClick={() => handleAssetClick(asset)}>
|
<div className="value" onClick={() => handleAssetClick(asset)} >
|
||||||
<RenameInput value={asset.name} />
|
<RenameInput value={asset.name} onRename={handleZoneAssetName} />
|
||||||
</div>
|
</div>
|
||||||
<div className="options-container">
|
<div className="options-container">
|
||||||
<div className="lock option">
|
<div className="lock option">
|
||||||
|
|
|
@ -1,103 +1,96 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from "react";
|
||||||
import { Line } from 'react-chartjs-2'
|
import { Line } from "react-chartjs-2";
|
||||||
import useChartStore from '../../../../store/useChartStore';
|
import useChartStore from "../../../../store/useChartStore";
|
||||||
import { useWidgetStore } from '../../../../store/useWidgetStore';
|
import { useWidgetStore } from "../../../../store/useWidgetStore";
|
||||||
import axios from 'axios';
|
import axios from "axios";
|
||||||
import io from "socket.io-client";
|
import io from "socket.io-client";
|
||||||
import { WalletIcon } from '../../../icons/3dChartIcons';
|
import { WalletIcon } from "../../../icons/3dChartIcons";
|
||||||
|
|
||||||
|
const TotalCardComponent = ({ object }: any) => {
|
||||||
|
const [progress, setProgress] = useState<any>(0);
|
||||||
|
const [measurements, setmeasurements] = useState<any>({});
|
||||||
|
const [duration, setDuration] = useState("1h");
|
||||||
|
const [name, setName] = useState(object.header ? object.header : "");
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
const { header, flotingDuration, flotingMeasurements } = useChartStore();
|
||||||
|
const { selectedChartId } = useWidgetStore();
|
||||||
|
|
||||||
const TotalCardComponent = ({
|
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||||
object
|
|
||||||
}: any) => {
|
|
||||||
|
|
||||||
const [ progress, setProgress ] = useState<any>(0)
|
useEffect(() => {
|
||||||
const [measurements, setmeasurements] = useState<any>({});
|
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
|
||||||
const [duration, setDuration] = useState("1h")
|
return;
|
||||||
const [name, setName] = useState(object.header ? object.header : '')
|
|
||||||
const email = localStorage.getItem("email") || "";
|
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]
|
|
||||||
const { header, flotingDuration, flotingMeasurements } = useChartStore();
|
|
||||||
const { selectedChartId } = useWidgetStore();
|
|
||||||
|
|
||||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
const socket = io(`http://${iotApiUrl}`);
|
||||||
|
|
||||||
useEffect(() => {
|
const inputData = {
|
||||||
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
|
measurements,
|
||||||
|
duration,
|
||||||
|
interval: 1000,
|
||||||
|
};
|
||||||
|
|
||||||
const socket = io(`http://${iotApiUrl}`);
|
const startStream = () => {
|
||||||
|
socket.emit("lastInput", inputData);
|
||||||
|
};
|
||||||
|
|
||||||
const inputData = {
|
socket.on("connect", startStream);
|
||||||
measurements,
|
|
||||||
duration,
|
|
||||||
interval: 1000,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
socket.on("lastOutput", (response) => {
|
||||||
|
const responseData = response.input1;
|
||||||
|
|
||||||
const startStream = () => {
|
if (typeof responseData === "number") {
|
||||||
socket.emit("lastInput", inputData);
|
setProgress(responseData);
|
||||||
};
|
|
||||||
|
|
||||||
socket.on("connect", startStream);
|
|
||||||
|
|
||||||
socket.on("lastOutput", (response) => {
|
|
||||||
const responseData = response.input1;
|
|
||||||
|
|
||||||
if (typeof responseData === "number") {
|
|
||||||
setProgress(responseData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
socket.off("lastOutput");
|
|
||||||
socket.emit("stop_stream"); // Stop streaming when component unmounts
|
|
||||||
socket.disconnect();
|
|
||||||
};
|
|
||||||
}, [measurements, duration, iotApiUrl]);
|
|
||||||
|
|
||||||
const fetchSavedInputes = async() => {
|
|
||||||
|
|
||||||
if (object?.id !== "") {
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`);
|
|
||||||
if (response.status === 200) {
|
|
||||||
setmeasurements(response.data.Data.measurements)
|
|
||||||
setDuration(response.data.Data.duration)
|
|
||||||
setName(response.data.header)
|
|
||||||
} else {
|
|
||||||
console.log("Unexpected response:", response);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("There was an error!", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
return () => {
|
||||||
fetchSavedInputes();
|
socket.off("lastOutput");
|
||||||
}, []);
|
socket.emit("stop_stream"); // Stop streaming when component unmounts
|
||||||
|
socket.disconnect();
|
||||||
|
};
|
||||||
|
}, [measurements, duration, iotApiUrl]);
|
||||||
|
|
||||||
useEffect(() => {
|
const fetchSavedInputes = async () => {
|
||||||
if (selectedChartId?.id === object?.id) {
|
if (object?.id !== "") {
|
||||||
fetchSavedInputes();
|
try {
|
||||||
|
const response = await axios.get(
|
||||||
|
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`
|
||||||
|
);
|
||||||
|
if (response.status === 200) {
|
||||||
|
setmeasurements(response.data.Data.measurements);
|
||||||
|
setDuration(response.data.Data.duration);
|
||||||
|
setName(response.data.header);
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
}
|
} catch (error) {}
|
||||||
,[header, flotingDuration, flotingMeasurements])
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
useEffect(() => {
|
||||||
<>
|
fetchSavedInputes();
|
||||||
<div className="header-wrapper" >
|
}, []);
|
||||||
<div className="header">{name}</div>
|
|
||||||
<div className="data-values">
|
|
||||||
<div className="value">{progress}</div>
|
|
||||||
<div className="per">{object.per}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="icon">
|
|
||||||
<WalletIcon />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TotalCardComponent
|
useEffect(() => {
|
||||||
|
if (selectedChartId?.id === object?.id) {
|
||||||
|
fetchSavedInputes();
|
||||||
|
}
|
||||||
|
}, [header, flotingDuration, flotingMeasurements]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="header-wrapper">
|
||||||
|
<div className="header">{name}</div>
|
||||||
|
<div className="data-values">
|
||||||
|
<div className="value">{progress}</div>
|
||||||
|
<div className="per">{object.per}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="icon">
|
||||||
|
<WalletIcon />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TotalCardComponent;
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default function NavMeshDetails({
|
||||||
|
|
||||||
const [positions, indices] = getPositionsAndIndices(meshes);
|
const [positions, indices] = getPositionsAndIndices(meshes);
|
||||||
|
|
||||||
const cellSize = 0.35;
|
const cellSize = 0.2;
|
||||||
const cellHeight = 0.7;
|
const cellHeight = 0.7;
|
||||||
const walkableRadius = 0.5;
|
const walkableRadius = 0.5;
|
||||||
const { success, navMesh } = generateSoloNavMesh(positions, indices, {
|
const { success, navMesh } = generateSoloNavMesh(positions, indices, {
|
||||||
|
|
|
@ -86,8 +86,8 @@ async function addAssetModel(
|
||||||
} else {
|
} else {
|
||||||
// console.log(`Added ${selectedItem.name} from Backend`);
|
// console.log(`Added ${selectedItem.name} from Backend`);
|
||||||
|
|
||||||
loader.load(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`, async (gltf) => {
|
loader.load(`${url_Backend_dwinzo}/api/v2/AssetFile/${selectedItem.id}`, async (gltf) => {
|
||||||
const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v1/AssetFile/${selectedItem.id}`).then((res) => res.blob());
|
const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v2/AssetFile/${selectedItem.id}`).then((res) => res.blob());
|
||||||
await storeGLTF(selectedItem.id, modelBlob);
|
await storeGLTF(selectedItem.id, modelBlob);
|
||||||
THREE.Cache.add(selectedItem.id, gltf);
|
THREE.Cache.add(selectedItem.id, gltf);
|
||||||
await handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, setSimulationStates, socket);
|
await handleModelLoad(gltf, intersectPoint!, selectedItem, itemsGroup, tempLoader, isTempLoader, setFloorItems, setSimulationStates, socket);
|
||||||
|
@ -235,6 +235,7 @@ async function handleModelLoad(
|
||||||
points: {
|
points: {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: res.points.position as [number, number, number],
|
position: res.points.position as [number, number, number],
|
||||||
|
rotation: res.points.rotation as [number, number, number],
|
||||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: '', start: {}, hitCount: 1, end: {}, buffer: 0 },
|
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', type: '', start: {}, hitCount: 1, end: {}, buffer: 0 },
|
||||||
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
||||||
speed: 2,
|
speed: 2,
|
||||||
|
@ -297,6 +298,7 @@ async function handleModelLoad(
|
||||||
points: {
|
points: {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: res.points.position as [number, number, number],
|
position: res.points.position as [number, number, number],
|
||||||
|
rotation: res.points.rotation as [number, number, number],
|
||||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', buffer: 0, material: 'Inherit' },
|
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', buffer: 0, material: 'Inherit' },
|
||||||
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||||
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
||||||
|
@ -360,6 +362,7 @@ async function handleModelLoad(
|
||||||
points: {
|
points: {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: res.points.position as [number, number, number],
|
position: res.points.position as [number, number, number],
|
||||||
|
rotation: res.points.rotation as [number, number, number],
|
||||||
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', speed: 1, processes: [] },
|
actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', speed: 1, processes: [] },
|
||||||
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||||
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
connections: { source: { modelUUID: model.uuid, pointUUID: pointUUID }, targets: [] },
|
||||||
|
|
|
@ -53,7 +53,7 @@ export default async function assetManager(
|
||||||
if (!activePromises.get(taskId)) return; // Stop processing if task is canceled
|
if (!activePromises.get(taskId)) return; // Stop processing if task is canceled
|
||||||
|
|
||||||
await new Promise<void>(async (resolve) => {
|
await new Promise<void>(async (resolve) => {
|
||||||
const modelUrl = `${url_Backend_dwinzo}/api/v1/AssetFile/${item.modelfileID!}`;
|
const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${item.modelfileID!}`;
|
||||||
|
|
||||||
// Check Three.js Cache
|
// Check Three.js Cache
|
||||||
const cachedModel = THREE.Cache.get(item.modelfileID!);
|
const cachedModel = THREE.Cache.get(item.modelfileID!);
|
||||||
|
|
|
@ -105,7 +105,7 @@ export default function SocketResponses({
|
||||||
// console.log(`Getting ${data.data.modelname} from cache`);
|
// console.log(`Getting ${data.data.modelname} from cache`);
|
||||||
const model = cachedModel.scene.clone();
|
const model = cachedModel.scene.clone();
|
||||||
model.uuid = data.data.modeluuid;
|
model.uuid = data.data.modeluuid;
|
||||||
model.userData = { name: data.data.modelname, modelId: data.data.modelFileID, modeluuid: data.data.modeluuid };
|
model.userData = { name: data.data.modelname, modelId: data.data.modelfileID, modeluuid: data.data.modeluuid };
|
||||||
model.position.set(...data.data.position as [number, number, number]);
|
model.position.set(...data.data.position as [number, number, number]);
|
||||||
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
||||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||||
|
@ -159,7 +159,7 @@ export default function SocketResponses({
|
||||||
url = URL.createObjectURL(indexedDBModel);
|
url = URL.createObjectURL(indexedDBModel);
|
||||||
} else {
|
} else {
|
||||||
// console.log(`Getting ${data.data.modelname} from Backend`);
|
// console.log(`Getting ${data.data.modelname} from Backend`);
|
||||||
url = `${url_Backend_dwinzo}/api/v1/AssetFile/${data.data.modelfileID}`;
|
url = `${url_Backend_dwinzo}/api/v2/AssetFile/${data.data.modelfileID}`;
|
||||||
const modelBlob = await fetch(url).then((res) => res.blob());
|
const modelBlob = await fetch(url).then((res) => res.blob());
|
||||||
await storeGLTF(data.data.modelfileID, modelBlob);
|
await storeGLTF(data.data.modelfileID, modelBlob);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ export default function SocketResponses({
|
||||||
THREE.Cache.remove(url);
|
THREE.Cache.remove(url);
|
||||||
const model = gltf.scene;
|
const model = gltf.scene;
|
||||||
model.uuid = data.data.modeluuid;
|
model.uuid = data.data.modeluuid;
|
||||||
model.userData = { name: data.data.modelname, modelId: data.data.modelFileID, modeluuid: data.data.modeluuid };
|
model.userData = { name: data.data.modelname, modelId: data.data.modelfileID, modeluuid: data.data.modeluuid };
|
||||||
model.position.set(...data.data.position as [number, number, number]);
|
model.position.set(...data.data.position as [number, number, number]);
|
||||||
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
model.rotation.set(data.data.rotation.x, data.data.rotation.y, data.data.rotation.z);
|
||||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { getFloorAssets } from '../../../services/factoryBuilder/assest/floorAss
|
||||||
async function loadInitialFloorItems(
|
async function loadInitialFloorItems(
|
||||||
itemsGroup: Types.RefGroup,
|
itemsGroup: Types.RefGroup,
|
||||||
setFloorItems: Types.setFloorItemSetState,
|
setFloorItems: Types.setFloorItemSetState,
|
||||||
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => void
|
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => void
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!itemsGroup.current) return;
|
if (!itemsGroup.current) return;
|
||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||||
|
@ -82,16 +82,14 @@ async function loadInitialFloorItems(
|
||||||
if (indexedDBModel) {
|
if (indexedDBModel) {
|
||||||
// console.log(`[IndexedDB] Fetching ${item.modelname}`);
|
// console.log(`[IndexedDB] Fetching ${item.modelname}`);
|
||||||
const blobUrl = URL.createObjectURL(indexedDBModel);
|
const blobUrl = URL.createObjectURL(indexedDBModel);
|
||||||
loader.load(
|
loader.load(blobUrl, (gltf) => {
|
||||||
blobUrl,
|
URL.revokeObjectURL(blobUrl);
|
||||||
(gltf) => {
|
THREE.Cache.remove(blobUrl);
|
||||||
URL.revokeObjectURL(blobUrl);
|
THREE.Cache.add(item.modelfileID!, gltf);
|
||||||
THREE.Cache.remove(blobUrl);
|
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, setSimulationStates);
|
||||||
THREE.Cache.add(item.modelfileID!, gltf);
|
modelsLoaded++;
|
||||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, setSimulationStates);
|
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||||
modelsLoaded++;
|
},
|
||||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
|
||||||
},
|
|
||||||
undefined,
|
undefined,
|
||||||
(error) => {
|
(error) => {
|
||||||
toast.error(`[IndexedDB] Error loading ${item.modelname}:`);
|
toast.error(`[IndexedDB] Error loading ${item.modelname}:`);
|
||||||
|
@ -104,17 +102,15 @@ async function loadInitialFloorItems(
|
||||||
|
|
||||||
// Fetch from Backend
|
// Fetch from Backend
|
||||||
// console.log(`[Backend] Fetching ${item.modelname}`);
|
// console.log(`[Backend] Fetching ${item.modelname}`);
|
||||||
const modelUrl = `${url_Backend_dwinzo}/api/v1/AssetFile/${item.modelfileID!}`;
|
const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${item.modelfileID!}`;
|
||||||
loader.load(
|
loader.load(modelUrl, async (gltf) => {
|
||||||
modelUrl,
|
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
||||||
async (gltf) => {
|
await storeGLTF(item.modelfileID!, modelBlob);
|
||||||
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
THREE.Cache.add(item.modelfileID!, gltf);
|
||||||
await storeGLTF(item.modelfileID!, modelBlob);
|
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, setSimulationStates);
|
||||||
THREE.Cache.add(item.modelfileID!, gltf);
|
modelsLoaded++;
|
||||||
processLoadedModel(gltf.scene.clone(), item, itemsGroup, setFloorItems, setSimulationStates);
|
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
||||||
modelsLoaded++;
|
},
|
||||||
checkLoadingCompletion(modelsLoaded, modelsToLoad, dracoLoader, resolve);
|
|
||||||
},
|
|
||||||
undefined,
|
undefined,
|
||||||
(error) => {
|
(error) => {
|
||||||
toast.error(`[Backend] Error loading ${item.modelname}:`);
|
toast.error(`[Backend] Error loading ${item.modelname}:`);
|
||||||
|
@ -137,7 +133,7 @@ async function loadInitialFloorItems(
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (item.eventData || item.modelfileID === '67e3db95c2e8f37134526fb2') {
|
if (item.eventData) {
|
||||||
processEventData(item, setSimulationStates);
|
processEventData(item, setSimulationStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +153,7 @@ function processLoadedModel(
|
||||||
item: Types.EventData,
|
item: Types.EventData,
|
||||||
itemsGroup: Types.RefGroup,
|
itemsGroup: Types.RefGroup,
|
||||||
setFloorItems: Types.setFloorItemSetState,
|
setFloorItems: Types.setFloorItemSetState,
|
||||||
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => void
|
setSimulationStates: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => void
|
||||||
) {
|
) {
|
||||||
const model = gltf;
|
const model = gltf;
|
||||||
model.uuid = item.modeluuid;
|
model.uuid = item.modeluuid;
|
||||||
|
@ -192,7 +188,7 @@ function processLoadedModel(
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (item.eventData || item.modelfileID === '67e3db5ac2e8f37134526f40') {
|
if (item.eventData) {
|
||||||
processEventData(item, setSimulationStates);
|
processEventData(item, setSimulationStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +217,7 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
|
||||||
data.modeluuid = item.modeluuid;
|
data.modeluuid = item.modeluuid;
|
||||||
data.modelName = item.modelname;
|
data.modelName = item.modelname;
|
||||||
data.position = item.position;
|
data.position = item.position;
|
||||||
|
data.rotation = [item.rotation.x, item.rotation.y, item.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
|
|
|
@ -263,6 +263,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
return {
|
return {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: vehiclePoint?.position,
|
position: vehiclePoint?.position,
|
||||||
|
rotation: vehiclePoint?.rotation,
|
||||||
actions: hasActions
|
actions: hasActions
|
||||||
? {
|
? {
|
||||||
...vehiclePoint.actions,
|
...vehiclePoint.actions,
|
||||||
|
@ -315,6 +316,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
newEventData.modeluuid = newFloorItem.modeluuid;
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
|
@ -339,12 +341,14 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
return {
|
return {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: vehiclePoint?.position,
|
position: vehiclePoint?.position,
|
||||||
|
rotation: vehiclePoint?.rotation,
|
||||||
actions: hasActions
|
actions: hasActions
|
||||||
? {
|
? {
|
||||||
...vehiclePoint.actions,
|
...vehiclePoint.actions,
|
||||||
uuid: THREE.MathUtils.generateUUID()
|
uuid: THREE.MathUtils.generateUUID()
|
||||||
}
|
}
|
||||||
: defaultAction,
|
: defaultAction,
|
||||||
|
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||||
connections: {
|
connections: {
|
||||||
source: { modelUUID: obj.uuid, pointUUID },
|
source: { modelUUID: obj.uuid, pointUUID },
|
||||||
targets: []
|
targets: []
|
||||||
|
@ -415,6 +419,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
||||||
return {
|
return {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: vehiclePoint?.position,
|
position: vehiclePoint?.position,
|
||||||
|
rotation: vehiclePoint?.rotation,
|
||||||
actions: hasActions
|
actions: hasActions
|
||||||
? {
|
? {
|
||||||
...vehiclePoint.actions,
|
...vehiclePoint.actions,
|
||||||
|
|
|
@ -245,6 +245,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
return {
|
return {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: vehiclePoint?.position,
|
position: vehiclePoint?.position,
|
||||||
|
rotation: vehiclePoint?.rotation,
|
||||||
actions: hasActions
|
actions: hasActions
|
||||||
? {
|
? {
|
||||||
...vehiclePoint.actions,
|
...vehiclePoint.actions,
|
||||||
|
@ -297,6 +298,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
newEventData.modeluuid = newFloorItem.modeluuid;
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
|
||||||
...(prevEvents || []),
|
...(prevEvents || []),
|
||||||
|
@ -321,12 +323,14 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
return {
|
return {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: vehiclePoint?.position,
|
position: vehiclePoint?.position,
|
||||||
|
rotation: vehiclePoint?.rotation,
|
||||||
actions: hasActions
|
actions: hasActions
|
||||||
? {
|
? {
|
||||||
...vehiclePoint.actions,
|
...vehiclePoint.actions,
|
||||||
uuid: THREE.MathUtils.generateUUID()
|
uuid: THREE.MathUtils.generateUUID()
|
||||||
}
|
}
|
||||||
: defaultAction,
|
: defaultAction,
|
||||||
|
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
|
||||||
connections: {
|
connections: {
|
||||||
source: { modelUUID: obj.uuid, pointUUID },
|
source: { modelUUID: obj.uuid, pointUUID },
|
||||||
targets: []
|
targets: []
|
||||||
|
@ -397,6 +401,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
||||||
return {
|
return {
|
||||||
uuid: pointUUID,
|
uuid: pointUUID,
|
||||||
position: vehiclePoint?.position,
|
position: vehiclePoint?.position,
|
||||||
|
rotation: vehiclePoint?.rotation,
|
||||||
actions: hasActions
|
actions: hasActions
|
||||||
? {
|
? {
|
||||||
...vehiclePoint.actions,
|
...vehiclePoint.actions,
|
||||||
|
|
|
@ -279,6 +279,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
newEventData.modeluuid = newFloorItem.modeluuid;
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
const updatedEvents = (prevEvents || []).map(event =>
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
|
|
@ -284,6 +284,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
newEventData.modeluuid = newFloorItem.modeluuid;
|
newEventData.modeluuid = newFloorItem.modeluuid;
|
||||||
newEventData.modelName = newFloorItem.modelname;
|
newEventData.modelName = newFloorItem.modelname;
|
||||||
newEventData.position = newFloorItem.position;
|
newEventData.position = newFloorItem.position;
|
||||||
|
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
|
||||||
|
|
||||||
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
|
||||||
const updatedEvents = (prevEvents || []).map(event =>
|
const updatedEvents = (prevEvents || []).map(event =>
|
||||||
|
|
|
@ -122,10 +122,15 @@ const SelectionControls: React.FC = () => {
|
||||||
|
|
||||||
if (!toggleView && activeModule === "builder") {
|
if (!toggleView && activeModule === "builder") {
|
||||||
helper.enabled = true;
|
helper.enabled = true;
|
||||||
canvasElement.addEventListener("pointerdown", onPointerDown);
|
if (duplicatedObjects.length === 0 && pastedObjects.length === 0) {
|
||||||
canvasElement.addEventListener("pointermove", onPointerMove);
|
canvasElement.addEventListener("pointerdown", onPointerDown);
|
||||||
|
canvasElement.addEventListener("pointermove", onPointerMove);
|
||||||
|
canvasElement.addEventListener("pointerup", onPointerUp);
|
||||||
|
} else {
|
||||||
|
helper.enabled = false;
|
||||||
|
helper.dispose();
|
||||||
|
}
|
||||||
canvasElement.addEventListener("contextmenu", onContextMenu);
|
canvasElement.addEventListener("contextmenu", onContextMenu);
|
||||||
canvasElement.addEventListener("pointerup", onPointerUp);
|
|
||||||
canvasElement.addEventListener("keydown", onKeyDown);
|
canvasElement.addEventListener("keydown", onKeyDown);
|
||||||
} else {
|
} else {
|
||||||
helper.enabled = false;
|
helper.enabled = false;
|
||||||
|
|
|
@ -952,8 +952,17 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// Ensure all required ArmBot point properties are included
|
actions: {
|
||||||
actions: state.points.actions,
|
...state.points.actions,
|
||||||
|
processes: state.points.actions.processes?.filter(process => {
|
||||||
|
return !(
|
||||||
|
process.startPoint === connection1.point ||
|
||||||
|
process.endPoint === connection1.point ||
|
||||||
|
process.startPoint === connection2.point ||
|
||||||
|
process.endPoint === connection2.point
|
||||||
|
);
|
||||||
|
}) || []
|
||||||
|
},
|
||||||
triggers: state.points.triggers
|
triggers: state.points.triggers
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,17 +2,30 @@ import html2canvas from "html2canvas";
|
||||||
|
|
||||||
export const captureVisualization = async (): Promise<string | null> => {
|
export const captureVisualization = async (): Promise<string | null> => {
|
||||||
const container = document.getElementById("real-time-vis-canvas");
|
const container = document.getElementById("real-time-vis-canvas");
|
||||||
if (!container) return null;
|
if (!container) {
|
||||||
|
console.error("Container element not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Use html2canvas to capture the container
|
// Hide any elements you don't want in the screenshot
|
||||||
|
const originalVisibility = container.style.visibility;
|
||||||
|
container.style.visibility = 'visible';
|
||||||
|
|
||||||
const canvas = await html2canvas(container, {
|
const canvas = await html2canvas(container, {
|
||||||
scale: 1, // Adjust scale for higher/lower resolution
|
scale: 2, // Higher scale for better quality
|
||||||
|
logging: false, // Disable console logging
|
||||||
|
useCORS: true, // Handle cross-origin images
|
||||||
|
allowTaint: true, // Allow tainted canvas
|
||||||
|
backgroundColor: '#ffffff', // Set white background
|
||||||
|
removeContainer: true // Clean up temporary containers
|
||||||
});
|
});
|
||||||
|
|
||||||
// Convert the canvas to a data URL (PNG format)
|
// Restore original visibility
|
||||||
const dataUrl = canvas.toDataURL("image/png");
|
container.style.visibility = originalVisibility;
|
||||||
return dataUrl;
|
|
||||||
|
// Convert to PNG with highest quality
|
||||||
|
return canvas.toDataURL('image/png', 1.0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error capturing visualization:", error);
|
console.error("Error capturing visualization:", error);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { saveTemplateApi } from "../../services/realTimeVisulization/zoneData/saveTempleteApi";
|
|
||||||
import { useSocketStore } from "../../store/store";
|
|
||||||
import { Template } from "../../store/useTemplateStore";
|
import { Template } from "../../store/useTemplateStore";
|
||||||
import { captureVisualization } from "./captureVisualization";
|
import { captureVisualization } from "./captureVisualization";
|
||||||
|
|
||||||
|
@ -28,6 +26,7 @@ export const handleSaveTemplate = async ({
|
||||||
templates = [],
|
templates = [],
|
||||||
visualizationSocket,
|
visualizationSocket,
|
||||||
}: HandleSaveTemplateProps): Promise<void> => {
|
}: HandleSaveTemplateProps): Promise<void> => {
|
||||||
|
console.log("floatingWidget: ", floatingWidget);
|
||||||
try {
|
try {
|
||||||
// Check if the selected zone has any widgets
|
// Check if the selected zone has any widgets
|
||||||
if (!selectedZone.panelOrder || selectedZone.panelOrder.length === 0) {
|
if (!selectedZone.panelOrder || selectedZone.panelOrder.length === 0) {
|
||||||
|
@ -50,9 +49,10 @@ export const handleSaveTemplate = async ({
|
||||||
// Capture visualization snapshot
|
// Capture visualization snapshot
|
||||||
const snapshot = await captureVisualization();
|
const snapshot = await captureVisualization();
|
||||||
|
|
||||||
// if (!snapshot) {
|
if (!snapshot) {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Create a new template
|
// Create a new template
|
||||||
const newTemplate: Template = {
|
const newTemplate: Template = {
|
||||||
id: generateUniqueId(),
|
id: generateUniqueId(),
|
||||||
|
|
|
@ -15,22 +15,19 @@ type WidgetData = {
|
||||||
|
|
||||||
export default function SocketRealTimeViz() {
|
export default function SocketRealTimeViz() {
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { setSelectedZone } = useSelectedZoneStore();
|
||||||
const deleteObject = useDroppedObjectsStore((state) => state.deleteObject);
|
const deleteObject = useDroppedObjectsStore((state) => state.deleteObject);
|
||||||
const duplicateObject = useDroppedObjectsStore((state) => state.duplicateObject);
|
|
||||||
const updateObjectPosition = useDroppedObjectsStore((state) => state.updateObjectPosition);
|
const updateObjectPosition = useDroppedObjectsStore((state) => state.updateObjectPosition);
|
||||||
const { addWidget } = useZoneWidgetStore()
|
const { addWidget } = useZoneWidgetStore()
|
||||||
const { templates, removeTemplate } = useTemplateStore();
|
const { removeTemplate } = useTemplateStore();
|
||||||
const { setTemplates } = useTemplateStore();
|
const { setTemplates } = useTemplateStore();
|
||||||
const { zoneWidgetData, setZoneWidgetData, updateWidgetPosition, updateWidgetRotation } = useZoneWidgetStore();
|
const { zoneWidgetData, setZoneWidgetData, updateWidgetPosition, updateWidgetRotation } = useZoneWidgetStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const email = localStorage.getItem("email") || "";
|
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
//add panel response
|
//add panel response
|
||||||
visualizationSocket.on("viz-panel:response:updates", (addPanel: any) => {
|
visualizationSocket.on("viz-panel:response:updates", (addPanel: any) => {
|
||||||
console.log('addPanel: ', addPanel);
|
|
||||||
if (addPanel.success) {
|
if (addPanel.success) {
|
||||||
let addPanelData = addPanel.data.data
|
let addPanelData = addPanel.data.data
|
||||||
setSelectedZone(addPanelData)
|
setSelectedZone(addPanelData)
|
||||||
|
@ -38,15 +35,33 @@ export default function SocketRealTimeViz() {
|
||||||
})
|
})
|
||||||
//delete panel response
|
//delete panel response
|
||||||
visualizationSocket.on("viz-panel:response:delete", (deletePanel: any) => {
|
visualizationSocket.on("viz-panel:response:delete", (deletePanel: any) => {
|
||||||
console.log('deletePanel: ', deletePanel);
|
|
||||||
if (deletePanel.success) {
|
if (deletePanel.success) {
|
||||||
let deletePanelData = deletePanel.data.data
|
let deletePanelData = deletePanel.data.data
|
||||||
setSelectedZone(deletePanelData)
|
setSelectedZone(deletePanelData)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
//clear Panel response
|
||||||
|
visualizationSocket.on("viz-panel:response:clear", (clearPanel: any) => {
|
||||||
|
|
||||||
|
if (clearPanel.success && clearPanel.message === "PanelWidgets cleared successfully") {
|
||||||
|
|
||||||
|
let clearPanelData = clearPanel.data.data
|
||||||
|
setSelectedZone(clearPanelData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//lock Panel response
|
||||||
|
visualizationSocket.on("viz-panel:response:locked", (lockPanel: any) => {
|
||||||
|
|
||||||
|
if (lockPanel.success && lockPanel.message === "locked panel updated successfully") {
|
||||||
|
|
||||||
|
let lockPanelData = lockPanel.data.data
|
||||||
|
setSelectedZone(lockPanelData)
|
||||||
|
}
|
||||||
|
})
|
||||||
// add 2dWidget response
|
// add 2dWidget response
|
||||||
visualizationSocket.on("viz-widget:response:updates", (add2dWidget: any) => {
|
visualizationSocket.on("viz-widget:response:updates", (add2dWidget: any) => {
|
||||||
console.log('add2dWidget: ', add2dWidget);
|
|
||||||
|
|
||||||
if (add2dWidget.success && add2dWidget.data) {
|
if (add2dWidget.success && add2dWidget.data) {
|
||||||
setSelectedZone((prev) => {
|
setSelectedZone((prev) => {
|
||||||
|
@ -65,7 +80,7 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//delete 2D Widget response
|
//delete 2D Widget response
|
||||||
visualizationSocket.on("viz-widget:response:delete", (deleteWidget: any) => {
|
visualizationSocket.on("viz-widget:response:delete", (deleteWidget: any) => {
|
||||||
console.log('deleteWidget: ', deleteWidget);
|
|
||||||
|
|
||||||
if (deleteWidget?.success && deleteWidget.data) {
|
if (deleteWidget?.success && deleteWidget.data) {
|
||||||
setSelectedZone((prevZone: any) => ({
|
setSelectedZone((prevZone: any) => ({
|
||||||
|
@ -78,7 +93,7 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//add Floating Widget response
|
//add Floating Widget response
|
||||||
visualizationSocket.on("viz-float:response:updates", (addFloatingWidget: any) => {
|
visualizationSocket.on("viz-float:response:updates", (addFloatingWidget: any) => {
|
||||||
console.log('addFloatingWidget: ', addFloatingWidget);
|
|
||||||
|
|
||||||
if (addFloatingWidget.success) {
|
if (addFloatingWidget.success) {
|
||||||
if (addFloatingWidget.success && addFloatingWidget.message === "FloatWidget created successfully") {
|
if (addFloatingWidget.success && addFloatingWidget.message === "FloatWidget created successfully") {
|
||||||
|
@ -105,7 +120,7 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//duplicate Floating Widget response
|
//duplicate Floating Widget response
|
||||||
visualizationSocket.on("viz-float:response:addDuplicate", (duplicateFloatingWidget: any) => {
|
visualizationSocket.on("viz-float:response:addDuplicate", (duplicateFloatingWidget: any) => {
|
||||||
console.log('duplicateFloatingWidget: ', duplicateFloatingWidget);
|
|
||||||
|
|
||||||
if (duplicateFloatingWidget.success && duplicateFloatingWidget.message === "duplicate FloatWidget created successfully") {
|
if (duplicateFloatingWidget.success && duplicateFloatingWidget.message === "duplicate FloatWidget created successfully") {
|
||||||
useDroppedObjectsStore.setState((state) => {
|
useDroppedObjectsStore.setState((state) => {
|
||||||
|
@ -133,7 +148,7 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//delete Floating Widget response
|
//delete Floating Widget response
|
||||||
visualizationSocket.on("viz-float:response:delete", (deleteFloatingWidget: any) => {
|
visualizationSocket.on("viz-float:response:delete", (deleteFloatingWidget: any) => {
|
||||||
console.log('deleteFloatingWidget: ', deleteFloatingWidget);
|
|
||||||
|
|
||||||
if (deleteFloatingWidget.success) {
|
if (deleteFloatingWidget.success) {
|
||||||
deleteObject(deleteFloatingWidget.data.zoneName, deleteFloatingWidget.data.floatWidgetID);
|
deleteObject(deleteFloatingWidget.data.zoneName, deleteFloatingWidget.data.floatWidgetID);
|
||||||
|
@ -142,9 +157,9 @@ export default function SocketRealTimeViz() {
|
||||||
//add 3D Widget response
|
//add 3D Widget response
|
||||||
visualizationSocket.on("viz-widget3D:response:updates", (add3DWidget: any) => {
|
visualizationSocket.on("viz-widget3D:response:updates", (add3DWidget: any) => {
|
||||||
|
|
||||||
console.log('add3DWidget: ', add3DWidget);
|
|
||||||
if (add3DWidget.success) {
|
if (add3DWidget.success) {
|
||||||
console.log('add3DWidget: ', add3DWidget);
|
|
||||||
if (add3DWidget.message === "Widget created successfully") {
|
if (add3DWidget.message === "Widget created successfully") {
|
||||||
addWidget(add3DWidget.data.zoneId, add3DWidget.data.widget);
|
addWidget(add3DWidget.data.zoneId, add3DWidget.data.widget);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +167,7 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//delete 3D Widget response
|
//delete 3D Widget response
|
||||||
visualizationSocket.on("viz-widget3D:response:delete", (delete3DWidget: any) => {
|
visualizationSocket.on("viz-widget3D:response:delete", (delete3DWidget: any) => {
|
||||||
console.log('delete3DWidget: ', delete3DWidget);
|
|
||||||
// "3DWidget delete unsuccessfull"
|
// "3DWidget delete unsuccessfull"
|
||||||
if (delete3DWidget.success && delete3DWidget.message === "3DWidget delete successfull") {
|
if (delete3DWidget.success && delete3DWidget.message === "3DWidget delete successfull") {
|
||||||
const activeZoneWidgets = zoneWidgetData[delete3DWidget.data.zoneId] || [];
|
const activeZoneWidgets = zoneWidgetData[delete3DWidget.data.zoneId] || [];
|
||||||
|
@ -164,16 +179,16 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//update3D widget response
|
//update3D widget response
|
||||||
visualizationSocket.on("viz-widget3D:response:modifyPositionRotation", (update3DWidget: any) => {
|
visualizationSocket.on("viz-widget3D:response:modifyPositionRotation", (update3DWidget: any) => {
|
||||||
console.log('update3DWidget: ', update3DWidget);
|
|
||||||
|
|
||||||
if (update3DWidget.success && update3DWidget.message==="widget update successfully") {
|
|
||||||
|
if (update3DWidget.success && update3DWidget.message === "widget update successfully") {
|
||||||
updateWidgetPosition(update3DWidget.data.zoneId, update3DWidget.data.widget.id, update3DWidget.data.widget.position);
|
updateWidgetPosition(update3DWidget.data.zoneId, update3DWidget.data.widget.id, update3DWidget.data.widget.position);
|
||||||
updateWidgetRotation(update3DWidget.data.zoneId, update3DWidget.data.widget.id, update3DWidget.data.widget.rotation);
|
updateWidgetRotation(update3DWidget.data.zoneId, update3DWidget.data.widget.id, update3DWidget.data.widget.rotation);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// add Template response
|
// add Template response
|
||||||
visualizationSocket.on("viz-template:response:add", (addingTemplate: any) => {
|
visualizationSocket.on("viz-template:response:add", (addingTemplate: any) => {
|
||||||
console.log('addingTemplate: ', addingTemplate);
|
|
||||||
|
|
||||||
if (addingTemplate.success) {
|
if (addingTemplate.success) {
|
||||||
if (addingTemplate.message === "Template saved successfully") {
|
if (addingTemplate.message === "Template saved successfully") {
|
||||||
|
@ -183,7 +198,7 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//load Template response
|
//load Template response
|
||||||
visualizationSocket.on("viz-template:response:addTemplateZone", (loadTemplate: any) => {
|
visualizationSocket.on("viz-template:response:addTemplateZone", (loadTemplate: any) => {
|
||||||
console.log('loadTemplate: ', loadTemplate);
|
|
||||||
|
|
||||||
if (loadTemplate.success) {
|
if (loadTemplate.success) {
|
||||||
if (loadTemplate.message === "Template placed in Zone") {
|
if (loadTemplate.message === "Template placed in Zone") {
|
||||||
|
@ -206,14 +221,12 @@ export default function SocketRealTimeViz() {
|
||||||
});
|
});
|
||||||
//delete Template response
|
//delete Template response
|
||||||
visualizationSocket.on("viz-template:response:delete", (deleteTemplate: any) => {
|
visualizationSocket.on("viz-template:response:delete", (deleteTemplate: any) => {
|
||||||
console.log('deleteTemplate: ', deleteTemplate);
|
|
||||||
|
|
||||||
if (deleteTemplate.success) {
|
if (deleteTemplate.success) {
|
||||||
if (deleteTemplate.message === 'Template deleted successfully') {
|
if (deleteTemplate.message === 'Template deleted successfully') {
|
||||||
removeTemplate(deleteTemplate.data);
|
removeTemplate(deleteTemplate.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}
|
||||||
|
|
||||||
export const getAssetModel = async (modelId: string) => {
|
export const getAssetModel = async (modelId: string) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${url_Backend_dwinzo}/api/v1/AssetFile/${modelId}`, {
|
const response = await fetch(`${url_Backend_dwinzo}/api/v2/AssetFile/${modelId}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
|
||||||
|
|
||||||
export const getFloorAssets = async (organization: string) => {
|
export const getFloorAssets = async (organization: string) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${url_Backend_dwinzo}/api/v2/floorAssets/${organization}`, {
|
const response = await fetch(`${url_Backend_dwinzo}/api/v2/floorAssets/${organization}`, {
|
||||||
|
@ -14,6 +15,7 @@ export const getFloorAssets = async (organization: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
|
||||||
export const setFloorItemApi = async (
|
export const setFloorItemApi = async (
|
||||||
organization: string,
|
organization: string,
|
||||||
modeluuid: string,
|
modeluuid?: string,
|
||||||
modelname: string,
|
modelname?: string,
|
||||||
modelfileID: string,
|
modelfileID?: string,
|
||||||
position: Object,
|
position?: Object,
|
||||||
rotation: Object,
|
rotation?: Object,
|
||||||
isLocked: boolean,
|
isLocked?: boolean,
|
||||||
isVisible: boolean,
|
isVisible?: boolean,
|
||||||
eventData?: any
|
eventData?: any
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -26,7 +26,7 @@ onmessage = async (event) => {
|
||||||
const message = "gltfLoaded";
|
const message = "gltfLoaded";
|
||||||
postMessage({ message, modelID, modelBlob });
|
postMessage({ message, modelID, modelBlob });
|
||||||
} else {
|
} else {
|
||||||
const modelUrl = `${url_Backend_dwinzo}/api/v1/AssetFile/${modelID}`;
|
const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${modelID}`;
|
||||||
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
|
||||||
await storeGLTF(modelID, modelBlob);
|
await storeGLTF(modelID, modelBlob);
|
||||||
const message = "gltfLoaded";
|
const message = "gltfLoaded";
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||||
|
|
||||||
export const getZonesApi = async (organization: string) => {
|
export const getZonesApi = async (organization: string) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
// let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||||
|
export const clearPanel = async (
|
||||||
|
zoneId: string,
|
||||||
|
organization: string,
|
||||||
|
panelName: string
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${url_Backend_dwinzo}/api/v2/clearpanel`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ organization, zoneId, panelName }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Failed to clearPanel in the zone");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
} else {
|
||||||
|
throw new Error("An unknown error occurred");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||||
|
export const lockPanel = async (
|
||||||
|
zoneId: string,
|
||||||
|
organization: string,
|
||||||
|
lockedPanel: any
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${url_Backend_dwinzo}/api/v2/zones/lockedPanels`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ organization, zoneId, lockedPanel }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Failed to Lock Panel in the zone");
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
throw new Error(error.message);
|
||||||
|
} else {
|
||||||
|
throw new Error("An unknown error occurred");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -9,20 +9,16 @@ export const update3dWidget = async (
|
||||||
console.log("organization: ", organization);
|
console.log("organization: ", organization);
|
||||||
console.log("zoneId: ", zoneId);
|
console.log("zoneId: ", zoneId);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(`${url_Backend_dwinzo}/api/v2/modifyPR/widget3D`, {
|
||||||
`${url_Backend_dwinzo}/api/v2/modifyPR/widget3D`,
|
method: "PATCH",
|
||||||
{
|
headers: { "Content-Type": "application/json", },
|
||||||
method: "PATCH",
|
body: JSON.stringify({
|
||||||
headers: {
|
organization,
|
||||||
"Content-Type": "application/json",
|
zoneId,
|
||||||
},
|
id,
|
||||||
body: JSON.stringify({
|
position,
|
||||||
organization,
|
}),
|
||||||
zoneId,
|
}
|
||||||
id,
|
|
||||||
position,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
|
|
@ -68,7 +68,11 @@ export const useWalls = create<any>((set: any) => ({
|
||||||
|
|
||||||
export const useZones = create<any>((set: any) => ({
|
export const useZones = create<any>((set: any) => ({
|
||||||
zones: [],
|
zones: [],
|
||||||
setZones: (x: any) => set(() => ({ zones: x })),
|
setZones: (callback: any) =>
|
||||||
|
set((state: any) => ({
|
||||||
|
zones:
|
||||||
|
typeof callback === 'function' ? callback(state.zones) : callback
|
||||||
|
}))
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface ZonePointsState {
|
interface ZonePointsState {
|
||||||
|
|
|
@ -45,6 +45,7 @@ input {
|
||||||
.toggle-header-container {
|
.toggle-header-container {
|
||||||
@include flex-center;
|
@include flex-center;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
|
margin: 6px 0;
|
||||||
|
|
||||||
.toggle-header-item {
|
.toggle-header-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -553,6 +554,7 @@ input {
|
||||||
.input-value {
|
.input-value {
|
||||||
width: 42px;
|
width: 42px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
&::-webkit-inner-spin-button,
|
&::-webkit-inner-spin-button,
|
||||||
&::-webkit-outer-spin-button {
|
&::-webkit-outer-spin-button {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
|
|
@ -66,9 +66,9 @@
|
||||||
.sidebar-left-content-container {
|
.sidebar-left-content-container {
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
// flex: 1;
|
// flex: 1;
|
||||||
height: calc(100% - 36px);
|
// height: calc(100% - 36px);
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto;
|
// overflow: auto;
|
||||||
|
|
||||||
.template-list {
|
.template-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -132,8 +132,12 @@
|
||||||
|
|
||||||
|
|
||||||
.widget-left-sideBar {
|
.widget-left-sideBar {
|
||||||
min-height: 50vh;
|
.widgets-wrapper {
|
||||||
max-height: 60vh;
|
|
||||||
|
min-height: 50vh;
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.widget2D {
|
.widget2D {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
|
@ -365,7 +365,7 @@
|
||||||
|
|
||||||
.panel.hidePanel {
|
.panel.hidePanel {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0.1;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,11 +310,13 @@ interface VehicleEventsSchema {
|
||||||
points: {
|
points: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
actions: { uuid: string; name: string; type: string; start: { x: number, y: number } | {}, hitCount: number, end: { x: number, y: number } | {}, buffer: number };
|
actions: { uuid: string; name: string; type: string; start: { x: number, y: number } | {}, hitCount: number, end: { x: number, y: number } | {}, buffer: number };
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
speed: number;
|
speed: number;
|
||||||
};
|
};
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StaticMachineEventsSchema {
|
interface StaticMachineEventsSchema {
|
||||||
|
@ -324,6 +326,7 @@ interface StaticMachineEventsSchema {
|
||||||
points: {
|
points: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||||
triggers: { uuid: string; name: string; type: string };
|
triggers: { uuid: string; name: string; type: string };
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
|
@ -339,6 +342,7 @@ interface ArmBotEventsSchema {
|
||||||
points: {
|
points: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[] };
|
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[] };
|
||||||
triggers: { uuid: string; name: string; type: string };
|
triggers: { uuid: string; name: string; type: string };
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
|
@ -371,6 +375,7 @@ export type EventData = {
|
||||||
points: {
|
points: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
actions: { uuid: string; name: string; type: string; start: { x: number, y: number } | {}, hitCount: number, end: { x: number, y: number } | {}, buffer: number };
|
actions: { uuid: string; name: string; type: string; start: { x: number, y: number } | {}, hitCount: number, end: { x: number, y: number } | {}, buffer: number };
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
speed: number;
|
speed: number;
|
||||||
|
@ -380,6 +385,7 @@ export type EventData = {
|
||||||
points: {
|
points: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
actions: { uuid: string; name: string; buffer: number; material: string; };
|
actions: { uuid: string; name: string; buffer: number; material: string; };
|
||||||
triggers: { uuid: string; name: string; type: string };
|
triggers: { uuid: string; name: string; type: string };
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
|
@ -389,6 +395,7 @@ export type EventData = {
|
||||||
points: {
|
points: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
|
rotation: [number, number, number];
|
||||||
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[] };
|
actions: { uuid: string; name: string; speed: number; processes: { triggerId: string; startPoint: string; endPoint: string }[] };
|
||||||
triggers: { uuid: string; name: string; type: string };
|
triggers: { uuid: string; name: string; type: string };
|
||||||
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
|
||||||
|
|
|
@ -55,9 +55,21 @@ const KeyPressListener: React.FC = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Function to handle keydown events
|
// Function to handle keydown events
|
||||||
const handleKeyPress = (event: KeyboardEvent) => {
|
const handleKeyPress = (event: KeyboardEvent) => {
|
||||||
// Allow default behavior for F5 and F12
|
|
||||||
|
const activeElement = document.activeElement;
|
||||||
|
|
||||||
|
const isTyping =
|
||||||
|
activeElement instanceof HTMLInputElement ||
|
||||||
|
activeElement instanceof HTMLTextAreaElement ||
|
||||||
|
(activeElement && activeElement.getAttribute('contenteditable') === 'true');
|
||||||
|
|
||||||
|
if (isTyping) {
|
||||||
|
return; // Don't trigger shortcuts while typing
|
||||||
|
}
|
||||||
|
|
||||||
const keyCombination = detectModifierKeys(event);
|
const keyCombination = detectModifierKeys(event);
|
||||||
|
|
||||||
|
// Allow default behavior for F5 and F12
|
||||||
if (["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") {
|
if (["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -148,11 +160,10 @@ const KeyPressListener: React.FC = () => {
|
||||||
setActiveTool("draw-floor");
|
setActiveTool("draw-floor");
|
||||||
setToolMode("Floor");
|
setToolMode("Floor");
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (keyCombination === "M") {
|
if (keyCombination === "M") {
|
||||||
setActiveTool("measure");
|
setActiveTool("measure");
|
||||||
setToolMode("MeasurementScale");
|
setToolMode("MeasurementScale");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue