diff --git a/typescript/frontend-marios2/LICENSE b/typescript/frontend-marios2/LICENSE deleted file mode 100644 index 5bff574e2..000000000 --- a/typescript/frontend-marios2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 BloomUI - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/typescript/frontend-marios2/package-lock.json b/typescript/frontend-marios2/package-lock.json index b616b0dc0..e573f61eb 100644 --- a/typescript/frontend-marios2/package-lock.json +++ b/typescript/frontend-marios2/package-lock.json @@ -18,7 +18,9 @@ "@types/react-dom": "17.0.13", "apexcharts": "3.35.3", "axios": "^1.5.0", + "chart.js": "^4.4.0", "clsx": "1.1.1", + "cytoscape": "^3.26.0", "date-fns": "2.28.0", "history": "5.3.0", "linq-to-typescript": "^11.0.0", @@ -27,9 +29,14 @@ "prop-types": "15.8.1", "react": "17.0.2", "react-apexcharts": "1.4.0", + "react-chartjs-2": "^5.2.0", "react-custom-scrollbars-2": "4.4.0", + "react-cytoscapejs": "^2.0.0", "react-dom": "17.0.2", + "react-flow-renderer": "^10.3.17", "react-helmet-async": "1.3.0", + "react-icons": "^4.11.0", + "react-icons-converter": "^1.1.4", "react-intl": "^6.4.4", "react-router": "6.3.0", "react-router-dom": "6.3.0", @@ -1768,11 +1775,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", - "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1790,6 +1797,11 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", @@ -3196,6 +3208,11 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -4181,6 +4198,228 @@ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.1.tgz", "integrity": "sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==" }, + "node_modules/@types/d3": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.1.tgz", + "integrity": "sha512-lBpYmbHTCtFKO1DB1R7E9dXp9/g1F3JXSGOF7iKPZ+wRmYg/Q6tCRHODGOc5Qk25fJRe2PI60EDRf2HLPUncMA==", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.8.tgz", + "integrity": "sha512-2xAVyAUgaXHX9fubjcCbGAUOqYfRJN1em1EKR2HfzWBpObZhwfnZKvofTN4TplMqJdFQao61I+NVSai/vnBvDQ==" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.4.tgz", + "integrity": "sha512-ySnjI/7qm+J602VjcejXcqs1hEuu5UBbGaJGp+Cn/yKVc1iS3JueLVpToGdQsS2sqta7tqA/kG4ore/+LH90UA==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.4.tgz", + "integrity": "sha512-Kg5uIsdJNMCs5lTqeZFsTKqj9lBvpiFRDkYN3j2CDlPhonNDg9/gXVpv1E/MKh3tEqArryIj9o6RBGE/MQe+6Q==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.4.tgz", + "integrity": "sha512-p4PvN1N+7GL3Y/NI9Ug1TKwowUV6h664kmxL79ctp1HRYCk1mhP0+SXhjRsoWXCdnJfbLLLmpV99rt8dMrHrzg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.1.tgz", + "integrity": "sha512-CSAVrHAtM9wfuLJ2tpvvwCU/F22sm7rMHNN+yh9D6O6hyAms3+O0cgMpC1pm6UEUMOntuZC8bMt74PteiDUdCg==" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.4.tgz", + "integrity": "sha512-B0aeX8Xg3MNUglULxqDvlgY1SVXuN2xtEleYSAY0iMhl/SMVT7snzgAveejjwM3KaWuNXIoXEJ7dmXE8oPq/jA==", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.2.tgz", + "integrity": "sha512-WplUJ/OHU7eITneDqNnzK+2pgR+WDzUHG6XAUVo+oWHPQq74VcgUdw8a4ODweaZzF56OVYK+x9GxCyuq6hSu1A==" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.4.tgz", + "integrity": "sha512-NApHpGHRNxUy7e2Lfzl/cwOucmn4Xdx6FdmXzAoomo8T81LyGmlBjjko/vP0TVzawlvEFLDq8OCRLulW6DDzKw==" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.4.tgz", + "integrity": "sha512-/t53K1erTuUbP7WIX9SE0hlmytpTYRbIthlhbGkBHzCV5vPO++7yrk8OlisWPyIJO5TGowTmqCtGH2tokY5T/g==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.4.tgz", + "integrity": "sha512-YxfUVJ55HxR8oq88136w09mBMPNhgH7PZjteq72onWXWOohGif/cLQnQv8V4A5lEGjXF04LhwSTpmzpY9wyVyA==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.4.tgz", + "integrity": "sha512-RleYajubALkGjrvatxWhlygfvB1KNF0Uzz9guRUeeA+M/2B7l8rxObYdktaX9zU1st04lMCHjZWe4vbl+msH2Q==", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.6.tgz", + "integrity": "sha512-G9wbOvCxkNlLrppoHLZ6oFpbm3z7ibfkXwLD8g5/4Aa7iTEV0Z7TQ0OL8UxAtvdOhCa2VZcSuqn1NQqyCEqmiw==" + }, + "node_modules/@types/d3-format": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.2.tgz", + "integrity": "sha512-9oQWvKk2qVBo49FQq8yD/et8Lx0W5Ac2FdGSOUecqOFKqh0wkpyHqf9Qc7A06ftTR+Lz13Pi3jHIQis0aCueOA==" + }, + "node_modules/@types/d3-geo": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.5.tgz", + "integrity": "sha512-ysEEU93Wv9p2UZBxTK3kUP7veHgyhTA0qYtI7bxK5EMXb3JxGv0D4IH54PxprAF26n+uHci24McVmzwIdLgvgQ==", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.4.tgz", + "integrity": "sha512-wrvjpRFdmEu6yAqgjGy8MSud9ggxJj+I9XLuztLeSf/E0j0j6RQYtxH2J8U0Cfbgiw9ZDHyhpmaVuWhxscYaAQ==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.2.tgz", + "integrity": "sha512-zAbCj9lTqW9J9PlF4FwnvEjXZUy75NQqPm7DMHZXuxCFTpuTrdK2NMYGQekf4hlasL78fCYOLu4EE3/tXElwow==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz", + "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.3.tgz", + "integrity": "sha512-GDWaR+rGEk4ToLQSGugYnoh9AYYblsg/8kmdpa1KAJMwcdZ0v8rwgnldURxI5UrzxPlCPzF7by/Tjmv+Jn21Dg==" + }, + "node_modules/@types/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.5.tgz", + "integrity": "sha512-w/C++3W394MHzcLKO2kdsIn5KKNTOqeQVzyPSGPLzQbkPw/jpeaGtSRlakcKevGgGsjJxGsbqS0fPrVFDbHrDA==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.7.tgz", + "integrity": "sha512-qoj2O7KjfqCobmtFOth8FMvjwMVPUAAmn6xiUbLl1ld7vQCPgffvyV5BBcEFfqWdilAUm+3zciU/3P3vZrUMlg==" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.3.tgz", + "integrity": "sha512-cHMdIq+rhF5IVwAV7t61pcEXfEHsEsrbBUPkFGBwTXuxtTAkBBrnrNA8++6OWm3jwVsXoZYQM8NEekg6CPJ3zw==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.1.tgz", + "integrity": "sha512-5j/AnefKAhCw4HpITmLDTPlf4vhi8o/dES+zbegfPb7LaGfNyqkLxBR6E+4yvTAgnJLmhe80EXFMzUs38fw4oA==" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.1.tgz", + "integrity": "sha512-Br6EFeu9B1Zrem7KaYbr800xCmEDyq8uE60kEU8rWhC/XpFYX6ocGMZuRJDQfFCq6SyakQxNHFqIfJbFLf4x6Q==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.5.tgz", + "integrity": "sha512-dcfjP6prFxj3ziFOJrnt4W2P0oXNj/sGxsJXH8286sHtVZ4qWGbjuZj+RRCYx4YZ4C0izpeE8OqXVCtoWEtzYg==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.5.tgz", + "integrity": "sha512-mIefdTLtxuWUWTbBupCUXPAXVPmi8/Uwrq41gQpRh0rD25GMU1ku+oTELqNY2NuuiI0F3wXC5e1liBQi7YS7XQ==", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/eslint": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", @@ -4225,6 +4464,11 @@ "@types/range-parser": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.11", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.11.tgz", + "integrity": "sha512-L7A0AINMXQpVwxHJ4jxD6/XjZ4NDufaRlUJHjNIFKYUFBH1SvOW+neaqb0VTRSLW5suSrSu19ObFEFnfNcr+qg==" + }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -4360,6 +4604,11 @@ "@types/react": "*" } }, + "node_modules/@types/resize-observer-browser": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", + "integrity": "sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg==" + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -5880,6 +6129,17 @@ "node": ">=6" } }, + "node_modules/chart.js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.0.tgz", + "integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=7" + } + }, "node_modules/check-types": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", @@ -5940,6 +6200,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, + "node_modules/classcat": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.4.tgz", + "integrity": "sha512-sbpkOw6z413p+HDGcBENe498WM9woqWHiJxCq7nvmxe9WmrUmqfAcxpIwAiMtM5Q3AhYkzXcNQHqsWq0mND51g==" + }, "node_modules/clean-css": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", @@ -6688,11 +6953,119 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" }, + "node_modules/cytoscape": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.26.0.tgz", + "integrity": "sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w==", + "dependencies": { + "heap": "^0.2.6", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/d3": { "version": "3.5.17", "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", "integrity": "sha512-yFk/2idb8OHPKkbAL8QaOaqENNoMhIaSHZerk3oQsECwkObkCpJyjYwCe+OHiq6UEdhe1m8ZGARRRO3ljFjlKg==" }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -8143,6 +8516,18 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "node_modules/fast-xml-parser": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz", + "integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==", + "bin": { + "xml2js": "cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -8904,6 +9289,11 @@ "he": "bin/he" } }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" + }, "node_modules/history": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", @@ -14427,6 +14817,15 @@ "node": ">=14" } }, + "node_modules/react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-custom-scrollbars-2": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/react-custom-scrollbars-2/-/react-custom-scrollbars-2-4.4.0.tgz", @@ -14441,6 +14840,18 @@ "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/react-cytoscapejs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-cytoscapejs/-/react-cytoscapejs-2.0.0.tgz", + "integrity": "sha512-t3SSl1DQy7+JQjN+8QHi1anEJlM3i3aAeydHTsJwmjo/isyKK7Rs7oCvU6kZsB9NwZidzZQR21Vm2PcBLG/Tjg==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "cytoscape": "^3.2.19", + "react": ">=15.0.0" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -14635,6 +15046,29 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" }, + "node_modules/react-flow-renderer": { + "version": "10.3.17", + "resolved": "https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz", + "integrity": "sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ==", + "deprecated": "react-flow-renderer has been renamed to reactflow, please use this package from now on https://reactflow.dev/docs/guides/migrate-to-v11/", + "dependencies": { + "@babel/runtime": "^7.18.9", + "@types/d3": "^7.4.0", + "@types/resize-observer-browser": "^0.1.7", + "classcat": "^5.0.3", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "zustand": "^3.7.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "16 || 17 || 18", + "react-dom": "16 || 17 || 18" + } + }, "node_modules/react-helmet-async": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", @@ -14651,6 +15085,45 @@ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-icons": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", + "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-icons-converter": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/react-icons-converter/-/react-icons-converter-1.1.4.tgz", + "integrity": "sha512-cXcODFJoyO1LwHB14qUP2jDaTDF4d5xXLF+ypArFqe2YoHc+DmB3fQNh4BHndk833NnuslWVwWv4giZrivEEug==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dependencies": { + "camelcase": "6.2.0", + "fast-xml-parser": "3.19.0", + "react-icons-lib-only": "4.2.0" + } + }, + "node_modules/react-icons-converter/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-icons-lib-only": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/react-icons-lib-only/-/react-icons-lib-only-4.2.0.tgz", + "integrity": "sha512-LbP5n4hRjQPa6Fy5zqCkGV4OusvYd3x/ZawbDYlgZEjfWjQ0ry9abWp/bnQXOzJKcnsLsGq0ly9zInfjAd9BsQ==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dependencies": { + "react": ">=16.3.0" + } + }, "node_modules/react-intl": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.4.4.tgz", @@ -17720,6 +18193,22 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } } }, "dependencies": { @@ -18859,11 +19348,18 @@ } }, "@babel/runtime": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz", - "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } } }, "@babel/runtime-corejs3": { @@ -19881,6 +20377,11 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, "@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -20435,6 +20936,228 @@ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.1.tgz", "integrity": "sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==" }, + "@types/d3": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.1.tgz", + "integrity": "sha512-lBpYmbHTCtFKO1DB1R7E9dXp9/g1F3JXSGOF7iKPZ+wRmYg/Q6tCRHODGOc5Qk25fJRe2PI60EDRf2HLPUncMA==", + "requires": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "@types/d3-array": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.8.tgz", + "integrity": "sha512-2xAVyAUgaXHX9fubjcCbGAUOqYfRJN1em1EKR2HfzWBpObZhwfnZKvofTN4TplMqJdFQao61I+NVSai/vnBvDQ==" + }, + "@types/d3-axis": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.4.tgz", + "integrity": "sha512-ySnjI/7qm+J602VjcejXcqs1hEuu5UBbGaJGp+Cn/yKVc1iS3JueLVpToGdQsS2sqta7tqA/kG4ore/+LH90UA==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-brush": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.4.tgz", + "integrity": "sha512-Kg5uIsdJNMCs5lTqeZFsTKqj9lBvpiFRDkYN3j2CDlPhonNDg9/gXVpv1E/MKh3tEqArryIj9o6RBGE/MQe+6Q==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-chord": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.4.tgz", + "integrity": "sha512-p4PvN1N+7GL3Y/NI9Ug1TKwowUV6h664kmxL79ctp1HRYCk1mhP0+SXhjRsoWXCdnJfbLLLmpV99rt8dMrHrzg==" + }, + "@types/d3-color": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.1.tgz", + "integrity": "sha512-CSAVrHAtM9wfuLJ2tpvvwCU/F22sm7rMHNN+yh9D6O6hyAms3+O0cgMpC1pm6UEUMOntuZC8bMt74PteiDUdCg==" + }, + "@types/d3-contour": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.4.tgz", + "integrity": "sha512-B0aeX8Xg3MNUglULxqDvlgY1SVXuN2xtEleYSAY0iMhl/SMVT7snzgAveejjwM3KaWuNXIoXEJ7dmXE8oPq/jA==", + "requires": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "@types/d3-delaunay": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.2.tgz", + "integrity": "sha512-WplUJ/OHU7eITneDqNnzK+2pgR+WDzUHG6XAUVo+oWHPQq74VcgUdw8a4ODweaZzF56OVYK+x9GxCyuq6hSu1A==" + }, + "@types/d3-dispatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.4.tgz", + "integrity": "sha512-NApHpGHRNxUy7e2Lfzl/cwOucmn4Xdx6FdmXzAoomo8T81LyGmlBjjko/vP0TVzawlvEFLDq8OCRLulW6DDzKw==" + }, + "@types/d3-drag": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.4.tgz", + "integrity": "sha512-/t53K1erTuUbP7WIX9SE0hlmytpTYRbIthlhbGkBHzCV5vPO++7yrk8OlisWPyIJO5TGowTmqCtGH2tokY5T/g==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-dsv": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.4.tgz", + "integrity": "sha512-YxfUVJ55HxR8oq88136w09mBMPNhgH7PZjteq72onWXWOohGif/cLQnQv8V4A5lEGjXF04LhwSTpmzpY9wyVyA==" + }, + "@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, + "@types/d3-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.4.tgz", + "integrity": "sha512-RleYajubALkGjrvatxWhlygfvB1KNF0Uzz9guRUeeA+M/2B7l8rxObYdktaX9zU1st04lMCHjZWe4vbl+msH2Q==", + "requires": { + "@types/d3-dsv": "*" + } + }, + "@types/d3-force": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.6.tgz", + "integrity": "sha512-G9wbOvCxkNlLrppoHLZ6oFpbm3z7ibfkXwLD8g5/4Aa7iTEV0Z7TQ0OL8UxAtvdOhCa2VZcSuqn1NQqyCEqmiw==" + }, + "@types/d3-format": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.2.tgz", + "integrity": "sha512-9oQWvKk2qVBo49FQq8yD/et8Lx0W5Ac2FdGSOUecqOFKqh0wkpyHqf9Qc7A06ftTR+Lz13Pi3jHIQis0aCueOA==" + }, + "@types/d3-geo": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.5.tgz", + "integrity": "sha512-ysEEU93Wv9p2UZBxTK3kUP7veHgyhTA0qYtI7bxK5EMXb3JxGv0D4IH54PxprAF26n+uHci24McVmzwIdLgvgQ==", + "requires": { + "@types/geojson": "*" + } + }, + "@types/d3-hierarchy": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.4.tgz", + "integrity": "sha512-wrvjpRFdmEu6yAqgjGy8MSud9ggxJj+I9XLuztLeSf/E0j0j6RQYtxH2J8U0Cfbgiw9ZDHyhpmaVuWhxscYaAQ==" + }, + "@types/d3-interpolate": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.2.tgz", + "integrity": "sha512-zAbCj9lTqW9J9PlF4FwnvEjXZUy75NQqPm7DMHZXuxCFTpuTrdK2NMYGQekf4hlasL78fCYOLu4EE3/tXElwow==", + "requires": { + "@types/d3-color": "*" + } + }, + "@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" + }, + "@types/d3-polygon": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz", + "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==" + }, + "@types/d3-quadtree": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.3.tgz", + "integrity": "sha512-GDWaR+rGEk4ToLQSGugYnoh9AYYblsg/8kmdpa1KAJMwcdZ0v8rwgnldURxI5UrzxPlCPzF7by/Tjmv+Jn21Dg==" + }, + "@types/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==" + }, + "@types/d3-scale": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.5.tgz", + "integrity": "sha512-w/C++3W394MHzcLKO2kdsIn5KKNTOqeQVzyPSGPLzQbkPw/jpeaGtSRlakcKevGgGsjJxGsbqS0fPrVFDbHrDA==", + "requires": { + "@types/d3-time": "*" + } + }, + "@types/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==" + }, + "@types/d3-selection": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.7.tgz", + "integrity": "sha512-qoj2O7KjfqCobmtFOth8FMvjwMVPUAAmn6xiUbLl1ld7vQCPgffvyV5BBcEFfqWdilAUm+3zciU/3P3vZrUMlg==" + }, + "@types/d3-shape": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.3.tgz", + "integrity": "sha512-cHMdIq+rhF5IVwAV7t61pcEXfEHsEsrbBUPkFGBwTXuxtTAkBBrnrNA8++6OWm3jwVsXoZYQM8NEekg6CPJ3zw==", + "requires": { + "@types/d3-path": "*" + } + }, + "@types/d3-time": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.1.tgz", + "integrity": "sha512-5j/AnefKAhCw4HpITmLDTPlf4vhi8o/dES+zbegfPb7LaGfNyqkLxBR6E+4yvTAgnJLmhe80EXFMzUs38fw4oA==" + }, + "@types/d3-time-format": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.1.tgz", + "integrity": "sha512-Br6EFeu9B1Zrem7KaYbr800xCmEDyq8uE60kEU8rWhC/XpFYX6ocGMZuRJDQfFCq6SyakQxNHFqIfJbFLf4x6Q==" + }, + "@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, + "@types/d3-transition": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.5.tgz", + "integrity": "sha512-dcfjP6prFxj3ziFOJrnt4W2P0oXNj/sGxsJXH8286sHtVZ4qWGbjuZj+RRCYx4YZ4C0izpeE8OqXVCtoWEtzYg==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-zoom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.5.tgz", + "integrity": "sha512-mIefdTLtxuWUWTbBupCUXPAXVPmi8/Uwrq41gQpRh0rD25GMU1ku+oTELqNY2NuuiI0F3wXC5e1liBQi7YS7XQ==", + "requires": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "@types/eslint": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", @@ -20479,6 +21202,11 @@ "@types/range-parser": "*" } }, + "@types/geojson": { + "version": "7946.0.11", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.11.tgz", + "integrity": "sha512-L7A0AINMXQpVwxHJ4jxD6/XjZ4NDufaRlUJHjNIFKYUFBH1SvOW+neaqb0VTRSLW5suSrSu19ObFEFnfNcr+qg==" + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -20614,6 +21342,11 @@ "@types/react": "*" } }, + "@types/resize-observer-browser": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", + "integrity": "sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg==" + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -21750,6 +22483,14 @@ "resolved": "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz", "integrity": "sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==" }, + "chart.js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.0.tgz", + "integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==", + "requires": { + "@kurkle/color": "^0.3.0" + } + }, "check-types": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", @@ -21795,6 +22536,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, + "classcat": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.4.tgz", + "integrity": "sha512-sbpkOw6z413p+HDGcBENe498WM9woqWHiJxCq7nvmxe9WmrUmqfAcxpIwAiMtM5Q3AhYkzXcNQHqsWq0mND51g==" + }, "clean-css": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", @@ -22329,11 +23075,86 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" }, + "cytoscape": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.26.0.tgz", + "integrity": "sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w==", + "requires": { + "heap": "^0.2.6", + "lodash": "^4.17.21" + } + }, "d3": { "version": "3.5.17", "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", "integrity": "sha512-yFk/2idb8OHPKkbAL8QaOaqENNoMhIaSHZerk3oQsECwkObkCpJyjYwCe+OHiq6UEdhe1m8ZGARRRO3ljFjlKg==" }, + "d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" + }, + "d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==" + }, + "d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + } + }, + "d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" + }, + "d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "requires": { + "d3-color": "1 - 3" + } + }, + "d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==" + }, + "d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" + }, + "d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "requires": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + } + }, + "d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + } + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -23400,6 +24221,11 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "fast-xml-parser": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz", + "integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==" + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -23939,6 +24765,11 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" + }, "history": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", @@ -27812,6 +28643,12 @@ "whatwg-fetch": "^3.6.2" } }, + "react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "requires": {} + }, "react-custom-scrollbars-2": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/react-custom-scrollbars-2/-/react-custom-scrollbars-2-4.4.0.tgz", @@ -27822,6 +28659,14 @@ "raf": "^3.1.0" } }, + "react-cytoscapejs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-cytoscapejs/-/react-cytoscapejs-2.0.0.tgz", + "integrity": "sha512-t3SSl1DQy7+JQjN+8QHi1anEJlM3i3aAeydHTsJwmjo/isyKK7Rs7oCvU6kZsB9NwZidzZQR21Vm2PcBLG/Tjg==", + "requires": { + "prop-types": "^15.8.1" + } + }, "react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -27961,6 +28806,21 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" }, + "react-flow-renderer": { + "version": "10.3.17", + "resolved": "https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz", + "integrity": "sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ==", + "requires": { + "@babel/runtime": "^7.18.9", + "@types/d3": "^7.4.0", + "@types/resize-observer-browser": "^0.1.7", + "classcat": "^5.0.3", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "zustand": "^3.7.2" + } + }, "react-helmet-async": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", @@ -27973,6 +28833,37 @@ "shallowequal": "^1.1.0" } }, + "react-icons": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", + "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==", + "requires": {} + }, + "react-icons-converter": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/react-icons-converter/-/react-icons-converter-1.1.4.tgz", + "integrity": "sha512-cXcODFJoyO1LwHB14qUP2jDaTDF4d5xXLF+ypArFqe2YoHc+DmB3fQNh4BHndk833NnuslWVwWv4giZrivEEug==", + "requires": { + "camelcase": "6.2.0", + "fast-xml-parser": "3.19.0", + "react-icons-lib-only": "4.2.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + } + } + }, + "react-icons-lib-only": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/react-icons-lib-only/-/react-icons-lib-only-4.2.0.tgz", + "integrity": "sha512-LbP5n4hRjQPa6Fy5zqCkGV4OusvYd3x/ZawbDYlgZEjfWjQ0ry9abWp/bnQXOzJKcnsLsGq0ly9zInfjAd9BsQ==", + "requires": { + "react": ">=16.3.0" + } + }, "react-intl": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.4.4.tgz", @@ -30302,6 +31193,12 @@ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" } } + }, + "zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "requires": {} } } } diff --git a/typescript/frontend-marios2/package.json b/typescript/frontend-marios2/package.json index f89037602..d0c1bf1ae 100644 --- a/typescript/frontend-marios2/package.json +++ b/typescript/frontend-marios2/package.json @@ -14,7 +14,9 @@ "@types/react-dom": "17.0.13", "apexcharts": "3.35.3", "axios": "^1.5.0", + "chart.js": "^4.4.0", "clsx": "1.1.1", + "cytoscape": "^3.26.0", "date-fns": "2.28.0", "history": "5.3.0", "linq-to-typescript": "^11.0.0", @@ -23,9 +25,14 @@ "prop-types": "15.8.1", "react": "17.0.2", "react-apexcharts": "1.4.0", + "react-chartjs-2": "^5.2.0", "react-custom-scrollbars-2": "4.4.0", + "react-cytoscapejs": "^2.0.0", "react-dom": "17.0.2", + "react-flow-renderer": "^10.3.17", "react-helmet-async": "1.3.0", + "react-icons": "^4.11.0", + "react-icons-converter": "^1.1.4", "react-intl": "^6.4.4", "react-router": "6.3.0", "react-router-dom": "6.3.0", diff --git a/typescript/frontend-marios2/src/App.tsx b/typescript/frontend-marios2/src/App.tsx index 5b1956f85..605cafc58 100644 --- a/typescript/frontend-marios2/src/App.tsx +++ b/typescript/frontend-marios2/src/App.tsx @@ -15,13 +15,13 @@ import SidebarLayout from './layouts/SidebarLayout'; import { TokenContext } from './contexts/tokenContext'; import ResetPassword from './components/ResetPassword'; import ForgotPassword from './components/ForgotPassword'; +import InstallationTabs from './content/dashboards/Installations/index'; +import routes from 'src/Resources/routes.json'; +import './App.css'; function App() { - //const content = useRoutes(router); - const context = useContext(UserContext); const { currentUser, setUser } = context; - const tokencontext = useContext(TokenContext); const { token, setNewToken, removeToken } = tokencontext; const [forgotPassword, setForgotPassword] = useState(false); @@ -79,14 +79,14 @@ function App() { lazy(() => import('src/content/pages/Status/Maintenance')) ); - const routes: RouteObject[] = [ + const routesArray: RouteObject[] = [ { path: '', element: , children: [ { path: '/', - element: + element: }, { path: 'status', @@ -118,39 +118,6 @@ function App() { element: } ] - }, - { - path: 'ResetPassword', - element: - }, - { - path: 'Login', - element: - }, - { - path: 'installations', - element: ( - - ), - - children: [ - { - path: '', - element: - } - ] - }, - { - path: 'users', - element: ( - - ), - children: [ - { - path: '', - element: - } - ] } ]; if (forgotPassword) { @@ -189,7 +156,7 @@ function App() { > - {routes.map((route, index) => ( + {routesArray.map((route, index) => ( {route.children && route.children.map((childRoute, childIndex) => ( @@ -201,6 +168,23 @@ function App() { ))} ))} + + } + > + } + /> + } /> + }> + }> + diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx index 6f3c02dbc..36e301b70 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/FlatInstallationView.tsx @@ -1,8 +1,7 @@ -import React, { useContext, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { Card, CircularProgress, - Divider, Grid, Table, TableBody, @@ -18,26 +17,44 @@ import Installation from './Installation'; import CancelIcon from '@mui/icons-material/Cancel'; import { LogContext } from 'src/contexts/LogContextProvider'; import { FormattedMessage } from 'react-intl'; +import { useNavigate } from 'react-router-dom'; +import routes from 'src/Resources/routes.json'; interface FlatInstallationViewProps { installations: I_Installation[]; } const FlatInstallationView = (props: FlatInstallationViewProps) => { - const [selectedInstallation, setSelectedInstallation] = useState(-1); - const selectedBulkActions = selectedInstallation === -1 ? false : true; const [isRowHovered, setHoveredRow] = useState(-1); const logContext = useContext(LogContext); const { getStatus } = logContext; + const navigate = useNavigate(); + + const searchParams = new URLSearchParams(location.search); + const installationId = parseInt(searchParams.get('installation')); + const [selectedInstallation, setSelectedInstallation] = useState(-1); const handleSelectOneInstallation = (installationID: number): void => { if (selectedInstallation != installationID) { setSelectedInstallation(installationID); + navigate( + routes.installations + + routes.list + + '?installation=' + + installationID.toString(), + { + replace: true + } + ); } else { setSelectedInstallation(-1); } }; + useEffect(() => { + setSelectedInstallation(installationId); + }, [installationId]); + const theme = useTheme(); const findInstallation = (id: number) => { @@ -54,20 +71,27 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { return ( - + - - + + + + + + @@ -76,7 +100,7 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { {props.installations.map((installation) => { const isInstallationSelected = - installation.id === selectedInstallation ? true : false; + installation.id === selectedInstallation; const status = getStatus(installation.id); @@ -100,31 +124,58 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { onMouseEnter={() => handleRowMouseEnter(installation.id)} onMouseLeave={() => handleRowMouseLeave()} > - {installation.name} + {installation.location} + + + + {installation.country} + + + + + + {installation.orderNumbers} + + +
{ style={{ width: '20px', height: '20px', + marginLeft: '2px', borderRadius: '50%', backgroundColor: status === 2 @@ -182,15 +234,11 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => { - {props.installations.map((installation) => ( ))} diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/Installation.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/Installation.tsx index ce95baa30..097a50a97 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/Installation.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/Installation.tsx @@ -25,45 +25,56 @@ import Access from '../ManageAccess/Access'; import Log from 'src/content/dashboards/Log/Log'; import { TimeSpan, UnixTime } from 'src/dataCache/time'; import { FetchResult } from 'src/dataCache/dataCache'; -import { DataRecord } from 'src/dataCache/data'; -import { S3Access } from 'src/dataCache/S3/S3Access'; -import { parseCsv } from 'src/content/dashboards/Log/graph.util'; -import { I_S3Credentials, Notification } from 'src/interfaces/S3Types'; +import { + extractValues, + TopologyValues +} from 'src/content/dashboards/Log/graph.util'; +import { Notification } from 'src/interfaces/S3Types'; import { LogContext } from 'src/contexts/LogContextProvider'; -import LiveView from '../LiveView/LiveView'; +import Topology from '../Topology/Topology'; import { FormattedMessage } from 'react-intl'; +import Overview from '../Overview/overview'; +import Configuration from '../Configuration/Configuration'; +import { fetchData } from 'src/content/dashboards/Installations/fetchData'; interface singleInstallationProps { current_installation: I_Installation; type: string; - style?: React.CSSProperties; } function Installation(props: singleInstallationProps) { const tabs = [ { - value: 'installation', - label: ( - - ) + value: 'live', + label: }, + { + value: 'overview', + label: + }, + , { value: 'manage', - label: ( - - ) - }, - { - value: 'live', - label: + label: }, { value: 'log', label: + }, + { + value: 'information', + label: + }, + + { + value: 'configuration', + label: ( + + ) } ]; const theme = useTheme(); - const [currentTab, setCurrentTab] = useState(tabs[0].value); + const [currentTab, setCurrentTab] = useState('live'); const [formValues, setFormValues] = useState(props.current_installation); const requiredFields = ['name', 'region', 'location', 'country']; const context = useContext(UserContext); @@ -87,37 +98,9 @@ function Installation(props: singleInstallationProps) { const [errorLoadingS3Data, setErrorLoadingS3Data] = useState(false); const logContext = useContext(LogContext); const { installationStatus, handleLogWarningOrError, getStatus } = logContext; - - const fetchData = ( - timestamp: UnixTime, - s3Credentials: I_S3Credentials - ): Promise> => { - const s3Path = `${timestamp.ticks}.csv`; - if (s3Credentials && s3Credentials.s3Bucket) { - const s3Access = new S3Access( - s3Credentials.s3Bucket, - s3Credentials.s3Region, - s3Credentials.s3Provider, - s3Credentials.s3Key, - s3Credentials.s3Secret - ); - return s3Access - .get(s3Path) - .then(async (r) => { - if (r.status === 404) { - return Promise.resolve(FetchResult.notAvailable); - } else if (r.status === 200) { - const text = await r.text(); - return parseCsv(text); - } else { - return Promise.resolve(FetchResult.notAvailable); - } - }) - .catch((e) => { - return Promise.resolve(FetchResult.tryLater); - }); - } - }; + const searchParams = new URLSearchParams(location.search); + const installationId = parseInt(searchParams.get('installation')); + const [values, setValues] = useState(null); if (formValues == undefined) { return null; @@ -156,77 +139,127 @@ function Installation(props: singleInstallationProps) { return true; }; + const S3data = { + s3Region: props.current_installation.s3Region, + s3Provider: props.current_installation.s3Provider, + s3Key: props.current_installation.s3Key, + s3Secret: props.current_installation.s3Secret + }; + + const s3Bucket = + props.current_installation.id.toString() + + '-3e5b3069-214a-43ee-8d85-57d72000c19d'; + + const s3Credentials = { s3Bucket, ...S3data }; + useEffect(() => { + let isMounted = true; setFormValues(props.current_installation); - const S3data = { - s3Region: props.current_installation.s3Region, - s3Provider: props.current_installation.s3Provider, - s3Key: props.current_installation.s3Key, - s3Secret: props.current_installation.s3Secret - }; - - const s3Bucket = - props.current_installation.id.toString() + - '-3e5b3069-214a-43ee-8d85-57d72000c19d'; - const s3Credentials = { s3Bucket, ...S3data }; - setErrorLoadingS3Data(false); - const interval = setInterval(() => { + const fetchDataPeriodically = async () => { const now = UnixTime.now().earlier(TimeSpan.fromSeconds(20)); + const date = now.toDate(); - fetchData(now, s3Credentials) - .then((res) => { + try { + const res = await fetchData(now, s3Credentials); + + if (installationId == 2) { console.log('Fetched data from unix timestamp ' + now); - const newWarnings: Notification[] = []; - const newErrors: Notification[] = []; - if (res === FetchResult.notAvailable || res == FetchResult.tryLater) { - setErrorLoadingS3Data(true); - handleLogWarningOrError(props.current_installation.id, -1); - } else { - setErrorLoadingS3Data(false); - for (const key in res) { - if ( - (res.hasOwnProperty(key) && - key.includes('/Alarms') && - res[key].value != '') || - (key.includes('/Warnings') && res[key].value != '') - ) { - if (key.includes('/Warnings')) { - newWarnings.push({ - key, - value: res[key].value.toString() - }); - } else if (key.includes('/Alarms')) { - newErrors.push({ - key, - value: res[key].value.toString() - }); - } + } + if (!isMounted) { + return; + } + + const newWarnings: Notification[] = []; + const newErrors: Notification[] = []; + + if (res === FetchResult.notAvailable || res === FetchResult.tryLater) { + setErrorLoadingS3Data(true); + handleLogWarningOrError(props.current_installation.id, -1); + } else { + setErrorLoadingS3Data(false); + setValues( + extractValues({ + time: now, + value: res + }) + ); + + for (const key in res) { + if ( + (res.hasOwnProperty(key) && + key.includes('/Alarms') && + res[key].value !== '') || + (key.includes('/Warnings') && res[key].value !== '') + ) { + if (key.includes('/Warnings')) { + newWarnings.push({ + device: key.substring(1, key.lastIndexOf('/')), + description: res[key].value.toString(), + date: + date.getFullYear() + + '-' + + date.getMonth() + + '-' + + date.getDay(), + time: + date.getHours() + + ':' + + date.getMinutes() + + ':' + + date.getSeconds() + }); + } else if (key.includes('/Alarms')) { + newErrors.push({ + device: key.substring(1, key.lastIndexOf('/')), + description: res[key].value.toString(), + date: + date.getFullYear() + + '-' + + date.getMonth() + + '-' + + date.getDay(), + time: + date.getHours() + + ':' + + date.getMinutes() + + ':' + + date.getSeconds() + }); } } - setWarnings(newWarnings); - setErrors(newErrors); - - if (newErrors.length > 0) { - handleLogWarningOrError(props.current_installation.id, 2); - } else if (newWarnings.length > 0) { - handleLogWarningOrError(props.current_installation.id, 1); - } else { - handleLogWarningOrError(props.current_installation.id, 0); - } } - }) - .catch((err) => { - setErrorLoadingS3Data(true); - }); - }, 2000); + + setWarnings(newWarnings); + setErrors(newErrors); + + if (newErrors.length > 0) { + handleLogWarningOrError(props.current_installation.id, 2); + } else if (newWarnings.length > 0) { + handleLogWarningOrError(props.current_installation.id, 1); + } else { + handleLogWarningOrError(props.current_installation.id, 0); + } + } + } catch (err) { + setErrorLoadingS3Data(true); + } + }; + + const interval = setInterval(fetchDataPeriodically, 2000); + + // Cleanup function to cancel interval and update isMounted when unmounted + return () => { + isMounted = false; + clearInterval(interval); + }; }, []); - return ( - <> - + if (installationId == props.current_installation.id) { + return ( + - {currentTab === 'installation' && ( + {currentTab === 'information' && (
+ + {currentUser.hasWriteAccess && ( + <> +
+ +
+ +
+ +
+ +
+ +
+ + )} +
setError(false)} // Set error state to false on click + onClick={() => setError(false)} sx={{ marginLeft: '4px' }} > @@ -448,6 +519,12 @@ function Installation(props: singleInstallationProps) { )} + {currentTab === 'overview' && ( + + )} + {currentTab === 'configuration' && currentUser.hasWriteAccess && ( + + )} {currentTab === 'manage' && currentUser.hasWriteAccess && ( )} - {currentTab === 'live' && ( - - )} + {currentTab === 'live' && } {currentTab === 'log' && ( - - ); + ); + } else { + return null; + } } export default Installation; diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/InstallationSearch.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/InstallationSearch.tsx index 1c6d65faa..2af85562f 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/InstallationSearch.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/InstallationSearch.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { FormControl, Grid, @@ -9,32 +9,42 @@ import { import { InstallationsContext } from 'src/contexts/InstallationsContextProvider'; import SearchTwoToneIcon from '@mui/icons-material/SearchTwoTone'; import FlatInstallationView from 'src/content/dashboards/Installations/FlatInstallationView'; +import LogContextProvider from 'src/contexts/LogContextProvider'; function InstallationSearch() { const theme = useTheme(); const [searchTerm, setSearchTerm] = useState(''); - const { data, fetchAllInstallations } = useContext(InstallationsContext); + const { installations, fetchAllInstallations } = + useContext(InstallationsContext); + + const searchParams = new URLSearchParams(location.search); + const installationId = parseInt(searchParams.get('installation')); useEffect(() => { fetchAllInstallations(); }, []); - const [filteredData, setFilteredData] = useState(data); + const [filteredData, setFilteredData] = useState(installations); useEffect(() => { - const filtered = data.filter( + const filtered = installations.filter( (item) => item.name.toLowerCase().includes(searchTerm.toLowerCase()) || item.location.toLowerCase().includes(searchTerm.toLowerCase()) ); setFilteredData(filtered); - }, [searchTerm, data]); + }, [searchTerm, installations]); return ( <> - - - + + + - + + + ); } diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx index 72834586f..7a892956f 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx @@ -1,25 +1,30 @@ -import { ChangeEvent, useState } from 'react'; +import React, { ChangeEvent, useEffect, useState } from 'react'; import Footer from 'src/components/Footer'; -import { Box, Card, Container, Grid, Tab, Tabs, useTheme } from '@mui/material'; -import InstallationsContextProvider from 'src/contexts/InstallationsContextProvider'; -import InstallationSearch from './InstallationSearch'; +import { Card, Container, Grid, Tab, Tabs, useTheme } from '@mui/material'; import ListIcon from '@mui/icons-material/List'; import AccountTreeIcon from '@mui/icons-material/AccountTree'; -import InstallationTree from '../Tree/InstallationTree'; import { TabsContainerWrapper } from 'src/layouts/TabsContainerWrapper'; import UsersContextProvider from 'src/contexts/UsersContextProvider'; -import LogContextProvider from '../../../contexts/LogContextProvider'; +import { + Link, + Route, + Routes, + useLocation, + useNavigate +} from 'react-router-dom'; +import FlatView from './flatView'; +import TreeView from '../Tree/treeView'; +import routes from 'src/Resources/routes.json'; function InstallationTabs() { const theme = useTheme(); - - const [currentTab, setCurrentTab] = useState('flat'); + const location = useLocation(); + const navigate = useNavigate(); const tabs = [ { - value: 'flat', + value: 'list', label: 'Flat view', - icon: , - component: {} + icon: }, { value: 'tree', @@ -27,9 +32,25 @@ function InstallationTabs() { icon: } ]; + const [currentTab, setCurrentTab] = useState('list'); + + useEffect(() => { + //console.log(location.pathname); + if ( + location.pathname === '/installations' || + location.pathname === '/installations/' + ) { + navigate(routes.installations + routes.list, { + replace: true + }); + } else if (location.pathname === '/installations/tree') { + setCurrentTab('tree'); + } + }, [location.pathname, navigate]); const handleTabsChange = (_event: ChangeEvent<{}>, value: string): void => { setCurrentTab(value); + navigate(value); }; return ( @@ -45,40 +66,30 @@ function InstallationTabs() { indicatorColor="primary" > {tabs.map((tab) => ( - + ))} - - - - - {currentTab === 'tree' && ( - <> - - - - - - - )} - {currentTab === 'flat' && ( - - - - - - )} - - - - + + + + } /> + } /> + + +
diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx index 02885e928..3678a1258 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/installationForm.tsx @@ -13,6 +13,7 @@ import { Close as CloseIcon } from '@mui/icons-material'; import { I_Installation } from 'src/interfaces/InstallationTypes'; import { TokenContext } from 'src/contexts/tokenContext'; import { InstallationsContext } from 'src/contexts/InstallationsContextProvider'; +import { FormattedMessage } from 'react-intl'; interface installationFormProps { cancel: () => void; @@ -96,7 +97,12 @@ function installationForm(props: installationFormProps) { >
+ } name="name" value={formValues.name} onChange={handleChange} @@ -107,7 +113,7 @@ function installationForm(props: installationFormProps) {
} name="region" value={formValues.region} onChange={handleChange} @@ -118,7 +124,9 @@ function installationForm(props: installationFormProps) {
+ } name="location" value={formValues.location} onChange={handleChange} @@ -130,7 +138,9 @@ function installationForm(props: installationFormProps) {
+ } name="country" value={formValues.country} onChange={handleChange} @@ -141,7 +151,12 @@ function installationForm(props: installationFormProps) {
+ } name="orderNumbers" value={formValues.orderNumbers} onChange={handleChange} @@ -164,7 +179,7 @@ function installationForm(props: installationFormProps) { }} disabled={!areRequiredFieldsFilled()} > - Submit + {loading && ( @@ -195,11 +210,14 @@ function installationForm(props: installationFormProps) { alignItems: 'center' }} > - An error has occurred + setError(false)} // Set error state to false on click + onClick={() => setError(false)} sx={{ marginLeft: '4px' }} > diff --git a/typescript/frontend-marios2/src/content/dashboards/LiveView/LiveView.tsx b/typescript/frontend-marios2/src/content/dashboards/LiveView/LiveView.tsx deleted file mode 100644 index 898dd8cd7..000000000 --- a/typescript/frontend-marios2/src/content/dashboards/LiveView/LiveView.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import React, { Fragment } from 'react'; -import { - Alert, - Container, - Divider, - Grid, - IconButton, - ListItem, - useTheme -} from '@mui/material'; -import ListItemAvatar from '@mui/material/ListItemAvatar'; -import Avatar from '@mui/material/Avatar'; -import ListItemText from '@mui/material/ListItemText'; -import WarningIcon from '@mui/icons-material/Warning'; -import ErrorIcon from '@mui/icons-material/Error'; -import Typography from '@mui/material/Typography'; -import { Notification } from 'src/interfaces/S3Types'; - -interface LiveViewProps { - warnings: Notification[]; - errors: Notification[]; - errorLoadingS3Data: boolean; -} - -function LiveView(props: LiveViewProps) { - const theme = useTheme(); - - return ( - - - - {props.errors.length > 0 && - props.errors.map((error) => { - return ( - - - - - - - - - {'Error from: ' + - error.key + - ' device: ' + - error.value} - - } - /> - - - - ); - })} - {!props.errorLoadingS3Data && props.errors.length == 0 && ( - - There are no errors - - - )} - - - {props.errors.length > 0 && props.warnings.length > 0 && ( - - )} - - - {props.errorLoadingS3Data && ( - - Cannot load logging data - - - )} - {props.warnings.length > 0 && - props.warnings.map((warning) => { - return ( - - - - - - - - - {'Warning from: ' + - warning.key + - ' device: ' + - warning.value} - - } - /> - - - - ); - })} - - {!props.errorLoadingS3Data && props.warnings.length == 0 && ( - - There are no warnings - - - )} - - - - ); -} - -export default LiveView; diff --git a/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx b/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx index 6c4b55c35..d28063310 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx @@ -1,20 +1,24 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import { Alert, + Card, Container, Divider, Grid, IconButton, - ListItem, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, useTheme } from '@mui/material'; -import ListItemAvatar from '@mui/material/ListItemAvatar'; -import Avatar from '@mui/material/Avatar'; -import ListItemText from '@mui/material/ListItemText'; import WarningIcon from '@mui/icons-material/Warning'; -import ErrorIcon from '@mui/icons-material/Error'; import Typography from '@mui/material/Typography'; import { Notification } from 'src/interfaces/S3Types'; +import { FormattedMessage } from 'react-intl'; +import ErrorIcon from '@mui/icons-material/Error'; interface LogProps { warnings: Notification[]; @@ -29,43 +33,171 @@ function Log(props: LogProps) { - {props.errors.length > 0 && - props.errors.map((error) => { - return ( - - - - - 0 || props.warnings.length > 0) && ( + + + +
+ + + + + + + + + + - - - - {'Error from: ' + - error.key + - ' device: ' + - error.value} - - } - /> - - - - ); - })} + + + + + + + + + + + {props.errors.map((error, index) => { + return ( + + + + + + + {error.device} + + + + + {error.description} + + + + + {error.date} + + + + + {error.time} + + + + ); + })} + + {props.warnings.map((warning, index) => { + return ( + + + + + + + {warning.device} + + + + + {warning.description} + + + + + {warning.date} + + + + + {warning.time} + + + + ); + })} + +
+
+
+ )} + {!props.errorLoadingS3Data && props.errors.length == 0 && ( - There are no errors + )}
- - {props.errors.length > 0 && props.warnings.length > 0 && ( - - )} - + {props.errorLoadingS3Data && ( - Cannot load logging data + )} - {props.warnings.length > 0 && - props.warnings.map((warning) => { - return ( - - - - - - - - - {'Warning from: ' + - warning.key + - ' device: ' + - warning.value} - - } - /> - - - - ); - })} {!props.errorLoadingS3Data && props.warnings.length == 0 && ( - There are no warnings + { }) .reduce((acc, current) => ({ ...acc, ...current }), {} as DataRecord); }; + +export interface I_BoxDataValue { + unit: string; + value: string | number; +} + +export type BoxData = { + label: string; + values: I_BoxDataValue[]; +}; + +export type TopologyValues = { + grid: BoxData; + gridToAcInConnection: BoxData; + gridBus: BoxData; + islandBus: BoxData; + dcBus: BoxData; + dcBusToDcDcConnection: BoxData; + dcDCToBatteryConnection: BoxData; + battery: BoxData; + dcBusToLoadOnDcConnection: BoxData; + islandBusToLoadOnIslandBusConnection: BoxData; + gridBusToPvOnGridbusConnection: BoxData; + gridBusToLoadOnGridBusConnection: BoxData; + inverter: BoxData; + dcDc: BoxData; + islandBusToInverter: BoxData; + inverterToDcBus: BoxData; + gridBusToIslandBusConnection: BoxData; + pvOnDcBusToDcBusConnection: BoxData; + pvOnIslandBusToIslandBusConnection: BoxData; + minimumSoC: BoxData; + installedDcDcPower: BoxData; + gridSetPoint: BoxData; + maximumDischargePower: BoxData; + calibrationChargeForced: BoxData; +}; + +type TopologyPaths = { [key in keyof TopologyValues]: string[] }; + +export const topologyPaths: TopologyPaths = { + grid: [ + '/GridMeter/Ac/L1/Power/Active', + '/GridMeter/Ac/L2/Power/Active', + '/GridMeter/Ac/L3/Power/Active' + ], + gridToAcInConnection: ['/GridMeter/Ac/Power/Active'], + + gridBus: [ + '/GridMeter/Ac/L1/Power/Active', + '/GridMeter/Ac/L2/Power/Active', + '/GridMeter/Ac/L3/Power/Active' + ], + gridBusToPvOnGridbusConnection: ['/PvOnAcGrid/Power/Active'], + + gridBusToLoadOnGridBusConnection: ['/LoadOnAcGrid/Power/Active'], + gridBusToIslandBusConnection: ['/AcGridToAcIsland/Power/Active'], + + islandBus: [ + '/AcDc/Ac/L1/Power/Active', + '/AcDc/Ac/L2/Power/Active', + '/AcDc/Ac/L3/Power/Active' + ], + islandBusToLoadOnIslandBusConnection: ['/LoadOnAcIsland/Power/Active'], + islandBusToInverter: ['/AcDc/Dc/Power'], + pvOnIslandBusToIslandBusConnection: ['/PvOnAcIsland/Power/Active'], + + inverter: [ + '/AcDc/Devices/1/Status/Ac/Power/Active', + '/AcDc/Devices/2/Status/Ac/Power/Active', + '/AcDc/Devices/3/Status/Ac/Power/Active', + '/AcDc/Devices/4/Status/Ac/Power/Active' + ], + inverterToDcBus: ['/AcDc/Dc/Power'], + + dcBus: ['/DcDc/Dc/Link/Voltage'], + dcBusToDcDcConnection: ['/DcDc/Dc/Link/Power'], + pvOnDcBusToDcBusConnection: ['/PvOnDc/Dc/Power'], + dcBusToLoadOnDcConnection: ['/LoadOnDc/Power'], + + dcDc: ['/DcDc/Dc/Battery/Voltage'], + + dcDCToBatteryConnection: ['/DcDc/Dc/Link/Power'], + battery: [ + '/Battery/Soc', + '/Battery/Dc/Voltage', + '/Battery/Dc/Current', + '/Battery/Temperature', + '/Battery/Devices/1/Dc/Voltage', + '/Battery/Devices/2/Dc/Voltage', + '/Battery/Devices/3/Dc/Voltage', + '/Battery/Devices/4/Dc/Voltage', + '/Battery/Devices/5/Dc/Voltage', + '/Battery/Devices/6/Dc/Voltage', + '/Battery/Devices/7/Dc/Voltage', + '/Battery/Devices/8/Dc/Voltage', + '/Battery/Devices/9/Dc/Voltage', + '/Battery/Devices/10/Dc/Voltage' + ], + + minimumSoC: ['/Config/MinSoc'], + installedDcDcPower: ['/DcDc/SystemControl/TargetSlave'], + gridSetPoint: ['/Config/GridSetPoint'], + maximumDischargePower: ['/Config/MaxBatteryDischargingCurrent'], + calibrationChargeForced: ['/Config/ForceCalibrationCharge'] +}; + +export const extractValues = ( + timeSeriesData: DataPoint +): TopologyValues | null => { + const extractedValues: TopologyValues = {} as TopologyValues; + + for (const topologyKey of Object.keys(topologyPaths)) { + const paths = topologyPaths[topologyKey]; + let topologyValues: { unit: string; value: string | number }[] = []; + //console.log('paths is ', paths); + + // Check if any of the specified paths exist in the dataRecord + for (const path of paths) { + //console.log(' path is ', path); + if (timeSeriesData.value.hasOwnProperty(path)) { + //console.log('matching path is ', path); + //console.log(timeSeriesData.value[path]); + topologyValues.push({ + unit: timeSeriesData.value[path].unit, + value: timeSeriesData.value[path].value + }); + } + } + if (topologyValues.length > 0) { + extractedValues[topologyKey] = { + label: topologyPaths[topologyKey as keyof TopologyValues][0] + .split('/') + .pop(), + values: topologyValues + }; + } + } + + return extractedValues; +}; + +export const getHighestConnectionValue = (values: TopologyValues) => + Object.keys(values) + .filter((value) => value.includes('Connection')) + .reduce((acc, curr) => { + const value = Math.abs( + values[curr as keyof TopologyValues].values[0].value as number + ); + return value > acc ? value : acc; + }, 0); + +export const getAmount = ( + highestConnectionValue: number, + values: I_BoxDataValue[] +) => { + return Math.abs(values[0].value as number) / highestConnectionValue; +}; + +export const createTimes = ( + range: TimeRange, + numberOfNodes: number +): UnixTime[] => { + const oneSpan = range.duration.divide(numberOfNodes); + const roundedRange = TimeRange.fromTimes( + range.start.round(oneSpan), + range.end.round(oneSpan) + ); + return roundedRange.sample(oneSpan); +}; diff --git a/typescript/frontend-marios2/src/content/dashboards/ManageAccess/Access.tsx b/typescript/frontend-marios2/src/content/dashboards/ManageAccess/Access.tsx index 3e97e8ec8..f6d2dceab 100644 --- a/typescript/frontend-marios2/src/content/dashboards/ManageAccess/Access.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/ManageAccess/Access.tsx @@ -17,7 +17,7 @@ import { import { TokenContext } from 'src/contexts/tokenContext'; import { UserContext } from 'src/contexts/userContext'; import { I_Folder, I_Installation } from 'src/interfaces/InstallationTypes'; -import axiosConfig from '../../../Resources/axiosConfig'; +import axiosConfig from 'src/Resources/axiosConfig'; import ListItemAvatar from '@mui/material/ListItemAvatar'; import Avatar from '@mui/material/Avatar'; import ListItemText from '@mui/material/ListItemText'; @@ -26,7 +26,8 @@ import PersonIcon from '@mui/icons-material/Person'; import Button from '@mui/material/Button'; import { Close as CloseIcon } from '@mui/icons-material'; import { UsersContext } from 'src/contexts/UsersContextProvider'; -import { AccessContext } from '../../../contexts/AccessContextProvider'; +import { AccessContext } from 'src/contexts/AccessContextProvider'; +import { FormattedMessage } from 'react-intl'; interface AccessProps { currentResource: I_Folder | I_Installation; @@ -157,15 +158,32 @@ function Access(props: AccessProps) { if (NotGrantedAccessUsers.length > 0) { setError(true); - setErrorMessage( - 'Unable to grant access to: ' + NotGrantedAccessUsers.join(', ') - ); + + const message = + ( + + ).props.defaultMessage + + ' ' + + NotGrantedAccessUsers.join(', '); + + setErrorMessage(message); } if (grantedAccessUsers.length > 0) { - setUpdatedMessage( - 'Granted access to users: ' + grantedAccessUsers.join(', ') - ); + const message = + ( + + ).props.defaultMessage + + ' ' + + grantedAccessUsers.join(', '); + setUpdatedMessage(message); + setUpdated(true); setTimeout(() => { @@ -248,7 +266,10 @@ function Access(props: AccessProps) { //backgroundColor: 'white' }} > - Select users + - Submit + @@ -304,7 +313,10 @@ function userForm(props: userFormProps) { fontSize: 14 }} > - Grant access to installations + @@ -375,7 +387,7 @@ function userForm(props: userFormProps) { }} disabled={!areRequiredFieldsFilled()} > - Submit + {loading && ( @@ -410,7 +422,7 @@ function userForm(props: userFormProps) { setError(false)} // Set error state to false on click + onClick={() => setError(false)} sx={{ marginLeft: '4px' }} > diff --git a/typescript/frontend-marios2/src/contexts/AccessContextProvider.tsx b/typescript/frontend-marios2/src/contexts/AccessContextProvider.tsx index 585ea7f74..60e2e2735 100644 --- a/typescript/frontend-marios2/src/contexts/AccessContextProvider.tsx +++ b/typescript/frontend-marios2/src/contexts/AccessContextProvider.tsx @@ -1,4 +1,4 @@ -import { +import React, { createContext, ReactNode, useCallback, @@ -11,6 +11,7 @@ import { I_UserWithInheritedAccess, InnovEnergyUser } from '../interfaces/UserTypes'; +import { FormattedMessage } from 'react-intl'; interface AccessContextProviderProps { usersWithDirectAccess: InnovEnergyUser[]; @@ -82,7 +83,15 @@ const AccessContextProvider = ({ children }: { children: ReactNode }) => { }) .catch((error) => { setError(true); - setErrorMessage('Unable to load data'); + + const message = ( + + ).props.defaultMessage; + + setErrorMessage(message); }); }, [] @@ -99,7 +108,13 @@ const AccessContextProvider = ({ children }: { children: ReactNode }) => { }) .catch((error) => { setError(true); - setErrorMessage('Unable to load data'); + const message = ( + + ).props.defaultMessage; + setErrorMessage(message); }); }, [] @@ -127,7 +142,19 @@ const AccessContextProvider = ({ children }: { children: ReactNode }) => { resourceType, current_ResourceId ); - setUpdatedMessage('Revoked access from user: ' + name); + + const message = + ( + + ).props.defaultMessage + + ' ' + + name; + + setUpdatedMessage(message); + setUpdated(true); setTimeout(() => { setUpdated(false); @@ -136,7 +163,14 @@ const AccessContextProvider = ({ children }: { children: ReactNode }) => { }) .catch((error) => { setError(true); - setErrorMessage('Unable to revoke access'); + const message = ( + + ).props.defaultMessage; + + setErrorMessage(message); }); }, [] diff --git a/typescript/frontend-marios2/src/contexts/InstallationsContextProvider.tsx b/typescript/frontend-marios2/src/contexts/InstallationsContextProvider.tsx index 8fddbfeee..cd773e16b 100644 --- a/typescript/frontend-marios2/src/contexts/InstallationsContextProvider.tsx +++ b/typescript/frontend-marios2/src/contexts/InstallationsContextProvider.tsx @@ -11,7 +11,8 @@ import { I_Folder, I_Installation } from 'src/interfaces/InstallationTypes'; import { TokenContext } from './tokenContext'; interface I_InstallationContextProviderProps { - data: I_Installation[]; + installations: I_Installation[]; + foldersAndInstallations: I_Installation[]; fetchAllInstallations: () => Promise; fetchAllFoldersAndInstallations: () => Promise; createInstallation: (value: Partial) => Promise; @@ -24,14 +25,14 @@ interface I_InstallationContextProviderProps { setUpdated: (value: boolean) => void; deleteInstallation: (value: I_Installation, view: string) => Promise; createFolder: (value: Partial) => Promise; - updateFolder: (value: I_Folder) => Promise; deleteFolder: (value: I_Folder) => Promise; } export const InstallationsContext = createContext({ - data: [], + installations: [], + foldersAndInstallations: [], fetchAllInstallations: () => Promise.resolve(), fetchAllFoldersAndInstallations: () => Promise.resolve(), createInstallation: () => Promise.resolve(), @@ -44,7 +45,6 @@ export const InstallationsContext = setUpdated: () => {}, deleteInstallation: () => Promise.resolve(), createFolder: () => Promise.resolve(), - updateFolder: () => Promise.resolve(), deleteFolder: () => Promise.resolve() }); @@ -54,7 +54,8 @@ const InstallationsContextProvider = ({ }: { children: ReactNode; }) => { - const [data, setData] = useState([]); + const [installations, setInstallations] = useState([]); + const [foldersAndInstallations, setFoldersAndInstallations] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(false); const [updated, setUpdated] = useState(false); @@ -67,7 +68,7 @@ const InstallationsContextProvider = ({ axiosConfig .get('/GetAllInstallations', {}) .then((res) => { - setData(res.data); + setInstallations(res.data); }) .catch((err: AxiosError) => { if (err.response && err.response.status == 401) { @@ -80,14 +81,14 @@ const InstallationsContextProvider = ({ return axiosConfig .get('/GetAllFoldersAndInstallations') .then((res) => { - setData(res.data); + setFoldersAndInstallations(res.data); }) .catch((err) => { if (err.response && err.response.status == 401) { removeToken(); } }); - }, [setData]); + }, []); const createInstallation = useCallback( async (formValues: Partial) => { @@ -235,7 +236,8 @@ const InstallationsContextProvider = ({ return ( ( undefined ); -// Create a UserContextProvider component export const LogContextProvider = ({ children }: { children: ReactNode }) => { const [installationStatus, setInstallationStatus] = useState< Record >({}); + const BUFFER_LENGTH = 5; + const handleLogWarningOrError = (installation_id: number, value: number) => { setInstallationStatus((prevStatus) => { const newStatus = { ...prevStatus }; @@ -24,16 +25,23 @@ export const LogContextProvider = ({ children }: { children: ReactNode }) => { newStatus[installation_id] = []; } newStatus[installation_id].unshift(value); - newStatus[installation_id] = newStatus[installation_id].slice(0, 5); + newStatus[installation_id] = newStatus[installation_id].slice( + 0, + BUFFER_LENGTH + ); return newStatus; }); }; const getStatus = (installationId: number) => { let status; + if (!installationStatus.hasOwnProperty(installationId)) { status = -2; } else { + if (installationId === 2) { + console.log(installationStatus[2]); + } if (installationStatus[installationId][0] == -1) { let i = 0; for (i; i < installationStatus[installationId].length; i++) { diff --git a/typescript/frontend-marios2/src/dataCache/dataCache.ts b/typescript/frontend-marios2/src/dataCache/dataCache.ts index e57b25291..7b446cd1b 100644 --- a/typescript/frontend-marios2/src/dataCache/dataCache.ts +++ b/typescript/frontend-marios2/src/dataCache/dataCache.ts @@ -8,6 +8,7 @@ import {RecordSeries} from './data'; import {isUndefined, Maybe} from './utils/maybe'; import {isNumber} from './utils/runtimeTypeChecking'; import {I_CsvEntry} from 'src/content/dashboards/Log/graph.util'; +import {I_S3Credentials} from '../interfaces/S3Types'; export const FetchResult = { notAvailable: 'N/A', @@ -33,7 +34,10 @@ function reverseBits(x: number): number { } export default class DataCache> { - readonly _fetch: (t: UnixTime) => Promise>; + readonly _fetch: ( + t: UnixTime, + s3Credentials: I_S3Credentials + ) => Promise>; public readonly gotData: Observable; @@ -41,16 +45,23 @@ export default class DataCache> { private readonly resolution: TimeSpan; + private readonly s3Credentials: I_S3Credentials; + private readonly fetchQueue = createDispatchQueue(6); private readonly fetching: Set = new Set(); constructor( - fetch: (t: UnixTime) => Promise>, - resolution: TimeSpan + fetch: ( + t: UnixTime, + s3Credentials: I_S3Credentials + ) => Promise>, + resolution: TimeSpan, + s3Credentials: I_S3Credentials ) { this._fetch = fetch; this.resolution = resolution; + this.s3Credentials = s3Credentials; this.gotData = new Subject(); } @@ -71,7 +82,7 @@ export default class DataCache> { const t = time.ticks; const node = this.cache.find(t); - if (node.index !== t) this.fetchData(time); + if (node.index !== t) this.fetchData(time, this.s3Credentials); } } @@ -82,7 +93,7 @@ export default class DataCache> { const node = this.cache.find(t); if (node.index === t) return node.value; - if (fetch) this.fetchData(time); + if (fetch) this.fetchData(time, this.s3Credentials); return this.interpolate(node, t); } @@ -130,7 +141,7 @@ export default class DataCache> { return interpolated as T; } - private fetchData(time: UnixTime) { + private fetchData(time: UnixTime, s3Credentials: I_S3Credentials) { const t = time.ticks; if (this.fetching.has(t)) @@ -160,7 +171,7 @@ export default class DataCache> { (this.gotData as Subject).next(time); }; - return this._fetch(time) + return this._fetch(time, s3Credentials) .then( (d) => onSuccess(d), (f) => onFailure(f) diff --git a/typescript/frontend-marios2/src/interfaces/S3Types.tsx b/typescript/frontend-marios2/src/interfaces/S3Types.tsx index 3849aca09..4f04962b6 100644 --- a/typescript/frontend-marios2/src/interfaces/S3Types.tsx +++ b/typescript/frontend-marios2/src/interfaces/S3Types.tsx @@ -7,6 +7,8 @@ export interface I_S3Credentials { } export interface Notification { - key: string; - value: string; + device: string; + description: string; + date: string; + time: string; } diff --git a/typescript/frontend-marios2/src/lang/de.json b/typescript/frontend-marios2/src/lang/de.json index edd4d8bc2..e7bf215c7 100644 --- a/typescript/frontend-marios2/src/lang/de.json +++ b/typescript/frontend-marios2/src/lang/de.json @@ -16,7 +16,6 @@ "german": "Deutsch", "groupTabs": "Gruppen", "groupTree": "Gruppenbaum", - "information": "Information", "inheritedAccess": "Vererbter Zugriff von", "installation": "Installation", "installationTabs": "Installationen", @@ -48,5 +47,24 @@ "live": "Live Übertragung", "deleteInstallation": "Installation löschen", "errorOccured": "Ein Fehler ist aufgetreten", - "successfullyUpdated": "Erfolgreich aktualisiert" + "successfullyUpdated": "Erfolgreich aktualisiert", + "grantAccess": "Zugriff gewähren", + "UserswithDirectAccess": "Benutzer mit direktem Zugriff", + "UserswithInheritedAccess": "Benutzer mit geerbtem Zugriff", + "noerrors": "Es liegen keine Fehler vor", + "nowarnings": "Es gibt keine Warnungen", + "noUsersWithDirectAccessToThis": "Keine Benutzer mit direktem Zugriff darauf ", + "selectUsers": "Wählen Sie Benutzer aus", + "cancel": "Stornieren", + "addNewFolder": "Neuen Ordner hinzufügen", + "addNewInstallation": "Neue Installation hinzufügen", + "deleteFolder": "Lösche Ordner", + "grantAccessToFolders": "Gewähren Sie Zugriff auf Ordner", + "grantAccessToInstallations": "Gewähren Sie Zugriff auf Installationen", + "cannotloadloggingdata": "Protokollierungsdaten können nicht geladen werden", + "grantedAccessToUsers": "Benutzern Zugriff gewährt: ", + "unableToGrantAccess": "Der Zugriff auf kann nicht gewährt werden: ", + "unableToLoadData": "Daten können nicht geladen werden", + "unableToRevokeAccess": "Der Zugriff kann nicht widerrufen werden", + "revokedAccessFromUser": "Zugriff vom Benutzer widerrufen: " } diff --git a/typescript/frontend-marios2/src/lang/en.json b/typescript/frontend-marios2/src/lang/en.json index 03f70214f..71756e085 100644 --- a/typescript/frontend-marios2/src/lang/en.json +++ b/typescript/frontend-marios2/src/lang/en.json @@ -1,8 +1,6 @@ { - "liveView": "Live view", "allInstallations": "All installations", "applyChanges": "Apply changes", - "deleteInstallation": "Delete Installation", "country": "Country", "customerName": "Customer name", "english": "English", @@ -53,5 +51,24 @@ "live": "Live View", "deleteInstallation": "Delete Installation", "errorOccured": "An error has occurred", - "successfullyUpdated": "Successfully updated" + "successfullyUpdated": "Successfully updated", + "grantAccess": "Grant Access", + "UserswithDirectAccess": "Users with Direct Access", + "UserswithInheritedAccess": "Users with Inherited Access", + "noerrors": "There are no errors", + "nowarnings": "There are no warnings", + "noUsersWithDirectAccessToThis": "No users with direct access to this ", + "selectUsers": "Select Users", + "cancel": "Cancel", + "addNewFolder": "Add new Folder", + "addNewInstallation": "Add new Installation", + "deleteFolder": "Delete Folder", + "grantAccessToFolders": "Grant Access to Folders", + "grantAccessToInstallations": "Grant Access to Installations", + "cannotloadloggingdata": "Cannot load logging data", + "grantedAccessToUsers": "Granted access to users: ", + "unableToGrantAccess": "Unable to grant access to: ", + "unableToLoadData": "Unable to load data", + "unableToRevokeAccess": "Unable to revoke access", + "revokedAccessFromUser": "Revoked access from user: " } diff --git a/typescript/frontend-marios2/src/lang/fr.json b/typescript/frontend-marios2/src/lang/fr.json index 0f80c8463..b063dddb6 100644 --- a/typescript/frontend-marios2/src/lang/fr.json +++ b/typescript/frontend-marios2/src/lang/fr.json @@ -16,7 +16,6 @@ "german": "Allemand", "groupTabs": "Onglets de groupe", "groupTree": "Arbre de groupe", - "information": "Informations", "inheritedAccess": "Accès hérité de", "installation": "Installation", "installationTabs": "Onglets d'installation", @@ -48,5 +47,24 @@ "live": "Diffusion en direct", "deleteInstallation": "Supprimer l'installation", "errorOccured": "Une erreur est survenue", - "successfullyUpdated": "Mise à jour réussie" + "successfullyUpdated": "Mise à jour réussie", + "grantAccess": "Accorder l'accès", + "UserswithDirectAccess": "Utilisateurs avec accès direct", + "UserswithInheritedAccess": "Utilisateurs avec accès hérité", + "noerrors": "Il n'y a pas d'erreurs", + "nowarnings": "Il n'y a aucun avertissement", + "noUsersWithDirectAccessToThis": "Aucun utilisateur ayant un accès direct à ceci ", + "selectUsers": "Sélectionnez les utilisateurs", + "cancel": "Annuler", + "addNewFolder": "Ajouter un nouveau dossier", + "addNewInstallation": "Ajouter une nouvelle installation", + "deleteFolder": "Supprimer le dossier", + "grantAccessToFolders": "Accorder l'accès aux dossiers", + "grantAccessToInstallations": "Accorder l'accès aux installations", + "cannotloadloggingdata": "Impossible de charger les données de journalisation", + "grantedAccessToUsers": "Accès accordé aux utilisateurs: ", + "unableToGrantAccess": "Impossible d'accorder l'accès à: ", + "unableToLoadData": "Impossible de charger les données", + "unableToRevokeAccess": "Impossible de révoquer l'accès", + "revokedAccessFromUser": "Accès révoqué de l'utilisateur: " } diff --git a/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx b/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx index 4a50ceaad..b4982a0b8 100644 --- a/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx +++ b/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx @@ -4,8 +4,7 @@ import { ListItem, ListItemText, Menu, - MenuItem, - Switch + MenuItem } from '@mui/material'; import { useContext, useRef, useState } from 'react'; import { styled } from '@mui/material/styles'; @@ -98,6 +97,11 @@ function HeaderMenu(props: HeaderButtonsProps) { setOpen(false); }; + const handleLanguageSelect = (language) => { + props.onSelectLanguage(language); + handleClose(); + }; + return ( <> - - props.onSelectLanguage('en')}> + handleLanguageSelect('en')}> English - props.onSelectLanguage('de')}> + handleLanguageSelect('de')}> German - props.onSelectLanguage('fr')}> + handleLanguageSelect('fr')}> French diff --git a/typescript/frontend-marios2/src/layouts/SidebarLayout/Sidebar/index.tsx b/typescript/frontend-marios2/src/layouts/SidebarLayout/Sidebar/index.tsx index 9d4832a66..5dd05300b 100644 --- a/typescript/frontend-marios2/src/layouts/SidebarLayout/Sidebar/index.tsx +++ b/typescript/frontend-marios2/src/layouts/SidebarLayout/Sidebar/index.tsx @@ -18,7 +18,7 @@ import SidebarMenu from './SidebarMenu'; const SidebarWrapper = styled(Box)( ({ theme }) => ` width: ${theme.sidebar.width}; - min-width: ${theme.sidebar.width}; + min-width: "${theme.sidebar.width}"; color: ${theme.colors.alpha.trueWhite[70]}; position: relative; z-index: 7; @@ -64,8 +64,7 @@ function Sidebar() { alt="innovenergy logo" style={{ maxWidth: '150px', // Maximum width for the image - maxHeight: '150px', // Maximum height for the image - marginLeft: '50px' // Adjust the value as needed + maxHeight: '150px' // Maximum height for the image }} /> diff --git a/typescript/frontend-marios2/src/layouts/TabsContainerWrapper.tsx b/typescript/frontend-marios2/src/layouts/TabsContainerWrapper.tsx index b54f1924b..45963184a 100644 --- a/typescript/frontend-marios2/src/layouts/TabsContainerWrapper.tsx +++ b/typescript/frontend-marios2/src/layouts/TabsContainerWrapper.tsx @@ -1,4 +1,5 @@ -import { Box, styled } from '@mui/material'; +import { Box, Card, styled } from '@mui/material'; +import Avatar from '@mui/material/Avatar'; export const TabsContainerWrapper = styled(Box)( ({ theme }) => ` @@ -81,3 +82,61 @@ export const TabsContainerWrapper = styled(Box)( } ` ); + +export const AvatarWrapper = styled(Avatar)( + ({ theme }) => ` + display: flex; + align-items: center; + justify-content: center; + border-radius: 60px; + margin-top: -5px; + height: ${theme.spacing(3.5)}; + width: ${theme.spacing(3.5)}; + background: ${ + theme.palette.mode === 'dark' + ? theme.colors.alpha.trueWhite[30] + : '#ffffff' + }; + + img { + background: ${theme.colors.alpha.trueWhite[100]}; + display: block; + border-radius: inherit; + height: ${theme.spacing(4.5)}; + width: ${theme.spacing(4.5)}; + } +` +); + +export const AvatarAddWrapper = styled(Avatar)( + ({ theme }) => ` + background: ${theme.colors.alpha.black[10]}; + color: ${theme.colors.primary.main}; + width: ${theme.spacing(8)}; + height: ${theme.spacing(8)}; +` +); + +export const CardAddAction = styled(Card)( + ({ theme }) => ` + border: ${theme.colors.primary.main} dashed 1px; + height: 100%; + color: ${theme.colors.primary.main}; + transition: ${theme.transitions.create(['all'])}; + + .MuiCardActionArea-root { + height: 100%; + justify-content: center; + align-items: center; + display: flex; + } + + .MuiTouchRipple-root { + opacity: .2; + } + + &:hover { + border-color: ${theme.colors.alpha.black[70]}; + } +` +); diff --git a/typescript/frontend-marios2/src/theme/schemes/PureLightTheme.ts b/typescript/frontend-marios2/src/theme/schemes/PureLightTheme.ts index 34d971901..4e4c2a62b 100644 --- a/typescript/frontend-marios2/src/theme/schemes/PureLightTheme.ts +++ b/typescript/frontend-marios2/src/theme/schemes/PureLightTheme.ts @@ -240,7 +240,7 @@ export const PureLightTheme = createTheme({ menuItemHeadingColor: colors.layout.sidebar.menuItemHeadingColor, boxShadow: '2px 0 3px rgba(159, 162, 191, .18), 1px 0 1px rgba(159, 162, 191, 0.32)', - width: '290px' + width: '200px' }, header: { height: '80px',