diff --git a/CHANGELOG.md b/CHANGELOG.md index 954873cf2eb..15cde5e0a13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ As a minor extension, we have adopted a slightly different versioning convention - Added support in the `mithril-client` library for retrieving `CardanoStakeDistribution` by epoch or by hash, and for listing all available `CardanoStakeDistribution`. - Implement `CardanoStakeDistribution` commands under the `--unstable` flag in the Mithril client CLI to list all available `CardanoStakeDistribution` and to download artifact by epoch or hash. - Implement `mithril-client` library functions related to `CardanoStakeDistribution` within the WASM library. + - Add new tab Cardano Stake Distribution in the explorer. - Crates versions: diff --git a/mithril-explorer/package-lock.json b/mithril-explorer/package-lock.json index ba04ad2f5df..653c65c1c4e 100644 --- a/mithril-explorer/package-lock.json +++ b/mithril-explorer/package-lock.json @@ -1,12 +1,12 @@ { "name": "mithril-explorer", - "version": "0.7.4", + "version": "0.7.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mithril-explorer", - "version": "0.7.4", + "version": "0.7.5", "dependencies": { "@mithril-dev/mithril-client-wasm": "file:../mithril-client-wasm/pkg", "@popperjs/core": "^2.11.8", diff --git a/mithril-explorer/package.json b/mithril-explorer/package.json index d0a21025ac2..8b019bd466e 100644 --- a/mithril-explorer/package.json +++ b/mithril-explorer/package.json @@ -1,6 +1,6 @@ { "name": "mithril-explorer", - "version": "0.7.4", + "version": "0.7.5", "private": true, "scripts": { "dev": "next dev", diff --git a/mithril-explorer/src/app/page.js b/mithril-explorer/src/app/page.js index 991fce3272a..b4dd108869b 100644 --- a/mithril-explorer/src/app/page.js +++ b/mithril-explorer/src/app/page.js @@ -19,6 +19,7 @@ import initMithrilClient from "@mithril-dev/mithril-client-wasm"; import EpochSettings from "#/EpochSettings"; import PendingCertificate from "#/PendingCertificate"; import CardanoDbSnapshotsList from "#/Artifacts/CardanoDbSnapshotsList"; +import CardanoStakeDistributionsList from "#/Artifacts/CardanoStakeDistributionsList"; import CardanoTransactionsSnapshotsList from "#/Artifacts/CardanoTransactionsSnapshotsList"; import CertificatesList from "#/Artifacts/CertificatesList"; import MithrilStakeDistributionsList from "#/Artifacts/MithrilStakeDistributionsList"; @@ -50,6 +51,7 @@ export default function Explorer() { // Used to avoid infinite loop between the update of the url query and the navigation handling. const [isUpdatingAggregatorInUrl, setIsUpdatingAggregatorInUrl] = useState(false); const [enableCardanoTransactionTab, setEnableCardanoTransactionTab] = useState(false); + const [enableCardanoStakeDistributionTab, setEnableCardanoStakeDistributionTab] = useState(false); const [currentTab, setCurrentTab] = useState(defaultTab); const selectedAggregator = useSelector(currentlySelectedAggregator); const selectedAggregatorSignedEntities = useSelector((state) => @@ -60,6 +62,9 @@ export default function Explorer() { setEnableCardanoTransactionTab( selectedAggregatorSignedEntities.includes(signedEntityType.CardanoTransactions), ); + setEnableCardanoStakeDistributionTab( + selectedAggregatorSignedEntities.includes(signedEntityType.CardanoStakeDistribution), + ); }, [selectedAggregatorSignedEntities]); useEffect(() => { @@ -128,6 +133,13 @@ export default function Explorer() { )} + {enableCardanoStakeDistributionTab && ( + + + + )} diff --git a/mithril-explorer/src/components/Artifacts/CardanoStakeDistributionsList/index.js b/mithril-explorer/src/components/Artifacts/CardanoStakeDistributionsList/index.js new file mode 100644 index 00000000000..37d4dc226af --- /dev/null +++ b/mithril-explorer/src/components/Artifacts/CardanoStakeDistributionsList/index.js @@ -0,0 +1,117 @@ +import React, { useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import { Badge, Button, Card, Col, Container, ListGroup, Row, Stack } from "react-bootstrap"; +import CertificateModal from "#/CertificateModal"; +import RawJsonButton from "#/RawJsonButton"; +import LocalDateTime from "#/LocalDateTime"; +import { selectedAggregator } from "@/store/settingsSlice"; + +export default function CardanoStakeDistributionsList(props) { + const [cardanoStakeDistributions, setCardanoStakeDistributions] = useState([]); + const [selectedCertificateHash, setSelectedCertificateHash] = useState(undefined); + const aggregator = useSelector(selectedAggregator); + const artifactsEndpoint = useSelector( + (state) => `${selectedAggregator(state)}/artifact/cardano-stake-distributions`, + ); + const autoUpdate = useSelector((state) => state.settings.autoUpdate); + const updateInterval = useSelector((state) => state.settings.updateInterval); + + useEffect(() => { + if (!autoUpdate) { + return; + } + + let fetchCardanoStakeDistribution = () => { + fetch(artifactsEndpoint) + .then((response) => response.json()) + .then((data) => setCardanoStakeDistributions(data)) + .catch((error) => { + setCardanoStakeDistributions([]); + console.error("Fetch cardanoStakeDistributions error:", error); + }); + }; + + // Fetch them once without waiting + fetchCardanoStakeDistribution(); + + const interval = setInterval(fetchCardanoStakeDistribution, updateInterval); + return () => clearInterval(interval); + }, [artifactsEndpoint, updateInterval, autoUpdate]); + + function handleCertificateHashChange(hash) { + setSelectedCertificateHash(hash); + } + + function showCertificate(hash) { + setSelectedCertificateHash(hash); + } + + return ( + <> + + +
+

+ Cardano Stake Distribution{" "} + +

+ {Object.entries(cardanoStakeDistributions).length === 0 ? ( +

No cardano stake distribution available

+ ) : ( + + + {cardanoStakeDistributions.map((cardanoStakeDistribution, index) => ( + + + + {cardanoStakeDistribution.hash} + + Epoch: {cardanoStakeDistribution.epoch} + {cardanoStakeDistribution.created_at && ( + + Created:{" "} + + + )} + + Certificate hash:
+ {cardanoStakeDistribution.certificate_hash}{" "} + +
+
+
+ + + {index === 0 && ( + <> + Latest{" "} + + )} + + + + +
+ + ))} +
+
+ )} +
+ + ); +}