Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mithril-explorer/__tests__/AggregatorSetter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import { initStore } from "./helpers";
import { Provider } from "react-redux";
import AggregatorSetter from "#/AggregatorSetter";
import AggregatorSetter from "#/ControlPanel/AggregatorSetter";
import default_available_aggregators from "@/aggregators-list";
import { settingsSlice } from "@/store/settingsSlice";

Expand Down
43 changes: 33 additions & 10 deletions mithril-explorer/__tests__/store.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import default_available_aggregators from "@/aggregators-list";
import { signedEntityType } from "@/constants";
import { poolsSlice } from "@/store/poolsSlice";
import {
changeRefreshSeed,
removeSelectedAggregator,
selectAggregator,
settingsSlice,
setUpdateInterval,
toggleAutoUpdate,
} from "@/store/settingsSlice";
import { saveToLocalStorage, storeBuilder } from "@/store/store";
import { waitFor } from "@testing-library/react";
Expand Down Expand Up @@ -67,24 +67,47 @@ describe("Store Initialization", () => {
expect(store.getState()).toEqual(expected);
});

it("Can toggle autoUpdate", () => {
const store = initStore();

store.dispatch(toggleAutoUpdate());
expect(store.getState().settings.autoUpdate).toEqual(false);
it("Can change refreshSeed", () => {
const initialSeed = 123;
const store = initStore({
settings: {
refreshSeed: initialSeed,
...settingsSlice.getInitialState(),
},
});

store.dispatch(toggleAutoUpdate());
expect(store.getState().settings.autoUpdate).toEqual(true);
store.dispatch(changeRefreshSeed());
expect(store.getState().settings.refreshSeed).not.toEqual(initialSeed);
});

it("Can change updateInterval", () => {
const store = initStore();
it("Set updateInterval to a number", () => {
const store = initStore({
settings: {
updateInterval: 0,
...settingsSlice.getInitialState(),
},
});
const expected = 124325;

store.dispatch(setUpdateInterval(expected));
expect(store.getState().settings.updateInterval).toEqual(expected);
});

it.each(["string", 1.123, "143", null, undefined])(
"Set updateInterval to something that is not an integer should yield undefined ('%s')",
(value) => {
const store = initStore({
settings: {
updateInterval: 1000,
...settingsSlice.getInitialState(),
},
});

store.dispatch(setUpdateInterval(value));
expect(store.getState().settings.updateInterval).toEqual(undefined);
},
);

it("Can change selectedAggregator", () => {
const store = initStore();
const expected = default_available_aggregators[2];
Expand Down
4 changes: 2 additions & 2 deletions mithril-explorer/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mithril-explorer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mithril-explorer",
"version": "0.7.17",
"version": "0.7.18",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
22 changes: 3 additions & 19 deletions mithril-explorer/src/app/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useSearchParams } from "next/navigation";
import dynamic from "next/dynamic";
import { Form, Row, Stack, Tab, Tabs } from "react-bootstrap";
import { Stack, Tab, Tabs } from "react-bootstrap";
import {
ArcElement,
BarElement,
Expand All @@ -16,6 +15,7 @@ import {
Tooltip,
} from "chart.js";
import initMithrilClient from "@mithril-dev/mithril-client-wasm";
import ControlPanel from "#/ControlPanel";
import CardanoDbSnapshotsList from "#/Artifacts/CardanoDbSnapshotsList";
import CardanoStakeDistributionsList from "#/Artifacts/CardanoStakeDistributionsList";
import CardanoTransactionsSnapshotsList from "#/Artifacts/CardanoTransactionsSnapshotsList";
Expand All @@ -29,14 +29,6 @@ import {
selectedAggregatorSignedEntities as currentAggregatorSignedEntities,
} from "@/store/settingsSlice";
import { updatePoolsForAggregator } from "@/store/poolsSlice";
import AggregatorStatus from "@/components/AggregatorStatus";

// Disable SSR for the following components since they use data from the store that are not
// available server sides (because those data can be read from the local storage).
const AggregatorSetter = dynamic(() => import("#/AggregatorSetter"), { ssr: false });
const IntervalSetter = dynamic(() => import("#/IntervalSetter"), {
ssr: false,
});

Chart.register(ArcElement, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);
setChartJsDefaults(Chart);
Expand Down Expand Up @@ -109,15 +101,7 @@ export default function Explorer() {

return (
<Stack gap={3}>
<Form>
<Row xs={1} sm={2} className="row-gap-2">
<AggregatorSetter />
<IntervalSetter />
</Row>
</Form>
<Stack direction="horizontal">
<AggregatorStatus />
</Stack>
<ControlPanel />
<Tabs activeKey={currentTab} onSelect={(key) => setCurrentTab(key)}>
<Tab title="Cardano Db" eventKey={signedEntityType.CardanoImmutableFilesFull}>
<CardanoDbSnapshotsList />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function CardanoDbSnapshotsList(props) {
const artifactsEndpoint = useSelector(
(state) => `${selectedAggregator(state)}/artifact/snapshots`,
);
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
const refreshSeed = useSelector((state) => state.settings.refreshSeed);
const updateInterval = useSelector((state) => state.settings.updateInterval);

useEffect(() => {
Expand All @@ -31,11 +31,11 @@ export default function CardanoDbSnapshotsList(props) {
// Fetch them once without waiting
fetchSnapshots();

if (autoUpdate) {
if (updateInterval) {
const interval = setInterval(fetchSnapshots, updateInterval);
return () => clearInterval(interval);
}
}, [artifactsEndpoint, updateInterval, autoUpdate]);
}, [artifactsEndpoint, updateInterval, refreshSeed]);

function handleCertificateHashChange(hash) {
setSelectedCertificateHash(hash);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function CardanoStakeDistributionsList(props) {
const artifactsEndpoint = useSelector(
(state) => `${selectedAggregator(state)}/artifact/cardano-stake-distributions`,
);
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
const refreshSeed = useSelector((state) => state.settings.refreshSeed);
const updateInterval = useSelector((state) => state.settings.updateInterval);

useEffect(() => {
Expand All @@ -30,11 +30,11 @@ export default function CardanoStakeDistributionsList(props) {
// Fetch them once without waiting
fetchCardanoStakeDistribution();

if (autoUpdate) {
if (updateInterval) {
const interval = setInterval(fetchCardanoStakeDistribution, updateInterval);
return () => clearInterval(interval);
}
}, [artifactsEndpoint, updateInterval, autoUpdate]);
}, [artifactsEndpoint, updateInterval, refreshSeed]);

function handleCertificateHashChange(hash) {
setSelectedCertificateHash(hash);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function CardanoTransactionsSnapshotsList(props) {
const artifactsEndpoint = useSelector(
(state) => `${selectedAggregator(state)}/artifact/cardano-transactions`,
);
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
const refreshSeed = useSelector((state) => state.settings.refreshSeed);
const updateInterval = useSelector((state) => state.settings.updateInterval);
const currentAggregatorCapabilities = useSelector((state) =>
selectedAggregatorCapabilities(state),
Expand All @@ -38,11 +38,11 @@ export default function CardanoTransactionsSnapshotsList(props) {
// Fetch them once without waiting
fetchSnapshots();

if (autoUpdate) {
if (updateInterval) {
const interval = setInterval(fetchSnapshots, updateInterval);
return () => clearInterval(interval);
}
}, [artifactsEndpoint, updateInterval, autoUpdate]);
}, [artifactsEndpoint, updateInterval, refreshSeed]);

function handleCertificateHashChange(hash) {
setSelectedCertificateHash(hash);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function CertificatesList(props) {
const [selectedCertificateHash, setSelectedCertificateHash] = useState(undefined);
const aggregator = useSelector(selectedAggregator);
const certificatesEndpoint = useSelector((state) => `${selectedAggregator(state)}/certificates`);
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
const refreshSeed = useSelector((state) => state.settings.refreshSeed);
const updateInterval = useSelector((state) => state.settings.updateInterval);

useEffect(() => {
Expand All @@ -29,11 +29,11 @@ export default function CertificatesList(props) {
// Fetch them once without waiting
fetchCertificates();

if (autoUpdate) {
if (updateInterval) {
const interval = setInterval(fetchCertificates, updateInterval);
return () => clearInterval(interval);
}
}, [certificatesEndpoint, updateInterval, autoUpdate]);
}, [certificatesEndpoint, updateInterval, refreshSeed]);

function handleCertificateHashChange(hash) {
setSelectedCertificateHash(hash);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function MithrilStakeDistributionsList(props) {
const artifactsEndpoint = useSelector(
(state) => `${selectedAggregator(state)}/artifact/mithril-stake-distributions`,
);
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
const refreshSeed = useSelector((state) => state.settings.refreshSeed);
const updateInterval = useSelector((state) => state.settings.updateInterval);

useEffect(() => {
Expand All @@ -30,11 +30,11 @@ export default function MithrilStakeDistributionsList(props) {
// Fetch them once without waiting
fetchMithrilStakeDistribution();

if (autoUpdate) {
if (updateInterval) {
const interval = setInterval(fetchMithrilStakeDistribution, updateInterval);
return () => clearInterval(interval);
}
}, [artifactsEndpoint, updateInterval, autoUpdate]);
}, [artifactsEndpoint, updateInterval, refreshSeed]);

function handleCertificateHashChange(hash) {
setSelectedCertificateHash(hash);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ export default function AggregatorSetter(props) {
<>
<AddAggregatorModal show={showAddModal} onAskClose={() => toggleAddModal(false)} />

<Form.Group as={Col} className={props.className}>
<Form.Label>Aggregator:</Form.Label>
<Form.Group as={Col} {...props}>
<InputGroup>
<Button variant="outline-success" onClick={() => toggleAddModal(true)}>
<i className="bi bi-plus-circle"></i>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Tooltip,
} from "react-bootstrap";
import { useSelector } from "react-redux";
import EpochSettings from "#/EpochSettings";
import EpochSettings from "#/ControlPanel/EpochSettings";
import LinkButton from "#/LinkButton";
import RawJsonButton from "#/RawJsonButton";
import ProtocolParameters from "#/ProtocolParameters";
Expand Down Expand Up @@ -55,17 +55,16 @@ function PercentTooltip({ value, total, ...props }) {
);
}

export default function AggregatorStatus() {
export default function AggregatorStatus({ showContent = true }) {
const [aggregatorStatus, setAggregatorStatus] = useState({});
const [aggregatorVersion, setAggregatorVersion] = useState({});
const currentAggregator = useSelector((state) => state.settings.selectedAggregator);
const aggregatorStatusEndpoint = useSelector((state) => `${selectedAggregator(state)}/status`);
const [registrationPageUrl, setRegistrationPageUrl] = useState(undefined);
const [inOutRegistrationsPageUrl, setInOutRegistrationsPageUrl] = useState(undefined);
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
const refreshSeed = useSelector((state) => state.settings.refreshSeed);
const updateInterval = useSelector((state) => state.settings.updateInterval);
const [fallbackToEpochSetting, setFallbackToEpochSetting] = useState(false);
const [showContent, setShowContent] = useState(true);

useEffect(() => {
let fetchAggregatorStatus = () => {
Expand All @@ -86,13 +85,11 @@ export default function AggregatorStatus() {
// Fetch it once without waiting
fetchAggregatorStatus();

if (autoUpdate) {
const interval = setInterval(() => {
fetchAggregatorStatus();
}, updateInterval);
if (updateInterval) {
const interval = setInterval(fetchAggregatorStatus, updateInterval);
return () => clearInterval(interval);
}
}, [aggregatorStatusEndpoint, updateInterval, autoUpdate]);
}, [aggregatorStatusEndpoint, updateInterval, refreshSeed]);

useEffect(() => {
if (!checkUrl(currentAggregator)) {
Expand Down Expand Up @@ -128,19 +125,15 @@ export default function AggregatorStatus() {
}

return fallbackToEpochSetting ? (
<EpochSettings />
<Stack direction="horizontal">
<Collapse in={showContent}>
<div id="contentRow">
<EpochSettings />
</div>
</Collapse>
</Stack>
) : (
<Container fluid>
<h3>
<a
role="button"
onClick={() => setShowContent(!showContent)}
aria-expanded={showContent}
aria-controls="contentRow">
Aggregator Status <i className={`bi bi-chevron-${showContent ? "up" : "down"}`}></i>
</a>
</h3>

<Collapse in={showContent}>
<div id="contentRow">
<Row className="d-flex flex-wrap justify-content-md-center">
Expand Down
Loading