Merge pull request 'simulation' (#53) from simulation into main
Reviewed-on: http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev/pulls/53
This commit is contained in:
commit
8cb7b5186b
|
@ -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);
|
||||||
|
@ -219,8 +220,8 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({
|
||||||
// e.stopPropagation();
|
// e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
wrapperClass="pointer-none"
|
wrapperClass="pointer-none"
|
||||||
className={`${selectedChartId?.id === id ? "activeChart" : ""}`}
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`productionCapacity-wrapper card ${selectedChartId?.id === id ? "activeChart" : ""}`}
|
className={`productionCapacity-wrapper card ${selectedChartId?.id === id ? "activeChart" : ""}`}
|
||||||
onClick={() => setSelectedChartId({ id: id, type: type })}
|
onClick={() => setSelectedChartId({ id: id, type: type })}
|
||||||
|
|
|
@ -46,20 +46,32 @@ interface ReturnOfInvestmentProps {
|
||||||
rotation: [number, number, number];
|
rotation: [number, number, number];
|
||||||
onContextMenu?: (event: React.MouseEvent) => void;
|
onContextMenu?: (event: React.MouseEvent) => void;
|
||||||
}
|
}
|
||||||
const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, position, rotation, onContextMenu }) => {
|
const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
position,
|
||||||
|
rotation,
|
||||||
|
onContextMenu,
|
||||||
|
}) => {
|
||||||
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
||||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
const {
|
||||||
|
measurements: chartMeasurements,
|
||||||
|
duration: chartDuration,
|
||||||
|
name: widgetName,
|
||||||
|
} = useChartStore();
|
||||||
const [measurements, setmeasurements] = useState<any>({});
|
const [measurements, setmeasurements] = useState<any>({});
|
||||||
const [duration, setDuration] = useState("1h")
|
const [duration, setDuration] = useState("1h");
|
||||||
const [name, setName] = useState("Widget")
|
const [name, setName] = useState("Widget");
|
||||||
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
const [chartData, setChartData] = useState<{
|
||||||
|
labels: string[];
|
||||||
|
datasets: any[];
|
||||||
|
}>({
|
||||||
labels: [],
|
labels: [],
|
||||||
datasets: [],
|
datasets: [],
|
||||||
});
|
});
|
||||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
// Improved sample data for the smooth curve graph (single day)
|
// Improved sample data for the smooth curve graph (single day)
|
||||||
const graphData: ChartData<"line"> = {
|
const graphData: ChartData<"line"> = {
|
||||||
labels: [
|
labels: [
|
||||||
|
@ -129,7 +141,8 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
|
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
const socket = io(`http://${iotApiUrl}`);
|
const socket = io(`http://${iotApiUrl}`);
|
||||||
|
|
||||||
|
@ -139,7 +152,6 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
|
||||||
interval: 1000,
|
interval: 1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const startStream = () => {
|
const startStream = () => {
|
||||||
socket.emit("lineInput", inputData);
|
socket.emit("lineInput", inputData);
|
||||||
};
|
};
|
||||||
|
@ -157,8 +169,10 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
|
||||||
return {
|
return {
|
||||||
label: datasetKey,
|
label: datasetKey,
|
||||||
data: responseData[datasetKey]?.values ?? [],
|
data: responseData[datasetKey]?.values ?? [],
|
||||||
borderColor: index === 0 ? "rgba(75, 192, 192, 1)" : "rgba(255, 99, 132, 1)", // Light blue color
|
borderColor:
|
||||||
backgroundColor: index === 0 ? "rgba(75, 192, 192, 0.2)" : "rgba(255, 99, 132, 0.2)",
|
index === 0 ? "rgba(75, 192, 192, 1)" : "rgba(255, 99, 132, 1)", // Light blue color
|
||||||
|
backgroundColor:
|
||||||
|
index === 0 ? "rgba(75, 192, 192, 0.2)" : "rgba(255, 99, 132, 0.2)",
|
||||||
fill: true,
|
fill: true,
|
||||||
tension: 0.4, // Smooth curve effect
|
tension: 0.4, // Smooth curve effect
|
||||||
pointRadius: 0, // Hide dots
|
pointRadius: 0, // Hide dots
|
||||||
|
@ -177,14 +191,15 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
|
||||||
}, [measurements, duration, iotApiUrl]);
|
}, [measurements, duration, iotApiUrl]);
|
||||||
|
|
||||||
const fetchSavedInputes = async () => {
|
const fetchSavedInputes = async () => {
|
||||||
|
|
||||||
if (id !== "") {
|
if (id !== "") {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`);
|
const response = await axios.get(
|
||||||
|
`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);
|
||||||
setName(response.data.widgetName)
|
setName(response.data.widgetName);
|
||||||
} else {
|
} else {
|
||||||
console.log("Unexpected response:", response);
|
console.log("Unexpected response:", response);
|
||||||
}
|
}
|
||||||
|
@ -192,7 +207,7 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
|
||||||
console.error("There was an error!", error);
|
console.error("There was an error!", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchSavedInputes();
|
fetchSavedInputes();
|
||||||
|
@ -202,8 +217,7 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
|
||||||
if (selectedChartId?.id === id) {
|
if (selectedChartId?.id === id) {
|
||||||
fetchSavedInputes();
|
fetchSavedInputes();
|
||||||
}
|
}
|
||||||
}
|
}, [chartMeasurements, chartDuration, widgetName]);
|
||||||
, [chartMeasurements, chartDuration, widgetName])
|
|
||||||
const rotationDegrees = {
|
const rotationDegrees = {
|
||||||
x: (rotation[0] * 180) / Math.PI,
|
x: (rotation[0] * 180) / Math.PI,
|
||||||
y: (rotation[1] * 180) / Math.PI,
|
y: (rotation[1] * 180) / Math.PI,
|
||||||
|
@ -215,27 +229,32 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ id, type, posit
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Html position={[position[0], position[1], position[2]]}
|
<Html
|
||||||
|
position={[position[0], position[1], position[2]]}
|
||||||
scale={[0.5, 0.5, 0.5]}
|
scale={[0.5, 0.5, 0.5]}
|
||||||
transform
|
transform
|
||||||
zIndexRange={[1, 0]}
|
zIndexRange={[1, 0]}
|
||||||
sprite
|
sprite
|
||||||
style={{
|
style={{
|
||||||
transform: transformStyle.transform,
|
transform: transformStyle.transform,
|
||||||
transformStyle: 'preserve-3d',
|
transformStyle: "preserve-3d",
|
||||||
transition: 'transform 0.1s ease-out'
|
transition: "transform 0.1s ease-out",
|
||||||
|
|
||||||
}}
|
}}
|
||||||
className={`${selectedChartId?.id === id ? "activeChart" : ""}`}
|
|
||||||
>
|
>
|
||||||
<div className="returnOfInvestment card"
|
<div
|
||||||
|
className={`returnOfInvestment card ${
|
||||||
|
selectedChartId?.id === id ? "activeChart" : ""
|
||||||
|
}`}
|
||||||
onClick={() => setSelectedChartId({ id: id, type: type })}
|
onClick={() => setSelectedChartId({ id: id, type: type })}
|
||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
>
|
>
|
||||||
<div className="header">Return of Investment</div>
|
<div className="header">Return of Investment</div>
|
||||||
<div className="lineGraph charts">
|
<div className="lineGraph charts">
|
||||||
{/* Smooth curve graph with two datasets */}
|
{/* Smooth curve graph with two datasets */}
|
||||||
<SmoothLineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
|
<SmoothLineGraphComponent
|
||||||
|
data={Object.keys(measurements).length > 0 ? chartData : graphData}
|
||||||
|
options={graphOptions}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="returns-wrapper">
|
<div className="returns-wrapper">
|
||||||
<div className="icon">
|
<div className="icon">
|
||||||
|
|
|
@ -13,16 +13,26 @@ interface StateWorkingProps {
|
||||||
rotation: [number, number, number];
|
rotation: [number, number, number];
|
||||||
onContextMenu?: (event: React.MouseEvent) => void;
|
onContextMenu?: (event: React.MouseEvent) => void;
|
||||||
}
|
}
|
||||||
const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotation, onContextMenu }) => {
|
const StateWorking: React.FC<StateWorkingProps> = ({
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
position,
|
||||||
|
rotation,
|
||||||
|
onContextMenu,
|
||||||
|
}) => {
|
||||||
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
||||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
const {
|
||||||
|
measurements: chartMeasurements,
|
||||||
|
duration: chartDuration,
|
||||||
|
name: widgetName,
|
||||||
|
} = useChartStore();
|
||||||
const [measurements, setmeasurements] = useState<any>({});
|
const [measurements, setmeasurements] = useState<any>({});
|
||||||
const [duration, setDuration] = useState("1h")
|
const [duration, setDuration] = useState("1h");
|
||||||
const [name, setName] = useState("Widget")
|
const [name, setName] = useState("Widget");
|
||||||
const [datas, setDatas] = useState<any>({});
|
const [datas, setDatas] = useState<any>({});
|
||||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
// const datas = [
|
// const datas = [
|
||||||
// { key: "Oil Tank:", value: "24/341" },
|
// { key: "Oil Tank:", value: "24/341" },
|
||||||
// { key: "Oil Refin:", value: 36.023 },
|
// { key: "Oil Refin:", value: 36.023 },
|
||||||
|
@ -33,7 +43,8 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
// ];
|
// ];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
|
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
|
||||||
|
return;
|
||||||
const socket = io(`http://${iotApiUrl}`);
|
const socket = io(`http://${iotApiUrl}`);
|
||||||
const inputData = {
|
const inputData = {
|
||||||
measurements,
|
measurements,
|
||||||
|
@ -46,7 +57,6 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
socket.on("connect", startStream);
|
socket.on("connect", startStream);
|
||||||
socket.on("lastOutput", (response) => {
|
socket.on("lastOutput", (response) => {
|
||||||
const responseData = response;
|
const responseData = response;
|
||||||
|
|
||||||
|
|
||||||
setDatas(responseData);
|
setDatas(responseData);
|
||||||
});
|
});
|
||||||
|
@ -59,14 +69,15 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
}, [measurements, duration, iotApiUrl]);
|
}, [measurements, duration, iotApiUrl]);
|
||||||
|
|
||||||
const fetchSavedInputes = async () => {
|
const fetchSavedInputes = async () => {
|
||||||
|
|
||||||
if (id !== "") {
|
if (id !== "") {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`);
|
const response = await axios.get(
|
||||||
|
`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);
|
||||||
setName(response.data.widgetName)
|
setName(response.data.widgetName);
|
||||||
} else {
|
} else {
|
||||||
console.log("Unexpected response:", response);
|
console.log("Unexpected response:", response);
|
||||||
}
|
}
|
||||||
|
@ -74,10 +85,7 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
console.error("There was an error!", error);
|
console.error("There was an error!", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchSavedInputes();
|
fetchSavedInputes();
|
||||||
|
@ -87,8 +95,7 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
if (selectedChartId?.id === id) {
|
if (selectedChartId?.id === id) {
|
||||||
fetchSavedInputes();
|
fetchSavedInputes();
|
||||||
}
|
}
|
||||||
}
|
}, [chartMeasurements, chartDuration, widgetName]);
|
||||||
, [chartMeasurements, chartDuration, widgetName])
|
|
||||||
|
|
||||||
const rotationDegrees = {
|
const rotationDegrees = {
|
||||||
x: (rotation[0] * 180) / Math.PI,
|
x: (rotation[0] * 180) / Math.PI,
|
||||||
|
@ -100,20 +107,22 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
transform: `rotateX(${rotationDegrees.x}deg) rotateY(${rotationDegrees.y}deg) rotateZ(${rotationDegrees.z}deg)`,
|
transform: `rotateX(${rotationDegrees.x}deg) rotateY(${rotationDegrees.y}deg) rotateZ(${rotationDegrees.z}deg)`,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Html position={[position[0], position[1], position[2]]}
|
<Html
|
||||||
|
position={[position[0], position[1], position[2]]}
|
||||||
scale={[0.5, 0.5, 0.5]}
|
scale={[0.5, 0.5, 0.5]}
|
||||||
transform
|
transform
|
||||||
zIndexRange={[1, 0]}
|
zIndexRange={[1, 0]}
|
||||||
sprite
|
sprite
|
||||||
style={{
|
style={{
|
||||||
transform: transformStyle.transform,
|
transform: transformStyle.transform,
|
||||||
transformStyle: 'preserve-3d',
|
transformStyle: "preserve-3d",
|
||||||
transition: 'transform 0.1s ease-out'
|
transition: "transform 0.1s ease-out",
|
||||||
|
|
||||||
}}
|
}}
|
||||||
className={`${selectedChartId?.id === id ? "activeChart" : ""}`}
|
|
||||||
>
|
>
|
||||||
<div className="stateWorking-wrapper card"
|
<div
|
||||||
|
className={`stateWorking-wrapper card ${
|
||||||
|
selectedChartId?.id === id ? "activeChart" : ""
|
||||||
|
}`}
|
||||||
onClick={() => setSelectedChartId({ id: id, type: type })}
|
onClick={() => setSelectedChartId({ id: id, type: type })}
|
||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
>
|
>
|
||||||
|
@ -121,12 +130,10 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
<div className="header">
|
<div className="header">
|
||||||
<span>State</span>
|
<span>State</span>
|
||||||
<span>
|
<span>
|
||||||
{datas?.input1 ? datas.input1 : 'input1'} <span>.</span>
|
{datas?.input1 ? datas.input1 : "input1"} <span>.</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="img">
|
<div className="img">{/* <img src={image} alt="" /> */}</div>
|
||||||
{/* <img src={image} alt="" /> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/* Data */}
|
{/* Data */}
|
||||||
<div className="data-wrapper">
|
<div className="data-wrapper">
|
||||||
|
@ -137,28 +144,52 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
</div>
|
</div>
|
||||||
))} */}
|
))} */}
|
||||||
<div className="data-table">
|
<div className="data-table">
|
||||||
<div className="data">{measurements?.input2?.fields ? measurements.input2.fields : 'input2'}</div>
|
<div className="data">
|
||||||
<div className="key">{datas?.input2 ? datas.input2 : 'data'}</div>
|
{measurements?.input2?.fields
|
||||||
|
? measurements.input2.fields
|
||||||
|
: "input2"}
|
||||||
|
</div>
|
||||||
|
<div className="key">{datas?.input2 ? datas.input2 : "data"}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="data-table">
|
<div className="data-table">
|
||||||
<div className="data">{measurements?.input3?.fields ? measurements.input3.fields : 'input3'}</div>
|
<div className="data">
|
||||||
<div className="key">{datas?.input3 ? datas.input3 : 'data'}</div>
|
{measurements?.input3?.fields
|
||||||
|
? measurements.input3.fields
|
||||||
|
: "input3"}
|
||||||
|
</div>
|
||||||
|
<div className="key">{datas?.input3 ? datas.input3 : "data"}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="data-table">
|
<div className="data-table">
|
||||||
<div className="data">{measurements?.input4?.fields ? measurements.input4.fields : 'input4'}</div>
|
<div className="data">
|
||||||
<div className="key">{datas?.input4 ? datas.input4 : 'data'}</div>
|
{measurements?.input4?.fields
|
||||||
|
? measurements.input4.fields
|
||||||
|
: "input4"}
|
||||||
|
</div>
|
||||||
|
<div className="key">{datas?.input4 ? datas.input4 : "data"}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="data-table">
|
<div className="data-table">
|
||||||
<div className="data">{measurements?.input5?.fields ? measurements.input5.fields : 'input5'}</div>
|
<div className="data">
|
||||||
<div className="key">{datas?.input5 ? datas.input5 : 'data'}</div>
|
{measurements?.input5?.fields
|
||||||
|
? measurements.input5.fields
|
||||||
|
: "input5"}
|
||||||
|
</div>
|
||||||
|
<div className="key">{datas?.input5 ? datas.input5 : "data"}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="data-table">
|
<div className="data-table">
|
||||||
<div className="data">{measurements?.input6?.fields ? measurements.input6.fields : 'input6'}</div>
|
<div className="data">
|
||||||
<div className="key">{datas?.input6 ? datas.input6 : 'data'}</div>
|
{measurements?.input6?.fields
|
||||||
|
? measurements.input6.fields
|
||||||
|
: "input6"}
|
||||||
|
</div>
|
||||||
|
<div className="key">{datas?.input6 ? datas.input6 : "data"}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="data-table">
|
<div className="data-table">
|
||||||
<div className="data">{measurements?.input7?.fields ? measurements.input7.fields : 'input7'}</div>
|
<div className="data">
|
||||||
<div className="key">{datas?.input7 ? datas.input7 : 'data'}</div>
|
{measurements?.input7?.fields
|
||||||
|
? measurements.input7.fields
|
||||||
|
: "input7"}
|
||||||
|
</div>
|
||||||
|
<div className="key">{datas?.input7 ? datas.input7 : "data"}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -167,5 +198,3 @@ const StateWorking: React.FC<StateWorkingProps> = ({ id, type, position, rotatio
|
||||||
};
|
};
|
||||||
|
|
||||||
export default StateWorking;
|
export default StateWorking;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,20 +49,32 @@ interface ThroughputProps {
|
||||||
onContextMenu?: (event: React.MouseEvent) => void;
|
onContextMenu?: (event: React.MouseEvent) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, onContextMenu }) => {
|
const Throughput: React.FC<ThroughputProps> = ({
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
position,
|
||||||
|
rotation,
|
||||||
|
onContextMenu,
|
||||||
|
}) => {
|
||||||
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
||||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
const {
|
||||||
|
measurements: chartMeasurements,
|
||||||
|
duration: chartDuration,
|
||||||
|
name: widgetName,
|
||||||
|
} = useChartStore();
|
||||||
const [measurements, setmeasurements] = useState<any>({});
|
const [measurements, setmeasurements] = useState<any>({});
|
||||||
const [duration, setDuration] = useState("1h")
|
const [duration, setDuration] = useState("1h");
|
||||||
const [name, setName] = useState("Widget")
|
const [name, setName] = useState("Widget");
|
||||||
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
const [chartData, setChartData] = useState<{
|
||||||
|
labels: string[];
|
||||||
|
datasets: any[];
|
||||||
|
}>({
|
||||||
labels: [],
|
labels: [],
|
||||||
datasets: [],
|
datasets: [],
|
||||||
});
|
});
|
||||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
// Sample data for the line graph
|
// Sample data for the line graph
|
||||||
const graphData: ChartData<"line"> = {
|
const graphData: ChartData<"line"> = {
|
||||||
|
@ -112,7 +124,8 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
|
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
const socket = io(`http://${iotApiUrl}`);
|
const socket = io(`http://${iotApiUrl}`);
|
||||||
|
|
||||||
|
@ -122,7 +135,6 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
|
||||||
interval: 1000,
|
interval: 1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const startStream = () => {
|
const startStream = () => {
|
||||||
socket.emit("lineInput", inputData);
|
socket.emit("lineInput", inputData);
|
||||||
};
|
};
|
||||||
|
@ -157,14 +169,15 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
|
||||||
}, [measurements, duration, iotApiUrl]);
|
}, [measurements, duration, iotApiUrl]);
|
||||||
|
|
||||||
const fetchSavedInputes = async () => {
|
const fetchSavedInputes = async () => {
|
||||||
|
|
||||||
if (id !== "") {
|
if (id !== "") {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget3D/${id}/${organization}`);
|
const response = await axios.get(
|
||||||
|
`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);
|
||||||
setName(response.data.widgetName)
|
setName(response.data.widgetName);
|
||||||
} else {
|
} else {
|
||||||
console.log("Unexpected response:", response);
|
console.log("Unexpected response:", response);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +185,7 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
|
||||||
console.error("There was an error!", error);
|
console.error("There was an error!", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchSavedInputes();
|
fetchSavedInputes();
|
||||||
|
@ -182,8 +195,7 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
|
||||||
if (selectedChartId?.id === id) {
|
if (selectedChartId?.id === id) {
|
||||||
fetchSavedInputes();
|
fetchSavedInputes();
|
||||||
}
|
}
|
||||||
}
|
}, [chartMeasurements, chartDuration, widgetName]);
|
||||||
, [chartMeasurements, chartDuration, widgetName])
|
|
||||||
const rotationDegrees = {
|
const rotationDegrees = {
|
||||||
x: (rotation[0] * 180) / Math.PI,
|
x: (rotation[0] * 180) / Math.PI,
|
||||||
y: (rotation[1] * 180) / Math.PI,
|
y: (rotation[1] * 180) / Math.PI,
|
||||||
|
@ -195,20 +207,22 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Html position={[position[0], position[1], position[2]]}
|
<Html
|
||||||
|
position={[position[0], position[1], position[2]]}
|
||||||
scale={[0.5, 0.5, 0.5]}
|
scale={[0.5, 0.5, 0.5]}
|
||||||
transform
|
transform
|
||||||
zIndexRange={[1, 0]}
|
zIndexRange={[1, 0]}
|
||||||
sprite
|
sprite
|
||||||
style={{
|
style={{
|
||||||
transform: transformStyle.transform,
|
transform: transformStyle.transform,
|
||||||
transformStyle: 'preserve-3d',
|
transformStyle: "preserve-3d",
|
||||||
transition: 'transform 0.1s ease-out'
|
transition: "transform 0.1s ease-out",
|
||||||
|
|
||||||
}}
|
}}
|
||||||
className={`${selectedChartId?.id === id ? "activeChart" : ""}`}
|
|
||||||
>
|
>
|
||||||
<div className="throughput-wrapper"
|
<div
|
||||||
|
className={`throughput-wrapper card ${
|
||||||
|
selectedChartId?.id === id ? "activeChart" : ""
|
||||||
|
}`}
|
||||||
onClick={() => setSelectedChartId({ id: id, type: type })}
|
onClick={() => setSelectedChartId({ id: id, type: type })}
|
||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
>
|
>
|
||||||
|
@ -235,7 +249,10 @@ const Throughput: React.FC<ThroughputProps> = ({ id, type, position, rotation, o
|
||||||
</div>
|
</div>
|
||||||
<div className="line-graph">
|
<div className="line-graph">
|
||||||
{/* Line graph using react-chartjs-2 */}
|
{/* Line graph using react-chartjs-2 */}
|
||||||
<LineGraphComponent data={Object.keys(measurements).length > 0 ? chartData : graphData} options={graphOptions} />
|
<LineGraphComponent
|
||||||
|
data={Object.keys(measurements).length > 0 ? chartData : graphData}
|
||||||
|
options={graphOptions}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="footer">
|
<div className="footer">
|
||||||
You made an extra <span className="value">$1256.13</span> this month
|
You made an extra <span className="value">$1256.13</span> this month
|
||||||
|
|
|
@ -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) {}
|
||||||
|
@ -147,7 +148,7 @@ const Assets: React.FC = () => {
|
||||||
<div className="assets-container">
|
<div className="assets-container">
|
||||||
{categoryAssets &&
|
{categoryAssets &&
|
||||||
categoryAssets?.map((asset: any, index: number) => (
|
categoryAssets?.map((asset: any, index: number) => (
|
||||||
<div key={index} className="assets">
|
<div key={index} className="assets" id={asset.filename}>
|
||||||
<img
|
<img
|
||||||
src={asset?.thumbnail}
|
src={asset?.thumbnail}
|
||||||
alt={asset.filename}
|
alt={asset.filename}
|
||||||
|
@ -171,6 +172,7 @@ const Assets: React.FC = () => {
|
||||||
<div className="assets-wrapper">
|
<div className="assets-wrapper">
|
||||||
<div
|
<div
|
||||||
className="back-button"
|
className="back-button"
|
||||||
|
id="asset-backButtom"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedCategory(null);
|
setSelectedCategory(null);
|
||||||
setCategoryAssets([]);
|
setCategoryAssets([]);
|
||||||
|
@ -182,7 +184,7 @@ const Assets: React.FC = () => {
|
||||||
<div className="assets-container">
|
<div className="assets-container">
|
||||||
{categoryAssets &&
|
{categoryAssets &&
|
||||||
categoryAssets?.map((asset: any, index: number) => (
|
categoryAssets?.map((asset: any, index: number) => (
|
||||||
<div key={index} className="assets">
|
<div key={index} className="assets" id={asset.filename}>
|
||||||
<img
|
<img
|
||||||
src={asset?.thumbnail}
|
src={asset?.thumbnail}
|
||||||
alt={asset.filename}
|
alt={asset.filename}
|
||||||
|
@ -190,7 +192,7 @@ const Assets: React.FC = () => {
|
||||||
onPointerDown={() =>
|
onPointerDown={() =>
|
||||||
setSelectedItem({
|
setSelectedItem({
|
||||||
name: asset.filename,
|
name: asset.filename,
|
||||||
id: asset.modelfileID,
|
id: asset.AssetID,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -222,6 +224,7 @@ const Assets: React.FC = () => {
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className="category"
|
className="category"
|
||||||
|
id={category}
|
||||||
onClick={() => fetchCategoryAssets(category)}
|
onClick={() => fetchCategoryAssets(category)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
|
|
@ -4,6 +4,7 @@ import useTemplateStore from "../../../../store/useTemplateStore";
|
||||||
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
||||||
import { getTemplateData } from "../../../../services/realTimeVisulization/zoneData/getTemplate";
|
import { getTemplateData } from "../../../../services/realTimeVisulization/zoneData/getTemplate";
|
||||||
import { useSocketStore } from "../../../../store/store";
|
import { useSocketStore } from "../../../../store/store";
|
||||||
|
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||||
|
|
||||||
const Templates = () => {
|
const Templates = () => {
|
||||||
const { templates, removeTemplate, setTemplates } = useTemplateStore();
|
const { templates, removeTemplate, setTemplates } = useTemplateStore();
|
||||||
|
@ -34,7 +35,10 @@ const Templates = () => {
|
||||||
templateID: id,
|
templateID: id,
|
||||||
};
|
};
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-template:deleteTemplate", deleteTemplate);
|
visualizationSocket.emit(
|
||||||
|
"v2:viz-template:deleteTemplate",
|
||||||
|
deleteTemplate
|
||||||
|
);
|
||||||
}
|
}
|
||||||
removeTemplate(id);
|
removeTemplate(id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -65,11 +69,15 @@ const Templates = () => {
|
||||||
widgets: template.widgets,
|
widgets: template.widgets,
|
||||||
});
|
});
|
||||||
|
|
||||||
useDroppedObjectsStore.getState().setZone(selectedZone.zoneName, selectedZone.zoneId);
|
useDroppedObjectsStore
|
||||||
|
.getState()
|
||||||
|
.setZone(selectedZone.zoneName, selectedZone.zoneId);
|
||||||
|
|
||||||
if (Array.isArray(template.floatingWidget)) {
|
if (Array.isArray(template.floatingWidget)) {
|
||||||
template.floatingWidget.forEach((val: any) => {
|
template.floatingWidget.forEach((val: any) => {
|
||||||
useDroppedObjectsStore.getState().addObject(selectedZone.zoneName, val);
|
useDroppedObjectsStore
|
||||||
|
.getState()
|
||||||
|
.addObject(selectedZone.zoneName, val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -79,7 +87,7 @@ const Templates = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="template-list">
|
<div className="template-list">
|
||||||
{templates.map((template) => (
|
{templates.map((template, index) => (
|
||||||
<div key={template.id} className="template-item">
|
<div key={template.id} className="template-item">
|
||||||
{template?.snapshot && (
|
{template?.snapshot && (
|
||||||
<div className="template-image-container">
|
<div className="template-image-container">
|
||||||
|
@ -96,7 +104,8 @@ const Templates = () => {
|
||||||
onClick={() => handleLoadTemplate(template)}
|
onClick={() => handleLoadTemplate(template)}
|
||||||
className="template-name"
|
className="template-name"
|
||||||
>
|
>
|
||||||
{template.name}
|
{/* {`Template ${index + 1}`} */}
|
||||||
|
<RenameInput value={`Template ${index + 1}`} />
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDeleteTemplate(template.id)}
|
onClick={() => handleDeleteTemplate(template.id)}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
import React, { useEffect } from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
CleanPannel,
|
CleanPannel,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
LockIcon,
|
LockIcon,
|
||||||
} from "../../icons/RealTimeVisulationIcons";
|
} from "../../icons/RealTimeVisulationIcons";
|
||||||
import { panelData } from "../../../services/realTimeVisulization/zoneData/panel";
|
|
||||||
import { AddIcon } from "../../icons/ExportCommonIcons";
|
import { AddIcon } from "../../icons/ExportCommonIcons";
|
||||||
import { deletePanelApi } from "../../../services/realTimeVisulization/zoneData/deletePanel";
|
|
||||||
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";
|
||||||
|
|
||||||
|
// Define the type for HiddenPanels, where keys are zone IDs and values are arrays of hidden sides
|
||||||
|
interface HiddenPanels {
|
||||||
|
[zoneId: string]: Side[];
|
||||||
|
}
|
||||||
|
|
||||||
// Define the type for the props passed to the Buttons component
|
// Define the type for the props passed to the Buttons component
|
||||||
interface ButtonsProps {
|
interface ButtonsProps {
|
||||||
selectedZone: {
|
selectedZone: {
|
||||||
|
@ -35,7 +40,6 @@ interface ButtonsProps {
|
||||||
zoneName: string;
|
zoneName: string;
|
||||||
activeSides: Side[];
|
activeSides: Side[];
|
||||||
panelOrder: Side[];
|
panelOrder: Side[];
|
||||||
|
|
||||||
lockedPanels: Side[];
|
lockedPanels: Side[];
|
||||||
zoneId: string;
|
zoneId: string;
|
||||||
zoneViewPortTarget: number[];
|
zoneViewPortTarget: number[];
|
||||||
|
@ -49,8 +53,8 @@ interface ButtonsProps {
|
||||||
}[];
|
}[];
|
||||||
}>
|
}>
|
||||||
>;
|
>;
|
||||||
hiddenPanels: Side[]; // Add this prop for hidden panels
|
hiddenPanels: HiddenPanels; // Updated prop type
|
||||||
setHiddenPanels: React.Dispatch<React.SetStateAction<Side[]>>; // Add this prop for updating hidden panels
|
setHiddenPanels: React.Dispatch<React.SetStateAction<HiddenPanels>>; // Updated prop type
|
||||||
}
|
}
|
||||||
|
|
||||||
const AddButtons: React.FC<ButtonsProps> = ({
|
const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
|
@ -61,11 +65,35 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
|
||||||
// Local state to track hidden panels
|
// Function to toggle visibility of a panel
|
||||||
|
const toggleVisibility = (side: Side) => {
|
||||||
|
const isHidden = hiddenPanels[selectedZone.zoneId]?.includes(side) ?? false;
|
||||||
|
|
||||||
|
if (isHidden) {
|
||||||
|
// If the panel is already hidden, remove it from the hiddenPanels array for this zone
|
||||||
|
setHiddenPanels((prevHiddenPanels) => ({
|
||||||
|
...prevHiddenPanels,
|
||||||
|
[selectedZone.zoneId]: prevHiddenPanels[selectedZone.zoneId].filter(
|
||||||
|
(panel) => panel !== side
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
// If the panel is visible, add it to the hiddenPanels array for this zone
|
||||||
|
setHiddenPanels((prevHiddenPanels) => ({
|
||||||
|
...prevHiddenPanels,
|
||||||
|
[selectedZone.zoneId]: [
|
||||||
|
...(prevHiddenPanels[selectedZone.zoneId] || []),
|
||||||
|
side,
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 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)
|
||||||
|
@ -76,36 +104,65 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
lockedPanels: newLockedPanels,
|
lockedPanels: newLockedPanels,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the selectedZone state
|
let lockedPanel = {
|
||||||
setSelectedZone(updatedZone);
|
organization: organization,
|
||||||
};
|
lockedPanel: newLockedPanels,
|
||||||
|
zoneId: selectedZone.zoneId,
|
||||||
// Function to toggle visibility of a panel
|
};
|
||||||
const toggleVisibility = (side: Side) => {
|
if (visualizationSocket) {
|
||||||
const isHidden = hiddenPanels.includes(side);
|
visualizationSocket.emit("v2:viz-panel:locked", lockedPanel);
|
||||||
if (isHidden) {
|
|
||||||
// If the panel is already hidden, remove it from the hiddenPanels array
|
|
||||||
setHiddenPanels(hiddenPanels.filter((panel) => panel !== side));
|
|
||||||
} else {
|
|
||||||
// If the panel is visible, add it to the hiddenPanels array
|
|
||||||
setHiddenPanels([...hiddenPanels, side]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -150,8 +207,6 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
} else {
|
} else {
|
||||||
setHiddenPanels(hiddenPanels.filter((panel) => panel !== side));
|
|
||||||
|
|
||||||
// Panel does not exist: Create panel
|
// Panel does not exist: Create panel
|
||||||
try {
|
try {
|
||||||
// Get email and organization safely with a default fallback
|
// Get email and organization safely with a default fallback
|
||||||
|
@ -185,10 +240,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
// } else {
|
// } else {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
} catch (error) {}
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
|
@ -196,9 +250,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
<div key={side} className={`side-button-container ${side}`}>
|
<div key={side} className={`side-button-container ${side}`}>
|
||||||
{/* "+" Button */}
|
{/* "+" Button */}
|
||||||
<button
|
<button
|
||||||
className={`side-button ${side}${
|
className={`side-button ${side}${selectedZone.activeSides.includes(side) ? " active" : ""
|
||||||
selectedZone.activeSides.includes(side) ? " active" : ""
|
}`}
|
||||||
}`}
|
|
||||||
onClick={() => handlePlusButtonClick(side)}
|
onClick={() => handlePlusButtonClick(side)}
|
||||||
title={
|
title={
|
||||||
selectedZone.activeSides.includes(side)
|
selectedZone.activeSides.includes(side)
|
||||||
|
@ -217,16 +270,20 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
{/* Hide Panel */}
|
{/* Hide Panel */}
|
||||||
<div
|
<div
|
||||||
className={`icon ${
|
className={`icon ${
|
||||||
hiddenPanels.includes(side) ? "active" : ""
|
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
||||||
|
? "active"
|
||||||
|
: ""
|
||||||
}`}
|
}`}
|
||||||
title={
|
title={
|
||||||
hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel"
|
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
||||||
|
? "Show Panel"
|
||||||
|
: "Hide Panel"
|
||||||
}
|
}
|
||||||
onClick={() => toggleVisibility(side)}
|
onClick={() => toggleVisibility(side)}
|
||||||
>
|
>
|
||||||
<EyeIcon
|
<EyeIcon
|
||||||
fill={
|
fill={
|
||||||
hiddenPanels.includes(side)
|
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
||||||
? "var(--primary-color)"
|
? "var(--primary-color)"
|
||||||
: "var(--text-color)"
|
: "var(--text-color)"
|
||||||
}
|
}
|
||||||
|
@ -244,9 +301,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
|
|
||||||
{/* Lock/Unlock Panel */}
|
{/* Lock/Unlock Panel */}
|
||||||
<div
|
<div
|
||||||
className={`icon ${
|
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""
|
||||||
selectedZone.lockedPanels.includes(side) ? "active" : ""
|
}`}
|
||||||
}`}
|
|
||||||
title={
|
title={
|
||||||
selectedZone.lockedPanels.includes(side)
|
selectedZone.lockedPanels.includes(side)
|
||||||
? "Unlock Panel"
|
? "Unlock Panel"
|
||||||
|
|
|
@ -157,6 +157,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
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);
|
||||||
|
|
||||||
|
|
||||||
let res = await getFloatingZoneData(zoneId, organization);
|
let res = await getFloatingZoneData(zoneId, organization);
|
||||||
|
|
||||||
setFloatingWidget(res);
|
setFloatingWidget(res);
|
||||||
|
|
|
@ -88,12 +88,15 @@ export const DraggableWidget = ({
|
||||||
|
|
||||||
const chartWidget = useRef<HTMLDivElement>(null);
|
const chartWidget = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const isPanelHidden = hiddenPanels.includes(widget.panel);
|
OuterClick({
|
||||||
|
contextClassName: [
|
||||||
// OuterClick({
|
"chart-container",
|
||||||
// contextClassName: ["chart-container", "floating", "sidebar-right-wrapper"],
|
"floating",
|
||||||
// setMenuVisible: () => setSelectedChartId(null),
|
"sidebar-right-wrapper",
|
||||||
// });
|
"card",
|
||||||
|
],
|
||||||
|
setMenuVisible: () => setSelectedChartId(null),
|
||||||
|
});
|
||||||
|
|
||||||
const deleteSelectedChart = async () => {
|
const deleteSelectedChart = async () => {
|
||||||
try {
|
try {
|
||||||
|
@ -397,4 +400,4 @@ export const DraggableWidget = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// by using canvasDimensions.height canvasDimensions.width dynamically div value insted of static 6 and 4 calculate according to canvasDimensions.width canvasDimensions.height
|
||||||
|
|
|
@ -143,7 +143,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
// if (res.message === "FloatingWidget deleted successfully") {
|
// if (res.message === "FloatingWidget deleted successfully") {
|
||||||
// deleteObject(zoneName, id, index); // Call the deleteObject method from the store
|
// deleteObject(zoneName, id, index); // Call the deleteObject method from the store
|
||||||
// }
|
// }
|
||||||
} catch (error) {}
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
||||||
|
@ -510,7 +510,6 @@ const DroppedObjects: React.FC = () => {
|
||||||
|
|
||||||
const widthMultiplier = parseFloat(containerWidth) * 0.13;
|
const widthMultiplier = parseFloat(containerWidth) * 0.13;
|
||||||
|
|
||||||
console.log("zone.objects: ", zone.objects);
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onPointerMove={handlePointerMove}
|
onPointerMove={handlePointerMove}
|
||||||
|
@ -520,46 +519,41 @@ const DroppedObjects: React.FC = () => {
|
||||||
{zone.objects.map((obj, index) => {
|
{zone.objects.map((obj, index) => {
|
||||||
const topPosition =
|
const topPosition =
|
||||||
typeof obj.position.top === "number"
|
typeof obj.position.top === "number"
|
||||||
? `calc(${obj.position.top}px + ${
|
? `calc(${obj.position.top}px + ${isPlaying && selectedZone.activeSides.includes("top")
|
||||||
isPlaying && selectedZone.activeSides.includes("top")
|
? `${heightMultiplier - 55}px`
|
||||||
? `${heightMultiplier - 55}px`
|
: "0px"
|
||||||
: "0px"
|
})`
|
||||||
})`
|
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
const leftPosition =
|
const leftPosition =
|
||||||
typeof obj.position.left === "number"
|
typeof obj.position.left === "number"
|
||||||
? `calc(${obj.position.left}px + ${
|
? `calc(${obj.position.left}px + ${isPlaying && selectedZone.activeSides.includes("left")
|
||||||
isPlaying && selectedZone.activeSides.includes("left")
|
? `${widthMultiplier - 100}px`
|
||||||
? `${widthMultiplier - 100}px`
|
: "0px"
|
||||||
: "0px"
|
})`
|
||||||
})`
|
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
const rightPosition =
|
const rightPosition =
|
||||||
typeof obj.position.right === "number"
|
typeof obj.position.right === "number"
|
||||||
? `calc(${obj.position.right}px + ${
|
? `calc(${obj.position.right}px + ${isPlaying && selectedZone.activeSides.includes("right")
|
||||||
isPlaying && selectedZone.activeSides.includes("right")
|
? `${widthMultiplier - 100}px`
|
||||||
? `${widthMultiplier - 100}px`
|
: "0px"
|
||||||
: "0px"
|
})`
|
||||||
})`
|
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
const bottomPosition =
|
const bottomPosition =
|
||||||
typeof obj.position.bottom === "number"
|
typeof obj.position.bottom === "number"
|
||||||
? `calc(${obj.position.bottom}px + ${
|
? `calc(${obj.position.bottom}px + ${isPlaying && selectedZone.activeSides.includes("bottom")
|
||||||
isPlaying && selectedZone.activeSides.includes("bottom")
|
? `${heightMultiplier - 55}px`
|
||||||
? `${heightMultiplier - 55}px`
|
: "0px"
|
||||||
: "0px"
|
})`
|
||||||
})`
|
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={`${zoneName}-${index}`}
|
key={`${zoneName}-${index}`}
|
||||||
className={`${obj.className} ${
|
className={`${obj.className} ${selectedChartId?.id === obj.id && "activeChart"
|
||||||
selectedChartId?.id === obj.id && "activeChart"
|
}`}
|
||||||
}`}
|
|
||||||
ref={chartWidget}
|
ref={chartWidget}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
|
|
|
@ -39,7 +39,7 @@ interface PanelProps {
|
||||||
widgets: Widget[];
|
widgets: Widget[];
|
||||||
}>
|
}>
|
||||||
>;
|
>;
|
||||||
hiddenPanels: string[];
|
hiddenPanels: any;
|
||||||
setZonesData: React.Dispatch<React.SetStateAction<any>>;
|
setZonesData: React.Dispatch<React.SetStateAction<any>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,12 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
const handleDrop = (e: React.DragEvent, panel: Side) => {
|
const handleDrop = (e: React.DragEvent, panel: Side) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const { draggedAsset } = useWidgetStore.getState();
|
const { draggedAsset } = useWidgetStore.getState();
|
||||||
if (!draggedAsset || isPanelLocked(panel)) return;
|
if (
|
||||||
|
!draggedAsset ||
|
||||||
|
isPanelLocked(panel) ||
|
||||||
|
hiddenPanels[selectedZone.zoneId]?.includes(panel)
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
const currentWidgetsCount = getCurrentWidgetCount(panel);
|
const currentWidgetsCount = getCurrentWidgetCount(panel);
|
||||||
const maxCapacity = calculatePanelCapacity(panel);
|
const maxCapacity = calculatePanelCapacity(panel);
|
||||||
|
@ -261,7 +266,7 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
{`
|
{`
|
||||||
:root {
|
:root {
|
||||||
--topWidth: ${topWidth};
|
--topWidth: ${topWidth};
|
||||||
--bottomWidth: ${bottomWidth};
|
--bottomWidth: ${bottomWidth} ;
|
||||||
--leftHeight: ${leftHeight};
|
--leftHeight: ${leftHeight};
|
||||||
--rightHeight: ${rightHeight};
|
--rightHeight: ${rightHeight};
|
||||||
|
|
||||||
|
@ -278,7 +283,7 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
key={side}
|
key={side}
|
||||||
id="panel-wrapper"
|
id="panel-wrapper"
|
||||||
className={`panel ${side}-panel absolute ${
|
className={`panel ${side}-panel absolute ${
|
||||||
hiddenPanels.includes(side) ? "hidePanel" : ""
|
hiddenPanels[selectedZone.zoneId]?.includes(side) ? "hidePanel" : ""
|
||||||
}`}
|
}`}
|
||||||
style={getPanelStyle(side)}
|
style={getPanelStyle(side)}
|
||||||
onDrop={(e) => handleDrop(e, side)}
|
onDrop={(e) => handleDrop(e, side)}
|
||||||
|
@ -294,9 +299,11 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
<div
|
<div
|
||||||
className={`panel-content ${isPlaying && "fullScreen"}`}
|
className={`panel-content ${isPlaying && "fullScreen"}`}
|
||||||
style={{
|
style={{
|
||||||
pointerEvents: selectedZone.lockedPanels.includes(side)
|
pointerEvents:
|
||||||
? "none"
|
selectedZone.lockedPanels.includes(side) ||
|
||||||
: "auto",
|
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
||||||
|
? "none"
|
||||||
|
: "auto",
|
||||||
opacity: selectedZone.lockedPanels.includes(side) ? "0.8" : "1",
|
opacity: selectedZone.lockedPanels.includes(side) ? "0.8" : "1",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -53,8 +53,13 @@ type Widget = {
|
||||||
data: any;
|
data: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Define the type for HiddenPanels, where keys are zone IDs and values are arrays of hidden sides
|
||||||
|
interface HiddenPanels {
|
||||||
|
[zoneId: string]: Side[];
|
||||||
|
}
|
||||||
|
|
||||||
const RealTimeVisulization: React.FC = () => {
|
const RealTimeVisulization: React.FC = () => {
|
||||||
const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
|
const [hiddenPanels, setHiddenPanels] = React.useState<HiddenPanels>({});
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
|
@ -68,12 +73,12 @@ 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<Record<string, { zoneName: string; zoneId: string; objects: any[] }>>({});
|
// const [floatingWidgets, setFloatingWidgets] = useState<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();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function GetZoneData() {
|
async function GetZoneData() {
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
|
@ -100,7 +105,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
setZonesData(formattedData);
|
setZonesData(formattedData);
|
||||||
} catch (error) { }
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetZoneData();
|
GetZoneData();
|
||||||
|
@ -129,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") || "";
|
||||||
|
@ -175,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,
|
||||||
|
@ -182,23 +205,10 @@ 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,
|
|
||||||
[selectedZone.zoneName]: {
|
|
||||||
...prevWidgets[selectedZone.zoneName],
|
|
||||||
zoneName: selectedZone.zoneName,
|
|
||||||
zoneId: selectedZone.zoneId,
|
|
||||||
objects: [
|
|
||||||
...(prevWidgets[selectedZone.zoneName]?.objects || []),
|
|
||||||
newObject,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
} catch (error) { }
|
} catch (error) { }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -223,8 +233,6 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
};
|
};
|
||||||
}, [setRightClickSelected]);
|
}, [setRightClickSelected]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
|
@ -257,7 +265,6 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
}}
|
}}
|
||||||
onDrop={(event) => handleDrop(event)}
|
onDrop={(event) => handleDrop(event)}
|
||||||
onDragOver={(event) => event.preventDefault()}
|
onDragOver={(event) => event.preventDefault()}
|
||||||
|
|
||||||
>
|
>
|
||||||
<Scene />
|
<Scene />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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!);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,55 +1,22 @@
|
||||||
|
// 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) return null;
|
||||||
|
|
||||||
const canvas = document.createElement("canvas");
|
try {
|
||||||
const ctx = canvas.getContext("2d");
|
// Use html2canvas to capture the container
|
||||||
if (!ctx) return null;
|
// const canvas = await html2canvas(container, {
|
||||||
|
// scale: 1, // Adjust scale for higher/lower resolution
|
||||||
|
// });
|
||||||
|
|
||||||
const rect = container.getBoundingClientRect();
|
// // Convert the canvas to a data URL (PNG format)
|
||||||
canvas.width = rect.width;
|
// const dataUrl = canvas.toDataURL("image/png");
|
||||||
canvas.height = rect.height;
|
// return dataUrl;
|
||||||
|
|
||||||
// Draw background
|
return null;
|
||||||
ctx.fillStyle = getComputedStyle(container).backgroundColor;
|
} catch (error) {
|
||||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
console.error("Error capturing visualization:", error);
|
||||||
|
return null;
|
||||||
// Capture all canvas elements
|
}
|
||||||
const canvases = container.querySelectorAll("canvas");
|
|
||||||
canvases.forEach((childCanvas) => {
|
|
||||||
const childRect = childCanvas.getBoundingClientRect();
|
|
||||||
const x = childRect.left - rect.left;
|
|
||||||
const y = childRect.top - rect.top;
|
|
||||||
ctx.drawImage(childCanvas, x, y, childRect.width, childRect.height);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Capture SVG elements
|
|
||||||
const svgs = container.querySelectorAll("svg");
|
|
||||||
for (const svg of Array.from(svgs)) {
|
|
||||||
const svgString = new XMLSerializer().serializeToString(svg);
|
|
||||||
const svgBlob = new Blob([svgString], { type: "image/svg+xml" });
|
|
||||||
const url = URL.createObjectURL(svgBlob);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const img = await new Promise<HTMLImageElement>((resolve, reject) => {
|
|
||||||
const image = new Image();
|
|
||||||
image.onload = () => resolve(image);
|
|
||||||
image.onerror = reject;
|
|
||||||
image.src = url;
|
|
||||||
});
|
|
||||||
|
|
||||||
const svgRect = svg.getBoundingClientRect();
|
|
||||||
ctx.drawImage(
|
|
||||||
img,
|
|
||||||
svgRect.left - rect.left,
|
|
||||||
svgRect.top - rect.top,
|
|
||||||
svgRect.width,
|
|
||||||
svgRect.height
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return canvas.toDataURL("image/png");
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,10 +28,10 @@ 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) {
|
||||||
console.warn("No widgets found in the selected zone.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@ export const handleSaveTemplate = async ({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capture visualization snapshot
|
// Capture visualization snapshot
|
||||||
const snapshot = await captureVisualization();
|
// const snapshot = await captureVisualization();
|
||||||
|
const snapshot = null;
|
||||||
|
|
||||||
// if (!snapshot) {
|
// if (!snapshot) {
|
||||||
// return;
|
// return;
|
||||||
|
@ -64,8 +65,7 @@ export const handleSaveTemplate = async ({
|
||||||
floatingWidget,
|
floatingWidget,
|
||||||
widgets3D,
|
widgets3D,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('newTemplate: ', newTemplate);
|
|
||||||
// Extract organization from email
|
// Extract organization from email
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email.includes("@")
|
const organization = email.includes("@")
|
||||||
|
@ -73,7 +73,6 @@ export const handleSaveTemplate = async ({
|
||||||
: "";
|
: "";
|
||||||
|
|
||||||
if (!organization) {
|
if (!organization) {
|
||||||
console.error("Organization could not be determined from email.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let saveTemplate = {
|
let saveTemplate = {
|
||||||
|
@ -88,13 +87,13 @@ export const handleSaveTemplate = async ({
|
||||||
try {
|
try {
|
||||||
addTemplate(newTemplate);
|
addTemplate(newTemplate);
|
||||||
// const response = await saveTemplateApi(organization, newTemplate);
|
// const response = await saveTemplateApi(organization, newTemplate);
|
||||||
// console.log("Save API Response:", response);
|
//
|
||||||
|
|
||||||
// Add template only if API call succeeds
|
// Add template only if API call succeeds
|
||||||
} catch (apiError) {
|
} catch (apiError) {
|
||||||
// console.error("Error saving template to API:", apiError);
|
//
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.error("Error in handleSaveTemplate:", error);
|
//
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -81,9 +81,12 @@
|
||||||
|
|
||||||
.returnOfInvestment {
|
.returnOfInvestment {
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
min-width: 150px;
|
||||||
|
|
||||||
.charts {
|
.charts {
|
||||||
|
width: 100%;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
|
min-width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.returns-wrapper {
|
.returns-wrapper {
|
||||||
|
@ -126,6 +129,12 @@
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
border-radius: 5.2px;
|
border-radius: 5.2px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
font-size: $small;
|
font-size: $small;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
max-width: 80%;
|
max-width: 80%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-width: calc(100% - 500px);
|
max-width: calc(100% - 500px);
|
||||||
|
min-width: 150px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
transform: translate(-50%, -10%);
|
transform: translate(-50%, -10%);
|
||||||
|
|
||||||
|
@ -363,6 +364,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel.hidePanel {
|
.panel.hidePanel {
|
||||||
|
pointer-events: none;
|
||||||
opacity: 0.1;
|
opacity: 0.1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 }[] };
|
||||||
|
|
|
@ -148,11 +148,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