From 8a4102844d01e74275c120487d3adb93ef9d715e Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Tue, 28 Jan 2025 13:47:17 -0500 Subject: [PATCH] account metrics modal (#828) --- ui100/package-lock.json | 290 +++++++++++++----------------- ui100/package.json | 3 +- ui100/src/AccountMetricsModal.tsx | 67 +++++++ ui100/src/AccountPanel.tsx | 15 +- ui100/src/MetricsGraph.tsx | 21 +++ ui100/src/model/util.ts | 19 +- 6 files changed, 244 insertions(+), 171 deletions(-) create mode 100644 ui100/src/AccountMetricsModal.tsx create mode 100644 ui100/src/MetricsGraph.tsx diff --git a/ui100/package-lock.json b/ui100/package-lock.json index dfbf4e21..2db62f04 100644 --- a/ui100/package-lock.json +++ b/ui100/package-lock.json @@ -12,14 +12,15 @@ "@emotion/styled": "^11.13.5", "@mui/icons-material": "^6.1.8", "@mui/material": "^6.1.8", - "@mui/x-charts": "^7.23.2", "@xyflow/react": "^12.3.5", "d3-hierarchy": "^3.1.2", "formik": "^2.4.6", "material-react-table": "^3.1.0", + "moment": "^2.30.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router": "^7.0.1", + "recharts": "^2.15.1", "yup": "^1.6.1", "zustand": "^5.0.2" }, @@ -1359,64 +1360,6 @@ } } }, - "node_modules/@mui/x-charts": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.23.2.tgz", - "integrity": "sha512-wLeogvQZZtyrAOdG06mDzIQSHBSAB09Uy16AYRUcMxVObi7Fs0i3TJUMpQHMYz1/1DvE1u8zstDgVpVfk8/iCA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.7", - "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-charts-vendor": "7.20.0", - "@mui/x-internals": "7.23.0", - "@react-spring/rafz": "^9.7.5", - "@react-spring/web": "^9.7.5", - "clsx": "^2.1.1", - "prop-types": "^15.8.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@emotion/react": "^11.9.0", - "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14 || ^6.0.0", - "@mui/system": "^5.15.14 || ^6.0.0", - "react": "^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mui/x-charts-vendor": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@mui/x-charts-vendor/-/x-charts-vendor-7.20.0.tgz", - "integrity": "sha512-pzlh7z/7KKs5o0Kk0oPcB+sY0+Dg7Q7RzqQowDQjpy5Slz6qqGsgOB5YUzn0L+2yRmvASc4Pe0914Ao3tMBogg==", - "license": "MIT AND ISC", - "dependencies": { - "@babel/runtime": "^7.25.7", - "@types/d3-color": "^3.1.3", - "@types/d3-delaunay": "^6.0.4", - "@types/d3-interpolate": "^3.0.4", - "@types/d3-scale": "^4.0.8", - "@types/d3-shape": "^3.1.6", - "@types/d3-time": "^3.0.3", - "d3-color": "^3.1.0", - "d3-delaunay": "^6.0.4", - "d3-interpolate": "^3.0.1", - "d3-scale": "^4.0.2", - "d3-shape": "^3.2.0", - "d3-time": "^3.1.0", - "delaunator": "^5.0.1", - "robust-predicates": "^3.0.2" - } - }, "node_modules/@mui/x-date-pickers": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.23.3.tgz", @@ -1489,6 +1432,7 @@ "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.23.0.tgz", "integrity": "sha512-bPclKpqUiJYIHqmTxSzMVZi6MH51cQsn5U+8jskaTlo3J4QiMeCYJn/gn7YbeR9GOZFp8hetyHjoQoVHKRXCig==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0" @@ -1552,78 +1496,6 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@react-spring/animated": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz", - "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==", - "license": "MIT", - "dependencies": { - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@react-spring/core": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz", - "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==", - "license": "MIT", - "dependencies": { - "@react-spring/animated": "~9.7.5", - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-spring/donate" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@react-spring/rafz": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz", - "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==", - "license": "MIT" - }, - "node_modules/@react-spring/shared": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz", - "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==", - "license": "MIT", - "dependencies": { - "@react-spring/rafz": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@react-spring/types": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz", - "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==", - "license": "MIT" - }, - "node_modules/@react-spring/web": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.5.tgz", - "integrity": "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==", - "license": "MIT", - "dependencies": { - "@react-spring/animated": "~9.7.5", - "@react-spring/core": "~9.7.5", - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.27.3", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.3.tgz", @@ -2003,18 +1875,18 @@ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", "license": "MIT" }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT" + }, "node_modules/@types/d3-color": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", "license": "MIT" }, - "node_modules/@types/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", - "license": "MIT" - }, "node_modules/@types/d3-drag": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", @@ -2024,6 +1896,12 @@ "@types/d3-selection": "*" } }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, "node_modules/@types/d3-hierarchy": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", @@ -2076,6 +1954,12 @@ "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", "license": "MIT" }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, "node_modules/@types/d3-transition": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", @@ -2789,18 +2673,6 @@ "node": ">=12" } }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "license": "ISC", - "dependencies": { - "delaunator": "5" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/d3-dispatch": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", @@ -2993,6 +2865,12 @@ } } }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -3009,15 +2887,6 @@ "node": ">=0.10.0" } }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "license": "ISC", - "dependencies": { - "robust-predicates": "^3.0.2" - } - }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -3282,6 +3151,12 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3289,6 +3164,15 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-equals": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", + "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -3881,6 +3765,15 @@ "node": "*" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4227,6 +4120,21 @@ } } }, + "node_modules/react-smooth": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "license": "MIT", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -4243,6 +4151,38 @@ "react-dom": ">=16.6.0" } }, + "node_modules/recharts": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.1.tgz", + "integrity": "sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==", + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.4", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "license": "MIT", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", @@ -4292,12 +4232,6 @@ "node": ">=0.10.0" } }, - "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", - "license": "Unlicense" - }, "node_modules/rollup": { "version": "4.27.3", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.3.tgz", @@ -4477,6 +4411,12 @@ "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", "license": "MIT" }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", @@ -4635,6 +4575,28 @@ "punycode": "^2.1.0" } }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/vite": { "version": "5.4.14", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", diff --git a/ui100/package.json b/ui100/package.json index 9aabee4e..4fdb2a88 100644 --- a/ui100/package.json +++ b/ui100/package.json @@ -14,14 +14,15 @@ "@emotion/styled": "^11.13.5", "@mui/icons-material": "^6.1.8", "@mui/material": "^6.1.8", - "@mui/x-charts": "^7.23.2", "@xyflow/react": "^12.3.5", "d3-hierarchy": "^3.1.2", "formik": "^2.4.6", "material-react-table": "^3.1.0", + "moment": "^2.30.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router": "^7.0.1", + "recharts": "^2.15.1", "yup": "^1.6.1", "zustand": "^5.0.2" }, diff --git a/ui100/src/AccountMetricsModal.tsx b/ui100/src/AccountMetricsModal.tsx new file mode 100644 index 00000000..669d9927 --- /dev/null +++ b/ui100/src/AccountMetricsModal.tsx @@ -0,0 +1,67 @@ +import {Box, Grid2, Modal, Typography} from "@mui/material"; +import {User} from "./model/user.ts"; +import {modalStyle} from "./styling/theme.ts"; +import {useEffect, useState} from "react"; +import {buildMetrics} from "./model/util.ts"; +import {getMetadataApi} from "./model/api.ts"; +import MetricsGraph from "./MetricsGraph.tsx"; + +interface AccountMetricsModalProps { + close: () => void; + isOpen: boolean; + user: User; +} + +const AccountMetricsModal = ({ close, isOpen, user}: AccountMetricsModalProps) => { + const [metrics30, setMetrics30] = useState(buildMetrics([])); + const [metrics7, setMetrics7] = useState(buildMetrics([])); + const [metrics1, setMetrics1] = useState(buildMetrics([])); + + useEffect(() => { + let metadataApi = getMetadataApi(user); + metadataApi.getAccountMetrics() + .then(d => { + let m30 = buildMetrics(d); + console.log(m30); + setMetrics30(m30); + }) + .catch(e => { + e.response.json().then(ex => { + console.log("accountMetricsModal", ex.message); + }); + }); + metadataApi.getAccountMetrics({duration: "168h"}) + .then(d => { + setMetrics7(buildMetrics(d)); + }) + .catch(e => { + e.response.json().then(ex => { + console.log("accountMetricsModal", ex.message); + }); + }); + metadataApi.getAccountMetrics({duration: "24h"}) + .then(d => { + setMetrics1(buildMetrics(d)); + }) + .catch(e => { + e.response.json().then(ex => { + console.log("accountMetricsModal", ex.message); + }); + }); + }, []); + + return ( + + + + Account Metrics + + + + + + + ); +} + +export default AccountMetricsModal; \ No newline at end of file diff --git a/ui100/src/AccountPanel.tsx b/ui100/src/AccountPanel.tsx index 1b7fdc4a..2360e2c0 100644 --- a/ui100/src/AccountPanel.tsx +++ b/ui100/src/AccountPanel.tsx @@ -10,6 +10,8 @@ import React, {useState} from "react"; import AccountPasswordChangeModal from "./AccountPasswordChangeModal.tsx"; import RegenerateAccountTokenModal from "./RegenerateAccountTokenModal.tsx"; import ClipboardText from "./ClipboardText.tsx"; +import AccountMetricsModal from "./AccountMetricsModal.tsx"; +import MetricsIcon from "@mui/icons-material/QueryStats"; interface AccountPanelProps { account: Node; @@ -17,6 +19,13 @@ interface AccountPanelProps { const AccountPanel = ({ account }: AccountPanelProps) => { const user = useApiConsoleStore((state) => state.user); + const [accountMetricsOpen, setAccountMetricsOpen] = useState(false); + const openAccountMetrics = () => { + setAccountMetricsOpen(true); + } + const closeAccountMetrics = () => { + setAccountMetricsOpen(false); + } const [changePasswordOpen, setChangePasswordOpen] = useState(false); const openChangePassword = () => { setChangePasswordOpen(true); @@ -51,7 +60,10 @@ const AccountPanel = ({ account }: AccountPanelProps) => {
Your zrok account, {user.email}
- + + + + @@ -64,6 +76,7 @@ const AccountPanel = ({ account }: AccountPanelProps) => { + diff --git a/ui100/src/MetricsGraph.tsx b/ui100/src/MetricsGraph.tsx new file mode 100644 index 00000000..8461a0b9 --- /dev/null +++ b/ui100/src/MetricsGraph.tsx @@ -0,0 +1,21 @@ +import {Grid2, Typography} from "@mui/material"; +import {Area, AreaChart, CartesianGrid, XAxis, YAxis} from "recharts"; +import moment from "moment"; +import {bytesToSize} from "./model/util.ts"; + +const MetricsGraph = ({ title, data }) => { + return ( + + {title} + + + v.timestamp} scale={"time"} tickFormatter={(v) => moment(v).format("MMM DD") } style={{ fontSize: '75%', fontFamily: "Poppins" }}/> + bytesToSize(v)} style={{ fontSize: '75%', fontFamily: "Poppins" }}/> + v.tx ? v.tx : 0} stackId={"1"} /> + v.rx ? v.rx : 0} stackId={"1"} /> + + + ); +} + +export default MetricsGraph; \ No newline at end of file diff --git a/ui100/src/model/util.ts b/ui100/src/model/util.ts index 092081cb..d011b453 100644 --- a/ui100/src/model/util.ts +++ b/ui100/src/model/util.ts @@ -24,8 +24,17 @@ export const bytesToSize = (bytes: number): string => { return Math.max(bytes, 0.1).toFixed(1) + byteUnits[i]; } -function getReadableFileSizeString(fileSizeInBytes) { - let i = -1; - let byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB']; - return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]; -} +export const buildMetrics = (m) => { + let metrics = { + data: m.samples, + rx: 0, + tx: 0 + } + if(m.samples) { + m.samples.forEach(s => { + metrics.rx += s.rx ? s.rx : 0; + metrics.tx += s.tx ? s.tx : 0; + }); + } + return metrics; +} \ No newline at end of file