From 9fb5892212359193ee4a79b3ade46f2e5e58e849 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Fri, 4 Oct 2024 19:00:35 +0200 Subject: [PATCH] Move to sunburst component and inprove table --- package-lock.json | 1222 +++++++++++++---- package.json | 6 +- .../Availability/AvailabilitiesTable.css | 8 + .../Availability/AvailabilitiesTable.tsx | 85 +- .../Availability/AvailabilityActionsCell.tsx | 30 +- .../Availability/AvailabilityContext.ts | 4 + .../Availability/AvailabilityDiskRow.css | 10 + .../Availability/AvailabilityDiskRow.tsx | 74 + ...abilityCreate.css => AvailabilityEdit.css} | 0 .../Availability/AvailabilityEdit.tsx | 186 +++ .../Availability/AvailabilityForm.css | 12 + .../Availability/AvailabilityForm.tsx | 65 +- .../Availability/AvailabilityIdCell.css | 5 + .../Availability/AvailabilityIdCell.tsx | 62 + .../Availability/AvailabilityReservations.tsx | 7 +- ...Create.tsx => AvailabilitySheetCreate.tsx} | 22 +- .../Availability/AvailabilitySlotRow.css | 34 + .../Availability/AvailabilitySlotRow.tsx | 86 ++ .../AvailabilitySpaceAllocation.tsx | 19 +- .../Availability/AvailabilitySunburst.css | 5 + .../Availability/AvailabilitySunburst.tsx | 183 +++ .../Availability/availability.colors.ts | 33 + .../Availability/availability.domain.ts | 43 +- src/components/Availability/types.tsx | 12 +- .../Availability/useAvailabilityMutation.ts | 20 +- .../CustomStateCellRender.tsx | 30 +- src/components/FileCellRender/FileCell.tsx | 10 +- .../NodeSpaceAllocation.tsx | 5 + .../nodeSpaceAllocation.domain.ts | 5 + src/components/TruncateCell/TruncateCell.css | 19 + src/components/TruncateCell/TruncateCell.tsx | 16 +- src/routes/dashboard/availabilities.css | 177 ++- src/routes/dashboard/availabilities.tsx | 103 +- src/routes/dashboard/purchases.tsx | 38 +- src/utils/arrays.ts | 4 + src/utils/availabilities-storage.ts | 17 + src/utils/errors.ts | 33 + src/utils/promises.ts | 29 +- 38 files changed, 2205 insertions(+), 514 deletions(-) create mode 100644 src/components/Availability/AvailabilitiesTable.css create mode 100644 src/components/Availability/AvailabilityContext.ts create mode 100644 src/components/Availability/AvailabilityDiskRow.css create mode 100644 src/components/Availability/AvailabilityDiskRow.tsx rename src/components/Availability/{AvailabilityCreate.css => AvailabilityEdit.css} (100%) create mode 100644 src/components/Availability/AvailabilityEdit.tsx create mode 100644 src/components/Availability/AvailabilityIdCell.css create mode 100644 src/components/Availability/AvailabilityIdCell.tsx rename src/components/Availability/{AvailabilityCreate.tsx => AvailabilitySheetCreate.tsx} (89%) create mode 100644 src/components/Availability/AvailabilitySlotRow.css create mode 100644 src/components/Availability/AvailabilitySlotRow.tsx create mode 100644 src/components/Availability/AvailabilitySunburst.css create mode 100644 src/components/Availability/AvailabilitySunburst.tsx create mode 100644 src/components/Availability/availability.colors.ts create mode 100644 src/components/NodeSpaceAllocation/nodeSpaceAllocation.domain.ts create mode 100644 src/utils/arrays.ts create mode 100644 src/utils/availabilities-storage.ts create mode 100644 src/utils/errors.ts diff --git a/package-lock.json b/package-lock.json index 67b5387..c2f54dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,15 @@ "version": "0.0.3", "license": "MIT", "dependencies": { - "@codex-storage/marketplace-ui-components": "0.0.14", + "@codex-storage/marketplace-ui-components": "0.0.15", "@codex-storage/sdk-js": "0.0.6", + "@nivo/sunburst": "^0.87.0", "@sentry/browser": "^8.32.0", "@sentry/react": "^8.31.0", "@tanstack/react-query": "^5.51.15", "@tanstack/react-router": "^1.58.7", + "chart.js": "^4.4.4", + "echarts": "^5.5.1", "idb-keyval": "^6.2.1", "lucide-react": "^0.445.0", "react": "^18.3.1", @@ -32,6 +35,7 @@ "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.12", "prettier": "^3.3.3", + "sass-embedded": "^1.79.4", "typescript": "5.5.4", "vite": "^5.4.7" }, @@ -39,6 +43,48 @@ "node": ">=18" } }, + "../storybook": { + "name": "@codex-storage/marketplace-ui-components", + "version": "0.0.14", + "extraneous": true, + "license": "MIT", + "dependencies": { + "lucide-react": "^0.441.0" + }, + "devDependencies": { + "@chromatic-com/storybook": "^2.0.2", + "@storybook/addon-essentials": "^8.2.9", + "@storybook/addon-interactions": "^8.2.9", + "@storybook/addon-links": "^8.2.9", + "@storybook/addon-onboarding": "^8.2.9", + "@storybook/blocks": "^8.2.9", + "@storybook/react": "^8.2.9", + "@storybook/react-vite": "^8.2.9", + "@storybook/test": "^8.2.9", + "@typescript-eslint/eslint-plugin": "^8.6.0", + "@typescript-eslint/parser": "^8.0.0", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^8.57.0", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.7", + "glob": "^9.3.5", + "prettier": "^3.3.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "storybook": "^8.2.9", + "typescript": "5.5.2", + "vite-plugin-dts": "^4.0.3", + "vite-plugin-lib-inject-css": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@codex-storage/sdk-js": "0.0.6", + "react": "^18.3.1", + "react-dom": "^18.3.1" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "dev": true, @@ -341,10 +387,16 @@ "node": ">=6.9.0" } }, + "node_modules/@bufbuild/protobuf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.1.0.tgz", + "integrity": "sha512-+2Mx67Y3skJ4NCD/qNSdBJNWtu6x6Qr53jeNg+QcwiL6mt0wK+3jwHH2x1p7xaYH6Ve2JKOVn0OxU35WsmqI9A==", + "dev": true + }, "node_modules/@codex-storage/marketplace-ui-components": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@codex-storage/marketplace-ui-components/-/marketplace-ui-components-0.0.14.tgz", - "integrity": "sha512-V1JI3OexYGwcsCeMYWixYIMnjYMhXjvjk6YcueILmmg3l/qjMtR1rSr1kz7RiyqRokuCdaxz3xoNr+euZajl3w==", + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/@codex-storage/marketplace-ui-components/-/marketplace-ui-components-0.0.15.tgz", + "integrity": "sha512-S6zWaAI4t3IOxXxg/uEB9C1CCOynvhjYg7B8H+zJ2nq1bNleYwnCqld2KzPbXHCRLiFspMIzs/ul2gimTQa6aw==", "dependencies": { "lucide-react": "^0.441.0" }, @@ -555,6 +607,101 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "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/@nivo/arcs": { + "version": "0.87.0", + "resolved": "https://registry.npmjs.org/@nivo/arcs/-/arcs-0.87.0.tgz", + "integrity": "sha512-YWmIm0el0hgVbPI3C5AX6R59WNnuKjh2GdocaVDP5zupqAMhfqyoMx+IM+A+Cg+UzE4xakrL0mSzL+rpMUK90Q==", + "dependencies": { + "@nivo/colors": "0.87.0", + "@nivo/core": "0.87.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-shape": "^3.1.6", + "d3-shape": "^3.2.0" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/colors": { + "version": "0.87.0", + "resolved": "https://registry.npmjs.org/@nivo/colors/-/colors-0.87.0.tgz", + "integrity": "sha512-S4pZzRGKK23t8XAjQMhML6wwsfKO9nH03xuyN4SvCodNA/Dmdys9xV+9Dg/VILTzvzsBTBGTX0dFBg65WoKfVg==", + "dependencies": { + "@nivo/core": "0.87.0", + "@types/d3-color": "^3.0.0", + "@types/d3-scale": "^4.0.8", + "@types/d3-scale-chromatic": "^3.0.0", + "@types/prop-types": "^15.7.2", + "d3-color": "^3.1.0", + "d3-scale": "^4.0.2", + "d3-scale-chromatic": "^3.0.0", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/core": { + "version": "0.87.0", + "resolved": "https://registry.npmjs.org/@nivo/core/-/core-0.87.0.tgz", + "integrity": "sha512-yEQWJn7QjWnbmCZccBCo4dligNyNyz3kgyV9vEtcaB1iGeKhg55RJEAlCOul+IDgSCSPFci2SxTmipE6LZEZCg==", + "dependencies": { + "@nivo/tooltip": "0.87.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-shape": "^3.1.6", + "d3-color": "^3.1.0", + "d3-format": "^1.4.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-scale-chromatic": "^3.0.0", + "d3-shape": "^3.2.0", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nivo/donate" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/sunburst": { + "version": "0.87.0", + "resolved": "https://registry.npmjs.org/@nivo/sunburst/-/sunburst-0.87.0.tgz", + "integrity": "sha512-zK/Xj9jxnFz9kwhesYOAqnOsO17Kw/zqPwSeZtQCCQAnz7F6OD4QH3OzkAOsr584QZud/01/g3GwxAXdQlDXZA==", + "dependencies": { + "@nivo/arcs": "0.87.0", + "@nivo/colors": "0.87.0", + "@nivo/core": "0.87.0", + "@nivo/tooltip": "0.87.0", + "@types/d3-hierarchy": "^1.1.8", + "d3-hierarchy": "^1.1.8", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/tooltip": { + "version": "0.87.0", + "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.87.0.tgz", + "integrity": "sha512-nZJWyRIt/45V/JBdJ9ksmNm1LFfj59G1Dy9wB63Icf2YwyBT+J+zCzOGXaY7gxCxgF1mnSL3dC7fttcEdXyN/g==", + "dependencies": { + "@nivo/core": "0.87.0", + "@react-spring/web": "9.4.5 || ^9.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -587,6 +734,72 @@ "node": ">= 8" } }, + "node_modules/@react-spring/animated": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.4.tgz", + "integrity": "sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==", + "dependencies": { + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.4.tgz", + "integrity": "sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "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.4", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.4.tgz", + "integrity": "sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.4.tgz", + "integrity": "sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==", + "dependencies": { + "@react-spring/rafz": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.4.tgz", + "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.4.tgz", + "integrity": "sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/core": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "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.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", @@ -796,252 +1009,97 @@ ] }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.32.0.tgz", - "integrity": "sha512-DpUGhk5O1OVjT0fo9wsbEdO1R/S9gGBRDtn9+FFVeRtieJHwXpeZiLK+tZhTOvaILmtSoTPUEY3L5sK4j5Xq9g==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.33.1.tgz", + "integrity": "sha512-TW6/r+Gl5jiXv54iK1xZ3mlVgTS/jaBp4vcQ0xGMdgiQ3WchEPcFSeYovL+YHT3tSud0GZqVtDQCz+5i76puqA==", "dependencies": { - "@sentry/core": "8.32.0", - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/browser-utils/node_modules/@sentry/core": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.32.0.tgz", - "integrity": "sha512-+xidTr0lZ0c755tq4k75dXPEb8PA+qvIefW3U9+dQMORLokBrYoKYMf5zZTG2k/OfSJS6OSxatUj36NFuCs3aA==", - "dependencies": { - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/browser-utils/node_modules/@sentry/types": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.32.0.tgz", - "integrity": "sha512-hxckvN2MzS5SgGDgVQ0/QpZXk13Vrq4BtZLwXhPhyeTmZtUiUfWvcL5TFQqLinfKdTKPe9q2MxeAJ0D4LalhMg==", - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/browser-utils/node_modules/@sentry/utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.32.0.tgz", - "integrity": "sha512-t1WVERhgmYURxbBj9J4/H2P2X+VKqm7B3ce9iQyrZbdf5NekhcU4jHIecPUWCPHjQkFIqkVTorqeBmDTlg/UmQ==", - "dependencies": { - "@sentry/types": "8.32.0" + "@sentry/core": "8.33.1", + "@sentry/types": "8.33.1", + "@sentry/utils": "8.33.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.32.0.tgz", - "integrity": "sha512-XB7hiVJQW1tNzpoXIHbvm3rjipIt7PZiJJtFg2vxaqu/FzdgOcYqQiwIKivJVAKuRZ9rIeJtK1jdXQFOc/TRJA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.33.1.tgz", + "integrity": "sha512-qauMRTm3qDaLqZ3ibI03cj4gLF40y0ij65nj+cns6iWxGCtPrO8tjvXFWuQsE7Aye9dGMnBgmv7uN+NTUtC3RA==", "dependencies": { - "@sentry/core": "8.32.0", - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/feedback/node_modules/@sentry/core": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.32.0.tgz", - "integrity": "sha512-+xidTr0lZ0c755tq4k75dXPEb8PA+qvIefW3U9+dQMORLokBrYoKYMf5zZTG2k/OfSJS6OSxatUj36NFuCs3aA==", - "dependencies": { - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/feedback/node_modules/@sentry/types": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.32.0.tgz", - "integrity": "sha512-hxckvN2MzS5SgGDgVQ0/QpZXk13Vrq4BtZLwXhPhyeTmZtUiUfWvcL5TFQqLinfKdTKPe9q2MxeAJ0D4LalhMg==", - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/feedback/node_modules/@sentry/utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.32.0.tgz", - "integrity": "sha512-t1WVERhgmYURxbBj9J4/H2P2X+VKqm7B3ce9iQyrZbdf5NekhcU4jHIecPUWCPHjQkFIqkVTorqeBmDTlg/UmQ==", - "dependencies": { - "@sentry/types": "8.32.0" + "@sentry/core": "8.33.1", + "@sentry/types": "8.33.1", + "@sentry/utils": "8.33.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.32.0.tgz", - "integrity": "sha512-yiEUnn2yyo1AIQIFNeRX3tdK8fmyKIkxdFS1WiVQmeYI/hFwYBTZPly0FcO/g3xnRMSA2tvrS+hZEaaXfK4WhA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.33.1.tgz", + "integrity": "sha512-fm4coIOjmanU29NOVN9MyaP4fUCOYytbtFqVSKRFNZQ/xAgNeySiBIbUd6IjujMmnOk9bY0WEUMcdm3Uotjdog==", "dependencies": { - "@sentry-internal/browser-utils": "8.32.0", - "@sentry/core": "8.32.0", - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" + "@sentry-internal/browser-utils": "8.33.1", + "@sentry/core": "8.33.1", + "@sentry/types": "8.33.1", + "@sentry/utils": "8.33.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.32.0.tgz", - "integrity": "sha512-oBbhtDBkD+5z/T0NVJ5VenBWAid/S9QdVrod/UqxVqU7F8N+E9/INFQI48zCWr4iVlUMcszJPDElvJEsMDvvBQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.33.1.tgz", + "integrity": "sha512-nsxTFTPCT10Ty/v6+AiST3+yotGP1sUb8xqfKB9fPnS1hZHFryp0NnEls7xFjBsBbZPU1GpFkzrk/E6JFzixDQ==", "dependencies": { - "@sentry-internal/replay": "8.32.0", - "@sentry/core": "8.32.0", - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/core": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.32.0.tgz", - "integrity": "sha512-+xidTr0lZ0c755tq4k75dXPEb8PA+qvIefW3U9+dQMORLokBrYoKYMf5zZTG2k/OfSJS6OSxatUj36NFuCs3aA==", - "dependencies": { - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/types": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.32.0.tgz", - "integrity": "sha512-hxckvN2MzS5SgGDgVQ0/QpZXk13Vrq4BtZLwXhPhyeTmZtUiUfWvcL5TFQqLinfKdTKPe9q2MxeAJ0D4LalhMg==", - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.32.0.tgz", - "integrity": "sha512-t1WVERhgmYURxbBj9J4/H2P2X+VKqm7B3ce9iQyrZbdf5NekhcU4jHIecPUWCPHjQkFIqkVTorqeBmDTlg/UmQ==", - "dependencies": { - "@sentry/types": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/replay/node_modules/@sentry/core": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.32.0.tgz", - "integrity": "sha512-+xidTr0lZ0c755tq4k75dXPEb8PA+qvIefW3U9+dQMORLokBrYoKYMf5zZTG2k/OfSJS6OSxatUj36NFuCs3aA==", - "dependencies": { - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/replay/node_modules/@sentry/types": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.32.0.tgz", - "integrity": "sha512-hxckvN2MzS5SgGDgVQ0/QpZXk13Vrq4BtZLwXhPhyeTmZtUiUfWvcL5TFQqLinfKdTKPe9q2MxeAJ0D4LalhMg==", - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry-internal/replay/node_modules/@sentry/utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.32.0.tgz", - "integrity": "sha512-t1WVERhgmYURxbBj9J4/H2P2X+VKqm7B3ce9iQyrZbdf5NekhcU4jHIecPUWCPHjQkFIqkVTorqeBmDTlg/UmQ==", - "dependencies": { - "@sentry/types": "8.32.0" + "@sentry-internal/replay": "8.33.1", + "@sentry/core": "8.33.1", + "@sentry/types": "8.33.1", + "@sentry/utils": "8.33.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/browser": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.32.0.tgz", - "integrity": "sha512-AEKFj64g4iYwEMRvVcxiY0FswmClRXCP1IEvCqujn8OBS8AjMOr1z/RwYieEs0D90yNNB3YEqF8adrKENblJmw==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.33.1.tgz", + "integrity": "sha512-c6zI/igexkLwZuGk+u8Rj26ChjxGgkhe6ZbKFsXCYaKAp5ep5X7HQRkkqgbxApiqlC0LduHdd/ymzh139JLg8w==", "dependencies": { - "@sentry-internal/browser-utils": "8.32.0", - "@sentry-internal/feedback": "8.32.0", - "@sentry-internal/replay": "8.32.0", - "@sentry-internal/replay-canvas": "8.32.0", - "@sentry/core": "8.32.0", - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/browser/node_modules/@sentry/core": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.32.0.tgz", - "integrity": "sha512-+xidTr0lZ0c755tq4k75dXPEb8PA+qvIefW3U9+dQMORLokBrYoKYMf5zZTG2k/OfSJS6OSxatUj36NFuCs3aA==", - "dependencies": { - "@sentry/types": "8.32.0", - "@sentry/utils": "8.32.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/browser/node_modules/@sentry/types": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.32.0.tgz", - "integrity": "sha512-hxckvN2MzS5SgGDgVQ0/QpZXk13Vrq4BtZLwXhPhyeTmZtUiUfWvcL5TFQqLinfKdTKPe9q2MxeAJ0D4LalhMg==", - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/browser/node_modules/@sentry/utils": { - "version": "8.32.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.32.0.tgz", - "integrity": "sha512-t1WVERhgmYURxbBj9J4/H2P2X+VKqm7B3ce9iQyrZbdf5NekhcU4jHIecPUWCPHjQkFIqkVTorqeBmDTlg/UmQ==", - "dependencies": { - "@sentry/types": "8.32.0" + "@sentry-internal/browser-utils": "8.33.1", + "@sentry-internal/feedback": "8.33.1", + "@sentry-internal/replay": "8.33.1", + "@sentry-internal/replay-canvas": "8.33.1", + "@sentry/core": "8.33.1", + "@sentry/types": "8.33.1", + "@sentry/utils": "8.33.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/core": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.31.0.tgz", - "integrity": "sha512-5zsMBOML18e5a/ZoR5XpcYF59e2kSxb6lTg13u52f/+NA27EPgxKgXim5dz6L/6+0cizgwwmFaZFGJiFc2qoAA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.1.tgz", + "integrity": "sha512-3SS41suXLFzxL3OQvTMZ6q92ZapELVq2l2SoWlZopcamWhog2Ru0dp2vkunq97kFHb2TzKRTlFH4+4gbT8SJug==", "dependencies": { - "@sentry/types": "8.31.0", - "@sentry/utils": "8.31.0" + "@sentry/types": "8.33.1", + "@sentry/utils": "8.33.1" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/react": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.31.0.tgz", - "integrity": "sha512-geMQNbkJMGREC1TpSWn1Yr+hGOERO13gPqh3aQBpTF0GEDXbmVwX2U/+6wqXCVICGbKujDroReRBRLqk3fmWSA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.33.1.tgz", + "integrity": "sha512-SsEX05xfcfOvo7/pK1UyeyTAYWH8iSIsXXlsjvnSRsbuJkjb0c+q6yiZpj3A2PRdbcx43nTVE1n0lSpgaqj2HA==", "dependencies": { - "@sentry/browser": "8.31.0", - "@sentry/core": "8.31.0", - "@sentry/types": "8.31.0", - "@sentry/utils": "8.31.0", + "@sentry/browser": "8.33.1", + "@sentry/core": "8.33.1", + "@sentry/types": "8.33.1", + "@sentry/utils": "8.33.1", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -1051,91 +1109,20 @@ "react": "^16.14.0 || 17.x || 18.x || 19.x" } }, - "node_modules/@sentry/react/node_modules/@sentry-internal/browser-utils": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.31.0.tgz", - "integrity": "sha512-Bq7TFMhPr1PixRGYkB/6ar9ws7sj224XzQ+hgpz6OxGEc9fQakvD8t/Nn7dp14k3FI/hcBRA6BBvpOKUUuPgGA==", - "dependencies": { - "@sentry/core": "8.31.0", - "@sentry/types": "8.31.0", - "@sentry/utils": "8.31.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/react/node_modules/@sentry-internal/feedback": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.31.0.tgz", - "integrity": "sha512-R3LcC2IaTe8lgi5AU9h0rMgyVPpaTiMSLRhRlVeQPVmAKCz8pSG/um13q37t0BsXpTaImW9yYQ71Aj6h6IrShQ==", - "dependencies": { - "@sentry/core": "8.31.0", - "@sentry/types": "8.31.0", - "@sentry/utils": "8.31.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/react/node_modules/@sentry-internal/replay": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.31.0.tgz", - "integrity": "sha512-r8hmFDwWxeAxpdzBCRWTKQ/QHl8QanFw8XfM0fvFes/H1d/b43Vwc/IiUnsYoMOdooIP8hJFGDKlfq+Y5uVVGA==", - "dependencies": { - "@sentry-internal/browser-utils": "8.31.0", - "@sentry/core": "8.31.0", - "@sentry/types": "8.31.0", - "@sentry/utils": "8.31.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/react/node_modules/@sentry-internal/replay-canvas": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.31.0.tgz", - "integrity": "sha512-ConyrhWozx4HluRj0+9teN4XTC1ndXjxMdJQvDnbLFsQhCCEdwUfaZVshV1CFe9T08Bfyjruaw33yR7pDXYktw==", - "dependencies": { - "@sentry-internal/replay": "8.31.0", - "@sentry/core": "8.31.0", - "@sentry/types": "8.31.0", - "@sentry/utils": "8.31.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/react/node_modules/@sentry/browser": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.31.0.tgz", - "integrity": "sha512-LZK0uLPGB4Al+qWc1eaad+H/1SR6CY9a0V2XWpUbNAT3+VkEo0Z/78bW1kb43N0cok87hNPOe+c66SfwdxphVQ==", - "dependencies": { - "@sentry-internal/browser-utils": "8.31.0", - "@sentry-internal/feedback": "8.31.0", - "@sentry-internal/replay": "8.31.0", - "@sentry-internal/replay-canvas": "8.31.0", - "@sentry/core": "8.31.0", - "@sentry/types": "8.31.0", - "@sentry/utils": "8.31.0" - }, - "engines": { - "node": ">=14.18" - } - }, "node_modules/@sentry/types": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.31.0.tgz", - "integrity": "sha512-prRM/n5nlP+xQZSpdEkSR8BwwZtgsLk0NbI8eCjTMu2isVlrlggop8pVaJb7y9HmElVtDA1Q6y4u8TD2htQKFQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.1.tgz", + "integrity": "sha512-GjoAMvwtpIemoF/IiwZ7A60g4nQv3qwzR21GvJqDVUoKD0e8pv9OLX+HyXoUat4wEDGSuDUcUyUKD2G+od73QA==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry/utils": { - "version": "8.31.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.31.0.tgz", - "integrity": "sha512-9W2LZ9QIHKc0HSyH/7UmTolc01Q4vX/qMSZk7i1noinlkQtnRUmTP39r1DSITjKCrDHj6zvB/J1RPDUoRcTXxQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-uzuYpiiJuFY3N4WNHMBWUQX5oNv2t/TbG0OHRp3Rr7yeu+HSfD542TIp9/gMZ+G0Cxd8AmVO3wkKIFbk0TL4Qg==", "dependencies": { - "@sentry/types": "8.31.0" + "@sentry/types": "8.33.1" }, "engines": { "node": ">=14.18" @@ -1837,6 +1824,47 @@ "@babel/types": "^7.20.7" } }, + "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==" + }, + "node_modules/@types/d3-hierarchy": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.11.tgz", + "integrity": "sha512-lnQiU7jV+Gyk9oQYk0GGYccuexmQPTp08E0+4BidgFdiJivjEvf+esPSdZqCZ2C7UwTWejWpqetVaU8A+eX3FA==" + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, "node_modules/@types/estree": { "version": "1.0.5", "dev": true, @@ -1844,7 +1872,6 @@ }, "node_modules/@types/prop-types": { "version": "15.7.12", - "dev": true, "license": "MIT" }, "node_modules/@types/react": { @@ -2256,6 +2283,12 @@ "integrity": "sha512-tKYm5YHPU1djz0O+CGJ+oJIvimtsCcwR2Z9w7Skh08lUdyzXY5djods3q+z2JkWdb7tCcmM//eVavSRAiaPRNg==", "dev": true }, + "node_modules/buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", + "dev": true + }, "node_modules/callsites": { "version": "3.1.0", "dev": true, @@ -2277,6 +2310,17 @@ "node": ">=4" } }, + "node_modules/chart.js": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/chokidar": { "version": "3.6.0", "dev": true, @@ -2335,6 +2379,12 @@ "dev": true, "license": "MIT" }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "dev": true, @@ -2363,6 +2413,132 @@ "dev": true, "license": "MIT" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "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-format": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" + }, + "node_modules/d3-hierarchy": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", + "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==" + }, + "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-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "dependencies": { + "d3-time": "1 - 2" + } + }, + "node_modules/d3-time-format/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-time-format/node_modules/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/d3-time-format/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, "node_modules/debug": { "version": "4.3.7", "dev": true, @@ -2395,6 +2571,20 @@ "node": ">=6.0.0" } }, + "node_modules/echarts": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.1.tgz", + "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.0" + } + }, + "node_modules/echarts/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, "node_modules/escalade": { "version": "3.2.0", "dev": true, @@ -2890,6 +3080,12 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true + }, "node_modules/import-fresh": { "version": "3.3.0", "dev": true, @@ -2927,6 +3123,14 @@ "dev": true, "license": "ISC" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "dev": true, @@ -3064,6 +3268,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "dev": true, @@ -3172,6 +3381,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/once": { "version": "1.4.0", "dev": true, @@ -3324,6 +3541,16 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "dev": true, @@ -3505,6 +3732,402 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/sass-embedded": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.79.4.tgz", + "integrity": "sha512-3AATrtStMgxYjkit02/Ix8vx/P7qderYG6DHjmehfk5jiw53OaWVScmcGJSwp/d77kAkxDQ+Y0r+79VynGmrkw==", + "dev": true, + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^4.0.0", + "rxjs": "^7.4.0", + "supports-color": "^8.1.1", + "varint": "^6.0.0" + }, + "bin": { + "sass": "dist/bin/sass.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "sass-embedded-android-arm": "1.79.4", + "sass-embedded-android-arm64": "1.79.4", + "sass-embedded-android-ia32": "1.79.4", + "sass-embedded-android-riscv64": "1.79.4", + "sass-embedded-android-x64": "1.79.4", + "sass-embedded-darwin-arm64": "1.79.4", + "sass-embedded-darwin-x64": "1.79.4", + "sass-embedded-linux-arm": "1.79.4", + "sass-embedded-linux-arm64": "1.79.4", + "sass-embedded-linux-ia32": "1.79.4", + "sass-embedded-linux-musl-arm": "1.79.4", + "sass-embedded-linux-musl-arm64": "1.79.4", + "sass-embedded-linux-musl-ia32": "1.79.4", + "sass-embedded-linux-musl-riscv64": "1.79.4", + "sass-embedded-linux-musl-x64": "1.79.4", + "sass-embedded-linux-riscv64": "1.79.4", + "sass-embedded-linux-x64": "1.79.4", + "sass-embedded-win32-arm64": "1.79.4", + "sass-embedded-win32-ia32": "1.79.4", + "sass-embedded-win32-x64": "1.79.4" + } + }, + "node_modules/sass-embedded-android-arm": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.79.4.tgz", + "integrity": "sha512-YOVpDGDcwWUQvktpJhYo4zOkknDpdX6ALpaeHDTX6GBUvnZfx+Widh76v+QFUhiJQ/I/hndXg1jv/PKilOHRrw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.79.4.tgz", + "integrity": "sha512-0JAZ8TtXYv9yI3Yasaq03xvo7DLJOmD+Exb30oJKxXcWTAV9TB0ZWKoIRsFxbCyPxyn7ouxkaCEXQtaTRKrmfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.79.4.tgz", + "integrity": "sha512-IjO3RoyvNN84ZyfAR5s/a8TIdNPfClb7CLGrswB3BN/NElYIJUJMVHD6+Y8W9QwBIZ8DrK1IdLFSTV8nn82xMA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-riscv64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.79.4.tgz", + "integrity": "sha512-uOT8nXmKxSwuIdcqvElVWBFcm/+YcIvmwfoKbpuuSOSxUe9eqFzxo+fk7ILhynzf6FBlvRUH5DcjGj+sXtCc3w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.79.4.tgz", + "integrity": "sha512-W2FQoj3Z2J2DirNs3xSBVvrhMuqLnsqvOPulxOkhL/074+faKOZZnPx2tZ5zsHbY97SonciiU0SV0mm98xI42w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.79.4.tgz", + "integrity": "sha512-pcYtbN1VUAAcfgyHeX8ySndDWGjIvcq6rldduktPbGGuAlEWFDfnwjTbv0hS945ggdzZ6TFnaFlLEDr0SjKzBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.79.4.tgz", + "integrity": "sha512-ir8CFTfc4JLx/qCP8LK1/3pWv35nRyAQkUK7lBIKM6hWzztt64gcno9rZIk4SpHr7Z/Bp1IYWWRS4ZT+4HmsbA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.79.4.tgz", + "integrity": "sha512-H/XEE3rY7c+tY0qDaELjPjC6VheAhBo1tPJQ6UHoBEf8xrbT/RT3dWiIS8grp9Vk54RCn05BEB/+POaljvvKGA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.79.4.tgz", + "integrity": "sha512-XIVn2mCuA422SR2kmKjF6jhjMs1Vrt1DbZ/ktSp+eR0sU4ugu2htg45GajiUFSKKRj7Sc+cBdThq1zPPsDLf1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.79.4.tgz", + "integrity": "sha512-3nqZxV4nuUTb1ahLexVl4hsnx1KKwiGdHEf1xHWTZai6fYFMcwyNPrHySCQzFHqb5xiqSpPzzrKjuDhF6+guuQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.79.4.tgz", + "integrity": "sha512-HnbU1DEiQdUayioNzxh2WlbTEgQRBPTgIIvof8J63QLmVItUqE7EkWYkSUy4RhO+8NsuN9wzGmGTzFBvTImU7g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.79.4.tgz", + "integrity": "sha512-C6qX06waPEfDgOHR8jXoYxl0EtIXOyBDyyonrLO3StRjWjGx7XMQj2hA/KXSsV+Hr71fBOsaViosqWXPzTbEiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.79.4.tgz", + "integrity": "sha512-y5b0fdOPWyhj4c+mc88GvQiC5onRH1V0iNaWNjsiZ+L4hHje6T98nDLrCJn0fz5GQnXjyLCLZduMWbfV0QjHGg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-riscv64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.79.4.tgz", + "integrity": "sha512-G2M5ADMV9SqnkwpM0S+UzDz7xR2njCOhofku/sDMZABzAjQQWTsAykKoGmzlT98fTw2HbNhb6u74umf2WLhCfw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.79.4.tgz", + "integrity": "sha512-kQm8dCU3DXf7DtUGWYPiPs03KJYKvFeiZJHhSx993DCM8D2b0wCXWky0S0Z46gf1sEur0SN4Lvnt1WczTqxIBw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-riscv64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.79.4.tgz", + "integrity": "sha512-GaTI/mXYWYSzG5wxtM4H2cozLpATyh+4l+rO9FFKOL8e1sUOLAzTeRdU2nSBYCuRqsxRuTZIwCXhSz9Q3NRuNA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.79.4.tgz", + "integrity": "sha512-f9laGkqHgC01h99Qt4LsOV+OLMffjvUcTu14hYWqMS9QVX5a4ihMwpf1NoAtTUytb7cVF3rYY/NVGuXt6G3ppQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.79.4.tgz", + "integrity": "sha512-cidBvtaA2cJ6dNlwQEa8qak+ezypurzKs0h0QAHLH324+j/6Jum7LCnQhZRPYJBFjHl+WYd7KwzPnJ2X5USWnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.79.4.tgz", + "integrity": "sha512-hexdmNTIZGTKNTzlMcdvEXzYuxOJcY89zqgsf45aQ2YMy4y2M8dTOxRI/Vz7p4iRxVp1Jow6LCtaLHrNI2Ordg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.79.4.tgz", + "integrity": "sha512-73yrpiWIbti6DkxhWURklkgSLYKfU9itDmvHxB+oYSb4vQveIApqTwSyTOuIUb/6Da/EsgEpdJ4Lbj4sLaMZWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sass-embedded/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/scheduler": { "version": "0.23.2", "license": "MIT", @@ -3624,6 +4247,12 @@ "typescript": ">=4.2.0" } }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -3728,6 +4357,12 @@ "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.32.0.tgz", "integrity": "sha512-FXBnJl4bNOmeg7lQv+jfvo/wADsRBN8e9C3r+O77Re3dEnDma8opp7p4hcIbF7XJJ30h/5SVohdjer17/sHOsQ==" }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", + "dev": true + }, "node_modules/vite": { "version": "5.4.7", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz", @@ -4260,6 +4895,19 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zrender": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.0.tgz", + "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==", + "dependencies": { + "tslib": "2.3.0" + } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index c144f43..4c10a07 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,15 @@ "React" ], "dependencies": { - "@codex-storage/marketplace-ui-components": "0.0.14", + "@codex-storage/marketplace-ui-components": "0.0.15", "@codex-storage/sdk-js": "0.0.6", + "@nivo/sunburst": "^0.87.0", "@sentry/browser": "^8.32.0", "@sentry/react": "^8.31.0", "@tanstack/react-query": "^5.51.15", "@tanstack/react-router": "^1.58.7", + "chart.js": "^4.4.4", + "echarts": "^5.5.1", "idb-keyval": "^6.2.1", "lucide-react": "^0.445.0", "react": "^18.3.1", @@ -46,6 +49,7 @@ "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.12", "prettier": "^3.3.3", + "sass-embedded": "^1.79.4", "typescript": "5.5.4", "vite": "^5.4.7" }, diff --git a/src/components/Availability/AvailabilitiesTable.css b/src/components/Availability/AvailabilitiesTable.css new file mode 100644 index 0000000..23b14f0 --- /dev/null +++ b/src/components/Availability/AvailabilitiesTable.css @@ -0,0 +1,8 @@ +.availabilityTable-chevron { + cursor: pointer; + transition: transform 0.35s; +} + +.availabilityTable-chevron--open { + transform: rotate(180deg); +} diff --git a/src/components/Availability/AvailabilitiesTable.tsx b/src/components/Availability/AvailabilitiesTable.tsx index 2647d0a..78c156d 100644 --- a/src/components/Availability/AvailabilitiesTable.tsx +++ b/src/components/Availability/AvailabilitiesTable.tsx @@ -1,22 +1,33 @@ -import { Cell, Table } from "@codex-storage/marketplace-ui-components"; -import { TruncateCell } from "../TruncateCell/TruncateCell"; +import { Cell, Row, Table } from "@codex-storage/marketplace-ui-components"; import { PrettyBytes } from "../../utils/bytes"; import { AvailabilityActionsCell } from "./AvailabilityActionsCell"; -import { CodexAvailability } from "@codex-storage/sdk-js/async"; +import { CodexAvailability, CodexNodeSpace } from "@codex-storage/sdk-js/async"; import { Times } from "../../utils/times"; -import { useState } from "react"; +import { Fragment, useState } from "react"; import { AvailabilityReservations } from "./AvailabilityReservations"; +import { AvailabilityIdCell } from "./AvailabilityIdCell"; +import { ChevronDown } from "lucide-react"; +import "./AvailabilitiesTable.css"; +import { Arrays } from "../../utils/arrays"; +import { AvailabilitySlotRow } from "./AvailabilitySlotRow"; +import { classnames } from "../../utils/classnames"; +import { AvailabilityWithSlots } from "./types"; +import { AvailabilityDiskRow } from "./AvailabilityDiskRow"; type Props = { // onEdit: () => void; - availabilities: CodexAvailability[]; + space: CodexNodeSpace; + availabilities: AvailabilityWithSlots[]; }; -export function AvailabilitiesTable({ availabilities }: Props) { +export function AvailabilitiesTable({ availabilities, space }: Props) { const [availability, setAvailability] = useState( null ); + const [details, setDetails] = useState([]); + const headers = [ + "", "id", "total size", "duration", @@ -25,28 +36,56 @@ export function AvailabilitiesTable({ availabilities }: Props) { "actions", ]; - const onReservationsShow = (a: CodexAvailability) => setAvailability(a); - const onReservationsClose = () => setAvailability(null); - const cells = - availabilities.map((a) => { - return [ - , - , - , - , - , - , - ]; - }) || []; + const rows = availabilities.map((a, index) => { + const showDetails = details.includes(a.id); + + const onShowDetails = () => setDetails(Arrays.toggle(details, a.id)); + const hasSlots = a.slots.length > 0; + + return ( + + + {hasSlots ? ( + + ) : ( + + )} + , + , + {PrettyBytes(a.totalSize)}, + {Times.pretty(a.duration)}, + {a.minPrice.toString()}, + {a.maxCollateral.toString()}, + , + ]}> + + {a.slots.map((slot) => ( + + ))} + + ); + }); + + rows.unshift( + + ); return ( <> - +
void; - onReservationsShow: (availability: CodexAvailability) => void; }; -export function AvailabilityActionsCell({ - availability, - // onEdit, - onReservationsShow, -}: Props) { +/* eslint-disable @typescript-eslint/no-unused-vars */ +export function AvailabilityActionsCell(_: Props) { // const onEditClick = async () => { // const unit = availability.totalSize >= 1_000_000_000 ? "gb" : "mb"; // const totalSize = @@ -29,23 +26,20 @@ export function AvailabilityActionsCell({ // onEdit(); // }; - const onReservationsClick = () => onReservationsShow(availability); - return ( -
- {/* + + + + +
+ ); } diff --git a/src/components/Availability/AvailabilityContext.ts b/src/components/Availability/AvailabilityContext.ts new file mode 100644 index 0000000..7255bab --- /dev/null +++ b/src/components/Availability/AvailabilityContext.ts @@ -0,0 +1,4 @@ +import { createContext } from "react"; +import { AvailabilityWithSlots } from "./types"; + +export const AvailabilityContext = createContext(null); \ No newline at end of file diff --git a/src/components/Availability/AvailabilityDiskRow.css b/src/components/Availability/AvailabilityDiskRow.css new file mode 100644 index 0000000..d27469c --- /dev/null +++ b/src/components/Availability/AvailabilityDiskRow.css @@ -0,0 +1,10 @@ +.availabilityDiskRow { + border-bottom: 5px solid var(--codex-border-color); + background-color: var(--codex-background-light); +} + +.availabilityDiskRow-cell-content { + display: flex; + align-items: center; + gap: 1rem; +} diff --git a/src/components/Availability/AvailabilityDiskRow.tsx b/src/components/Availability/AvailabilityDiskRow.tsx new file mode 100644 index 0000000..01e7732 --- /dev/null +++ b/src/components/Availability/AvailabilityDiskRow.tsx @@ -0,0 +1,74 @@ +import { + Cell, + Row, + SimpleText, +} from "@codex-storage/marketplace-ui-components"; +import { PrettyBytes } from "../../utils/bytes"; +import "./AvailabilityDiskRow.css"; +import { classnames } from "../../utils/classnames"; + +type Props = { + bytes: number; +}; + +export function AvailabilityDiskRow({ bytes }: Props) { + return ( + + + , + +
+ +
+
+ Node +
+ + {PrettyBytes(bytes)} allocated for the node + +
+
+
, + ]}>
+ ); +} + +const HardDrive = () => ( + + + + + + + + + +); diff --git a/src/components/Availability/AvailabilityCreate.css b/src/components/Availability/AvailabilityEdit.css similarity index 100% rename from src/components/Availability/AvailabilityCreate.css rename to src/components/Availability/AvailabilityEdit.css diff --git a/src/components/Availability/AvailabilityEdit.tsx b/src/components/Availability/AvailabilityEdit.tsx new file mode 100644 index 0000000..5c8a8ed --- /dev/null +++ b/src/components/Availability/AvailabilityEdit.tsx @@ -0,0 +1,186 @@ +import { + Stepper, + useStepperReducer, + Button, + Modal, +} from "@codex-storage/marketplace-ui-components"; +import { useEffect, useRef, useState } from "react"; +import { AvailabilityForm } from "./AvailabilityForm"; +import { Pencil, Plus } from "lucide-react"; +import { CodexNodeSpace } from "@codex-storage/sdk-js"; +import { AvailabilityConfirm } from "./AvailabilityConfirmation"; +import { WebStorage } from "../../utils/web-storage"; +import { AvailabilityState } from "./types"; +import { STEPPER_DURATION } from "../../utils/constants"; +import { useAvailabilityMutation } from "./useAvailabilityMutation"; +import { AvailabilitySuccess } from "./AvailabilitySuccess"; +import { AvailabilityError } from "./AvailabilityError"; +import "./AvailabilityEdit.css"; + +type Props = { + space: CodexNodeSpace; + hasLabel?: boolean; + className?: string; +}; + +const CONFIRM_STATE = 2; + +const defaultAvailabilityData: AvailabilityState = { + totalSize: 1, + duration: 1, + minPrice: 0, + maxCollateral: 0, + totalSizeUnit: "gb", + durationUnit: "days", +}; + +export function AvailabilityEdit({ + space, + className = "", + hasLabel = true, +}: Props) { + const steps = useRef(["Sale", "Confirmation", "Success"]); + const [availability, setAvailability] = useState( + defaultAvailabilityData + ); + const { state, dispatch } = useStepperReducer(); + const { mutateAsync, error } = useAvailabilityMutation(dispatch, state); + const [availabilityId, setAvailabilityId] = useState(null); + + useEffect(() => { + Promise.all([ + WebStorage.get("availability-step"), + WebStorage.get("availability"), + ]).then(([s, a]) => { + if (s) { + dispatch({ + type: "next", + step: s, + }); + } + + if (a) { + setAvailability(a); + } + }); + }, [dispatch]); + + // We use a custom event to not re render the sunburst component + useEffect(() => { + const onAvailabilityIdChange = (e: Event) => { + const custom = e as CustomEvent; + setAvailabilityId(custom.detail); + }; + + document.addEventListener( + "codexavailabilityid", + onAvailabilityIdChange, + false + ); + + return () => + document.removeEventListener( + "codexavailabilityid", + onAvailabilityIdChange + ); + }, []); + + const components = [ + AvailabilityForm, + AvailabilityConfirm, + error ? AvailabilityError : AvailabilitySuccess, + ]; + + const onNextStep = async (step: number) => { + if (step === components.length) { + setAvailability(defaultAvailabilityData); + + dispatch({ + step: 0, + type: "next", + }); + + dispatch({ + type: "close", + }); + + return; + } + + WebStorage.set("availability-step", step); + + if (step == CONFIRM_STATE) { + mutateAsync(availability); + } else { + dispatch({ + step, + type: "next", + }); + } + }; + + const onAvailabilityChange = (data: Partial) => { + const val = { ...availability, ...data }; + + WebStorage.set("availability", val); + + setAvailability(val); + }; + + const onOpen = () => { + if (availability.id) { + WebStorage.set("availability-step", 0); + WebStorage.set("availability", defaultAvailabilityData); + + setAvailability(defaultAvailabilityData); + } + + dispatch({ + type: "open", + }); + + dispatch({ + step: 0, + type: "next", + }); + }; + + const onClose = () => dispatch({ type: "close" }); + + const Body = components[state.step] || (() => ); + const backLabel = state.step ? "Back" : "Close"; + const nextLabel = state.step === steps.current.length - 1 ? "Finish" : "Next"; + + return ( + <> +
+
); }; diff --git a/src/utils/arrays.ts b/src/utils/arrays.ts new file mode 100644 index 0000000..ab6ee1d --- /dev/null +++ b/src/utils/arrays.ts @@ -0,0 +1,4 @@ +export const Arrays = { + toggle: (arr: Array, value: T) => + arr.includes(value) ? arr.filter(i => i !== value) : [...arr, value] +} \ No newline at end of file diff --git a/src/utils/availabilities-storage.ts b/src/utils/availabilities-storage.ts new file mode 100644 index 0000000..f28bd02 --- /dev/null +++ b/src/utils/availabilities-storage.ts @@ -0,0 +1,17 @@ +import { createStore, del, get, set } from "idb-keyval"; + +const store = createStore("availabilities", "availabilities"); + +export const AvailabilityStorage = { + get(key: string) { + return get(key, store); + }, + + delete(key: string) { + return del(key, store); + }, + + async add(key: string, value: string) { + return set(key, value, store); + }, +}; diff --git a/src/utils/errors.ts b/src/utils/errors.ts new file mode 100644 index 0000000..d9830fc --- /dev/null +++ b/src/utils/errors.ts @@ -0,0 +1,33 @@ +import * as Sentry from "@sentry/browser"; +import { isCodexOnline } from "../components/NodeIndicator/NodeIndicator"; +import { CodexError } from "@codex-storage/sdk-js"; + +// It would be preferable to completely ignore the error +// when the node is not connected. However, during the +// initial load, we lack this information until the +// SPR response is completed. In the meantime, other +// requests may be initiated, so if the node is not +// connected, we should set the level to 'log'. +const getLogLevel = () => { + switch (isCodexOnline) { + case true: + return "error"; + case null: + return "info"; + case false: + return "log"; + } +}; + +export const Errors = { + report(safe: { error: true, data: CodexError }) { + Sentry.captureException(safe.data, { + extra: { + code: safe.data.code, + errors: safe.data.errors, + sourceStack: safe.data.sourceStack, + level: getLogLevel(), + }, + }); + } +} \ No newline at end of file diff --git a/src/utils/promises.ts b/src/utils/promises.ts index 2cd4ad4..467a2db 100644 --- a/src/utils/promises.ts +++ b/src/utils/promises.ts @@ -1,36 +1,11 @@ import { SafeValue } from "@codex-storage/sdk-js"; -import * as Sentry from "@sentry/browser"; -import { isCodexOnline } from "../components/NodeIndicator/NodeIndicator"; - -// It would be preferable to completely ignore the error -// when the node is not connected. However, during the -// initial load, we lack this information until the -// SPR response is completed. In the meantime, other -// requests may be initiated, so if the node is not -// connected, we should set the level to 'log'. -const getLogLevel = () => { - switch (isCodexOnline) { - case true: - return "error"; - case null: - return "info"; - case false: - return "log"; - } -}; +import { Errors } from "./errors"; export const Promises = { rejectOnError: (safe: SafeValue, report = true) => { if (safe.error) { if (report) { - Sentry.captureException(safe.data, { - extra: { - code: safe.data.code, - errors: safe.data.errors, - sourceStack: safe.data.sourceStack, - level: getLogLevel(), - }, - }); + Errors.report(safe) } return Promise.reject(safe.data);