add example of daterangepicker, fix bugs
This commit is contained in:
parent
0533a86b11
commit
9844c7a0ad
|
@ -15,6 +15,8 @@
|
|||
"@mui/icons-material": "^5.11.0",
|
||||
"@mui/lab": "^5.0.0-alpha.120",
|
||||
"@mui/material": "^5.11.7",
|
||||
"@mui/x-date-pickers": "^6.5.0",
|
||||
"@mui/x-date-pickers-pro": "^6.5.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
|
@ -26,6 +28,7 @@
|
|||
"axios": "^1.3.1",
|
||||
"chart.js": "^4.2.1",
|
||||
"css-loader": "^6.7.3",
|
||||
"dayjs": "^1.11.7",
|
||||
"formik": "^2.2.9",
|
||||
"linq-to-typescript": "^11.0.0",
|
||||
"package.json": "^2.0.1",
|
||||
|
@ -3091,9 +3094,9 @@
|
|||
"integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.20.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
|
||||
"integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
|
||||
"version": "7.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
|
||||
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
},
|
||||
|
@ -5015,13 +5018,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@mui/utils": {
|
||||
"version": "5.11.9",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz",
|
||||
"integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==",
|
||||
"version": "5.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.1.tgz",
|
||||
"integrity": "sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||
"@types/react-is": "^18.2.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0"
|
||||
},
|
||||
|
@ -5036,6 +5039,148 @@
|
|||
"react": "^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/x-date-pickers": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.5.0.tgz",
|
||||
"integrity": "sha512-dRCO1mzHjfOqsa4LdKxiXQnV0cuGiAkliyxSDCdRn6clK2WdF9Oj+1+4Mkx7fcJA61SV1eP4Yg29s0/VDsZKZw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.12.3",
|
||||
"@types/react-transition-group": "^4.4.6",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-transition-group": "^4.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mui"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@mui/base": "^5.0.0-alpha.87",
|
||||
"@mui/material": "^5.8.6",
|
||||
"@mui/system": "^5.8.0",
|
||||
"date-fns": "^2.25.0",
|
||||
"date-fns-jalali": "^2.13.0-0",
|
||||
"dayjs": "^1.10.7",
|
||||
"luxon": "^3.0.2",
|
||||
"moment": "^2.29.4",
|
||||
"moment-hijri": "^2.1.2",
|
||||
"moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0",
|
||||
"react": "^17.0.2 || ^18.0.0",
|
||||
"react-dom": "^17.0.2 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@emotion/styled": {
|
||||
"optional": true
|
||||
},
|
||||
"date-fns": {
|
||||
"optional": true
|
||||
},
|
||||
"date-fns-jalali": {
|
||||
"optional": true
|
||||
},
|
||||
"dayjs": {
|
||||
"optional": true
|
||||
},
|
||||
"luxon": {
|
||||
"optional": true
|
||||
},
|
||||
"moment": {
|
||||
"optional": true
|
||||
},
|
||||
"moment-hijri": {
|
||||
"optional": true
|
||||
},
|
||||
"moment-jalaali": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/x-date-pickers-pro": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-6.5.0.tgz",
|
||||
"integrity": "sha512-3pwBsLe0xdtVJ+trFo872KkVE+0uOz5MXGihvsQf5CaEic3SWj/CX0g+k9rcZYndpntteghkMp5UnbSn/trTGA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.12.3",
|
||||
"@mui/x-date-pickers": "6.5.0",
|
||||
"@mui/x-license-pro": "6.0.4",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-transition-group": "^4.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@mui/base": "^5.0.0-alpha.87",
|
||||
"@mui/material": "^5.8.6",
|
||||
"@mui/system": "^5.8.0",
|
||||
"date-fns": "^2.25.0",
|
||||
"date-fns-jalali": "^2.13.0-0",
|
||||
"dayjs": "^1.10.7",
|
||||
"luxon": "^3.0.2",
|
||||
"moment": "^2.29.4",
|
||||
"moment-hijri": "^2.1.2",
|
||||
"moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0",
|
||||
"react": "^17.0.2 || ^18.0.0",
|
||||
"react-dom": "^17.0.2 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@emotion/styled": {
|
||||
"optional": true
|
||||
},
|
||||
"date-fns": {
|
||||
"optional": true
|
||||
},
|
||||
"date-fns-jalali": {
|
||||
"optional": true
|
||||
},
|
||||
"dayjs": {
|
||||
"optional": true
|
||||
},
|
||||
"luxon": {
|
||||
"optional": true
|
||||
},
|
||||
"moment": {
|
||||
"optional": true
|
||||
},
|
||||
"moment-hijri": {
|
||||
"optional": true
|
||||
},
|
||||
"moment-jalaali": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/x-license-pro": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-6.0.4.tgz",
|
||||
"integrity": "sha512-4E9TRDb0Enc7OngSz/Lx34++WdiD95tsYuFCdhicq/FImahgLEg799qUj+il5UQJ5mxQP/pKdVqv0T8FZg2JPA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.11.13"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^17.0.2 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
|
||||
"version": "5.1.1-v1",
|
||||
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
|
||||
|
@ -6398,9 +6543,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/react-is": {
|
||||
"version": "17.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
|
||||
"integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ==",
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -6435,9 +6580,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
"integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
|
||||
"version": "4.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
|
||||
"integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==",
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -9648,6 +9793,11 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.7",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
|
||||
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
|
||||
},
|
||||
"node_modules/debounce": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
||||
|
@ -26996,9 +27146,9 @@
|
|||
"integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.20.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
|
||||
"integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
|
||||
"version": "7.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
|
||||
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
}
|
||||
|
@ -28294,17 +28444,53 @@
|
|||
"requires": {}
|
||||
},
|
||||
"@mui/utils": {
|
||||
"version": "5.11.9",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz",
|
||||
"integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==",
|
||||
"version": "5.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.1.tgz",
|
||||
"integrity": "sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.13",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||
"@types/react-is": "^18.2.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"@mui/x-date-pickers": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.5.0.tgz",
|
||||
"integrity": "sha512-dRCO1mzHjfOqsa4LdKxiXQnV0cuGiAkliyxSDCdRn6clK2WdF9Oj+1+4Mkx7fcJA61SV1eP4Yg29s0/VDsZKZw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.12.3",
|
||||
"@types/react-transition-group": "^4.4.6",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-transition-group": "^4.4.5"
|
||||
}
|
||||
},
|
||||
"@mui/x-date-pickers-pro": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-6.5.0.tgz",
|
||||
"integrity": "sha512-3pwBsLe0xdtVJ+trFo872KkVE+0uOz5MXGihvsQf5CaEic3SWj/CX0g+k9rcZYndpntteghkMp5UnbSn/trTGA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.12.3",
|
||||
"@mui/x-date-pickers": "6.5.0",
|
||||
"@mui/x-license-pro": "6.0.4",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-transition-group": "^4.4.5"
|
||||
}
|
||||
},
|
||||
"@mui/x-license-pro": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-6.0.4.tgz",
|
||||
"integrity": "sha512-4E9TRDb0Enc7OngSz/Lx34++WdiD95tsYuFCdhicq/FImahgLEg799qUj+il5UQJ5mxQP/pKdVqv0T8FZg2JPA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.11.13"
|
||||
}
|
||||
},
|
||||
"@nicolo-ribaudo/eslint-scope-5-internals": {
|
||||
"version": "5.1.1-v1",
|
||||
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
|
||||
|
@ -29391,9 +29577,9 @@
|
|||
}
|
||||
},
|
||||
"@types/react-is": {
|
||||
"version": "17.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz",
|
||||
"integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==",
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -29428,9 +29614,9 @@
|
|||
}
|
||||
},
|
||||
"@types/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
"integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
|
||||
"version": "4.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
|
||||
"integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
@ -31904,6 +32090,11 @@
|
|||
"whatwg-url": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"dayjs": {
|
||||
"version": "1.11.7",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
|
||||
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
|
||||
},
|
||||
"debounce": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
"@mui/icons-material": "^5.11.0",
|
||||
"@mui/lab": "^5.0.0-alpha.120",
|
||||
"@mui/material": "^5.11.7",
|
||||
"@mui/x-date-pickers": "^6.5.0",
|
||||
"@mui/x-date-pickers-pro": "^6.5.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
|
@ -21,6 +23,7 @@
|
|||
"axios": "^1.3.1",
|
||||
"chart.js": "^4.2.1",
|
||||
"css-loader": "^6.7.3",
|
||||
"dayjs": "^1.11.7",
|
||||
"formik": "^2.2.9",
|
||||
"linq-to-typescript": "^11.0.0",
|
||||
"package.json": "^2.0.1",
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -24,7 +24,7 @@
|
|||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<title>Innovenergy</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
|
|
@ -66,8 +66,12 @@ const InstallationList = (props: InstallationListProps) => {
|
|||
overflow: "auto",
|
||||
py: 0,
|
||||
mt: 1,
|
||||
height: "80vh",
|
||||
maxHeight: "70vh",
|
||||
height:
|
||||
routeMatch?.pattern.path ===
|
||||
routes.installations + routes.list + routes.log + ":id"
|
||||
? "130px"
|
||||
: "80vh",
|
||||
}}
|
||||
component="nav"
|
||||
aria-labelledby="nested-list-subheader"
|
||||
|
|
|
@ -10,8 +10,12 @@ import InstallationList from "./InstallationList";
|
|||
import Installation from "./Installation";
|
||||
import CheckboxTree from "./Log/CheckboxTree";
|
||||
import LogContextProvider from "../Context/LogContextProvider";
|
||||
import useRouteMatch from "../../hooks/useRouteMatch";
|
||||
|
||||
const Installations = () => {
|
||||
const routeMatch = useRouteMatch([
|
||||
routes.installations + routes.list + routes.log + ":id",
|
||||
]);
|
||||
return (
|
||||
<InstallationContextProvider>
|
||||
<LogContextProvider>
|
||||
|
@ -20,6 +24,7 @@ const Installations = () => {
|
|||
<SearchSidebar
|
||||
id="installations-search-sidebar"
|
||||
listComponent={InstallationList}
|
||||
height={routeMatch ? "200px" : undefined}
|
||||
/>
|
||||
<CheckboxTree />
|
||||
</Grid>
|
||||
|
|
|
@ -31,10 +31,16 @@ const CheckboxTree = () => {
|
|||
const handleCheckChildren = (children: TreeElement[], checked?: boolean) => {
|
||||
if (children.length > 0) {
|
||||
children.forEach((child) => {
|
||||
setCheckedToggles((prevState) => ({
|
||||
...prevState,
|
||||
[child.id]: !checked,
|
||||
}));
|
||||
setCheckedToggles((prevState) => {
|
||||
console.log("setChecked", {
|
||||
...prevState,
|
||||
[child.id]: !checked,
|
||||
});
|
||||
return {
|
||||
...prevState,
|
||||
[child.id]: !checked,
|
||||
};
|
||||
});
|
||||
if (child.children.length > 0) {
|
||||
handleCheckChildren(child.children, checked);
|
||||
}
|
||||
|
@ -57,6 +63,7 @@ const CheckboxTree = () => {
|
|||
event.stopPropagation();
|
||||
};
|
||||
const renderTree = (data: TreeElement[]): ReactNode => {
|
||||
console.log("checkedToggles", checkedToggles);
|
||||
return data.map((element) => {
|
||||
const checked = checkedToggles?.[element.id];
|
||||
const splitName = element.name.split("/");
|
||||
|
@ -84,23 +91,27 @@ const CheckboxTree = () => {
|
|||
);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Divider sx={{ mt: 2 }} />
|
||||
{toggles !== null && routeMatch !== null && (
|
||||
<TreeView
|
||||
aria-label="rich object"
|
||||
defaultCollapseIcon={<ExpandMoreIcon />}
|
||||
defaultExpandIcon={<ChevronRightIcon />}
|
||||
sx={{
|
||||
height: 480,
|
||||
flexGrow: 1,
|
||||
overflow: "auto",
|
||||
overflowX: "hidden",
|
||||
}}
|
||||
>
|
||||
{renderTree(toggles)}
|
||||
</TreeView>
|
||||
<>
|
||||
<Divider sx={{ mt: 2 }} />
|
||||
<TreeView
|
||||
aria-label="rich object"
|
||||
defaultCollapseIcon={<ExpandMoreIcon />}
|
||||
defaultExpandIcon={<ChevronRightIcon />}
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
overflow: "auto",
|
||||
overflowX: "hidden",
|
||||
position: ["sticky", "-webkit-sticky"],
|
||||
top: 1,
|
||||
}}
|
||||
>
|
||||
{renderTree(toggles)}
|
||||
</TreeView>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import * as React from "react";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
||||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
||||
import { StaticDateRangePicker } from "@mui/x-date-pickers-pro/StaticDateRangePicker";
|
||||
import { PickersShortcutsItem } from "@mui/x-date-pickers/PickersShortcuts";
|
||||
import { DateRange } from "@mui/x-date-pickers-pro";
|
||||
|
||||
const shortcutsItems: PickersShortcutsItem<DateRange<Dayjs>>[] = [
|
||||
{
|
||||
label: "This Week",
|
||||
getValue: () => {
|
||||
const today = dayjs();
|
||||
return [today.startOf("week"), today.endOf("week")];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Last Week",
|
||||
getValue: () => {
|
||||
const today = dayjs();
|
||||
const prevWeek = today.subtract(7, "day");
|
||||
return [prevWeek.startOf("week"), prevWeek.endOf("week")];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Last 7 Days",
|
||||
getValue: () => {
|
||||
const today = dayjs();
|
||||
return [today.subtract(7, "day"), today];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Current Month",
|
||||
getValue: () => {
|
||||
const today = dayjs();
|
||||
return [today.startOf("month"), today.endOf("month")];
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Next Month",
|
||||
getValue: () => {
|
||||
const today = dayjs();
|
||||
const startOfNextMonth = today.endOf("month").add(1, "day");
|
||||
return [startOfNextMonth, startOfNextMonth.endOf("month")];
|
||||
},
|
||||
},
|
||||
{ label: "Reset", getValue: () => [null, null] },
|
||||
];
|
||||
|
||||
export default function BasicRangeShortcuts() {
|
||||
return (
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<StaticDateRangePicker
|
||||
slotProps={{
|
||||
shortcuts: {
|
||||
items: shortcutsItems,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
);
|
||||
}
|
|
@ -2,11 +2,7 @@ import React from "react";
|
|||
import ScalarGraph from "./ScalarGraph";
|
||||
|
||||
const Log = () => {
|
||||
return (
|
||||
<>
|
||||
<ScalarGraph />
|
||||
</>
|
||||
);
|
||||
return <ScalarGraph />;
|
||||
};
|
||||
|
||||
export default Log;
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import Plot from "react-plotly.js";
|
||||
import { RecordSeries } from "../../../dataCache/data";
|
||||
import {
|
||||
GraphCoordinates,
|
||||
GraphData,
|
||||
flattenBarGraphData,
|
||||
createTimes,
|
||||
flattenToggles,
|
||||
insertTreeElements,
|
||||
isNumeric,
|
||||
isText,
|
||||
parseCsv,
|
||||
stringToColor,
|
||||
transformToBarGraphData,
|
||||
|
@ -18,28 +16,17 @@ import { BehaviorSubject, startWith, throttleTime, withLatestFrom } from "rxjs";
|
|||
import { S3Access } from "../../../dataCache/S3/S3Access";
|
||||
import DataCache, { FetchResult } from "../../../dataCache/dataCache";
|
||||
import { LogContext } from "../../Context/LogContextProvider";
|
||||
import { TreeElement, ToggleElement } from "./CheckboxTree";
|
||||
import { TreeElement } from "./CheckboxTree";
|
||||
import { isDefined } from "../../../dataCache/utils/maybe";
|
||||
|
||||
import { Data } from "plotly.js";
|
||||
|
||||
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);
|
||||
};
|
||||
import { Data, Layout } from "plotly.js";
|
||||
import { Alert } from "@mui/material";
|
||||
|
||||
const NUMBER_OF_NODES = 100;
|
||||
|
||||
const ScalarGraph = () => {
|
||||
const timeRange = createTimes(
|
||||
UnixTime.now() /* .fromTicks(1682085650) */
|
||||
.earlier(TimeSpan.fromDays(2))
|
||||
.rangeBefore(TimeSpan.fromDays(4)),
|
||||
NUMBER_OF_NODES
|
||||
);
|
||||
|
@ -78,19 +65,12 @@ const ScalarGraph = () => {
|
|||
const toggleValues = timeSeries.find((timeStamp) => timeStamp.value);
|
||||
if (toggles === null && toggleValues && toggleValues.value) {
|
||||
const treeElements = Object.keys(toggleValues.value)
|
||||
.map((path) => {
|
||||
return path
|
||||
.map((path) =>
|
||||
path
|
||||
.split("/")
|
||||
.map(
|
||||
(split, i) =>
|
||||
"/" +
|
||||
path
|
||||
.split("/")
|
||||
.slice(1, i + 1)
|
||||
.join("/")
|
||||
)
|
||||
.slice(1);
|
||||
})
|
||||
.map((_, i, arr) => `/${arr.slice(1, i + 1).join("/")}`)
|
||||
.slice(1)
|
||||
)
|
||||
.reduce(
|
||||
(children, path) => insertTreeElements(children, path),
|
||||
[] as TreeElement[]
|
||||
|
@ -139,6 +119,7 @@ const ScalarGraph = () => {
|
|||
transformedObject[key] = {
|
||||
x: [],
|
||||
y: [],
|
||||
marker: { color: stringToColor(key) },
|
||||
};
|
||||
}
|
||||
transformedObject[key].x.push(
|
||||
|
@ -147,7 +128,10 @@ const ScalarGraph = () => {
|
|||
transformedObject[key].y.push(item.value?.[key]);
|
||||
});
|
||||
}
|
||||
if (plotTitles.length === 0) {
|
||||
if (
|
||||
plotTitles.length === 0 &&
|
||||
Object.keys(transformedObject).length > 0
|
||||
) {
|
||||
setPlotTitles(Object.keys(transformedObject));
|
||||
}
|
||||
});
|
||||
|
@ -168,76 +152,34 @@ const ScalarGraph = () => {
|
|||
const renderGraphs = () => {
|
||||
if (checkedToggles) {
|
||||
const coordinateTimeSeries = transformToGraphData(timeSeries);
|
||||
if (plotTitles.length === 0) {
|
||||
setPlotTitles(Object.keys(coordinateTimeSeries));
|
||||
}
|
||||
return Object.keys(coordinateTimeSeries)
|
||||
.filter((path) => {
|
||||
return checkedToggles[path];
|
||||
})
|
||||
.map((path) => {
|
||||
const data = coordinateTimeSeries[path] ?? { x: [], y: [] };
|
||||
const isScalar = isNumeric(data.y[0]);
|
||||
if (!isScalar) {
|
||||
const barGraphData = transformToBarGraphData(data);
|
||||
return (
|
||||
<Plot
|
||||
key={path}
|
||||
data={barGraphData as Data[]}
|
||||
layout={{
|
||||
height: 500,
|
||||
width: 1000,
|
||||
title: path,
|
||||
uirevision: uiRevision,
|
||||
xaxis: {
|
||||
autorange: false,
|
||||
range: range,
|
||||
type: "date",
|
||||
},
|
||||
bargap: 0,
|
||||
barmode: "stack",
|
||||
barnorm: "percent",
|
||||
}}
|
||||
config={{
|
||||
modeBarButtonsToRemove: [
|
||||
"lasso2d",
|
||||
"select2d",
|
||||
"pan2d",
|
||||
"autoScale2d",
|
||||
],
|
||||
}}
|
||||
onRelayout={(params) => {
|
||||
const xaxisRange0 = params["xaxis.range[0]"];
|
||||
const xaxisRange1 = params["xaxis.range[1]"];
|
||||
const visibleGraphs = Object.keys(coordinateTimeSeries).filter((path) => {
|
||||
return checkedToggles[path];
|
||||
});
|
||||
if (visibleGraphs.length > 0) {
|
||||
return visibleGraphs.map((path) => {
|
||||
const isScalar = isNumeric(coordinateTimeSeries[path].y[0]);
|
||||
const data = isScalar
|
||||
? [
|
||||
{
|
||||
...coordinateTimeSeries[path],
|
||||
type: "scatter",
|
||||
mode: "lines+markers",
|
||||
fill: "tozeroy",
|
||||
},
|
||||
]
|
||||
: transformToBarGraphData(coordinateTimeSeries[path]);
|
||||
const barGraphLayout: Partial<Layout> = !isScalar
|
||||
? {
|
||||
bargap: 0,
|
||||
barmode: "stack",
|
||||
barnorm: "percent",
|
||||
}
|
||||
: {};
|
||||
|
||||
if (xaxisRange0 && xaxisRange1) {
|
||||
setRange([new Date(xaxisRange0), new Date(xaxisRange1)]);
|
||||
setUiRevision(Math.random());
|
||||
const times = createTimes(
|
||||
TimeRange.fromTimes(
|
||||
UnixTime.fromDate(new Date(xaxisRange0)),
|
||||
UnixTime.fromDate(new Date(xaxisRange1))
|
||||
),
|
||||
NUMBER_OF_NODES
|
||||
);
|
||||
cache.getSeries(times);
|
||||
times$.next(times);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Plot
|
||||
key={path}
|
||||
data={[
|
||||
{
|
||||
...data,
|
||||
type: isScalar ? "scatter" : "bar",
|
||||
mode: "lines+markers",
|
||||
marker: { color: "red" },
|
||||
},
|
||||
]}
|
||||
data={data as Data[]}
|
||||
layout={{
|
||||
width: 1000,
|
||||
height: 500,
|
||||
|
@ -248,6 +190,10 @@ const ScalarGraph = () => {
|
|||
range: range,
|
||||
type: "date",
|
||||
},
|
||||
yaxis: {
|
||||
rangemode: "tozero",
|
||||
},
|
||||
...barGraphLayout,
|
||||
}}
|
||||
config={{
|
||||
modeBarButtonsToRemove: [
|
||||
|
@ -278,6 +224,12 @@ const ScalarGraph = () => {
|
|||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
return (
|
||||
<Alert sx={{ mt: 2 }} severity="info">
|
||||
Please make a selection on the left
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
};
|
||||
return <>{renderGraphs()}</>;
|
||||
|
|
|
@ -5,14 +5,15 @@ import { useIntl } from "react-intl";
|
|||
interface SearchSidebarProps {
|
||||
listComponent: FC<{ searchQuery: string }>;
|
||||
id: string;
|
||||
height?: string;
|
||||
}
|
||||
const SearchSidebar = (props: SearchSidebarProps) => {
|
||||
const { listComponent: ListComponent, id } = props;
|
||||
const { listComponent: ListComponent, id, height } = props;
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<div style={{ height: "500px", overflow: "hidden" }}>
|
||||
<div style={{ height: height ?? "500px", overflow: "hidden" }}>
|
||||
<TextField
|
||||
id={id}
|
||||
label={intl.formatMessage({
|
||||
|
|
|
@ -3,6 +3,8 @@ import {
|
|||
TreeElement,
|
||||
ToggleElement,
|
||||
} from "../components/Installations/Log/CheckboxTree";
|
||||
import { TimeRange, UnixTime } from "../dataCache/time";
|
||||
import { DataRecord } from "../dataCache/data";
|
||||
|
||||
export interface GraphCoordinates {
|
||||
x: Datum[] | Datum[][] | TypedArray;
|
||||
|
@ -13,8 +15,20 @@ export interface GraphCoordinates {
|
|||
marker?: { color: string };
|
||||
type?: string;
|
||||
name?: string;
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
export interface GraphData {
|
||||
[path: string]: GraphCoordinates;
|
||||
}
|
||||
|
@ -130,3 +144,17 @@ export const transformToBarGraphData = (data: GraphCoordinates) => {
|
|||
});
|
||||
return flattenBarGraphData(barGraphData);
|
||||
};
|
||||
|
||||
export const getTreeElements = (toggleValues: DataRecord) => {
|
||||
return Object.keys(toggleValues)
|
||||
.map((path) =>
|
||||
path
|
||||
.split("/")
|
||||
.map((_, i, arr) => `/${arr.slice(1, i + 1).join("/")}`)
|
||||
.slice(1)
|
||||
)
|
||||
.reduce(
|
||||
(children, path) => insertTreeElements(children, path),
|
||||
[] as TreeElement[]
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue