mirror of
https://github.com/logos-storage/logos-storage-frontend.git
synced 2026-01-02 13:23:09 +00:00
ADD storage information to node
This commit is contained in:
parent
a05e2472fa
commit
d6cc20fefa
@ -8,4 +8,4 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "3000:80"
|
- "3000:80"
|
||||||
environment:
|
environment:
|
||||||
- codex_url=${codex_url:-http://kubernetes.docker.internal:31264}
|
- codex_url=${codex_url:-http://kubernetes.docker.internal:30003}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import DataPage from "./pages/data/DataPage";
|
|||||||
import DebugPage from "./pages/debug/DebugPage";
|
import DebugPage from "./pages/debug/DebugPage";
|
||||||
import SettingsPage from "./pages/settings/SettingsPage";
|
import SettingsPage from "./pages/settings/SettingsPage";
|
||||||
import MarketplacePage from "./pages/marketplace/Marketplace";
|
import MarketplacePage from "./pages/marketplace/Marketplace";
|
||||||
|
import NodeInfoPage from "./pages/node/NodePage";
|
||||||
|
|
||||||
function PlacehoderPage(props: { name: string }) {
|
function PlacehoderPage(props: { name: string }) {
|
||||||
return (
|
return (
|
||||||
@ -29,7 +30,7 @@ export default function App() {
|
|||||||
<Route path="/settings" element={<SettingsPage />} />
|
<Route path="/settings" element={<SettingsPage />} />
|
||||||
<Route path="/marketplace" element={<MarketplacePage/>}/>
|
<Route path="/marketplace" element={<MarketplacePage/>}/>
|
||||||
<Route path="/" element={<DataPage />} />
|
<Route path="/" element={<DataPage />} />
|
||||||
<Route path="/node" element={PlacehoderPage({ name: "Node" })} />
|
<Route path="/node" element={<NodeInfoPage/>} />
|
||||||
<Route path="/debug" element={DebugPage()} />
|
<Route path="/debug" element={DebugPage()} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|
||||||
|
|||||||
147
frontend/src/components/debugInfoItem/debugInfoItem.tsx
Normal file
147
frontend/src/components/debugInfoItem/debugInfoItem.tsx
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import React from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { DebugNodeInfoModel } from "../../data/models/DebugNodeInfoModel";
|
||||||
|
import DropDownList from "../layout/dropDownList/DropDownList";
|
||||||
|
|
||||||
|
function NodeInfoItemComponent(props: {
|
||||||
|
data: DebugNodeInfoModel | undefined;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
(props.data && (
|
||||||
|
<NodeInfoItemComponentWrapper>
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>Adresses: </span>
|
||||||
|
{props.data.addrs.join(", ")}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span>Codex Version: </span>
|
||||||
|
{`${props.data.codex.version} (${props.data.codex.revision})`}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>ID: </span>
|
||||||
|
{props.data.id}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>SPR: </span>
|
||||||
|
{props.data.spr}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3>Local Node</h3>
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>Address: </span>
|
||||||
|
{props.data.table.localNode.address}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span>Node ID: </span>
|
||||||
|
{props.data.table.localNode.nodeId}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>Peer ID: </span>
|
||||||
|
{props.data.table.localNode.peerId}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span>Seen: </span>
|
||||||
|
{`${props.data.table.localNode.seen
|
||||||
|
.toString()[0]
|
||||||
|
.toUpperCase()}${props.data.table.localNode.seen
|
||||||
|
.toString()
|
||||||
|
.slice(1)}`}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DropDownList title="Nodes">
|
||||||
|
{props.data.table.nodes.map((node, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<h3>Node {index + 1}</h3>
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>Address: </span>
|
||||||
|
{node.address}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span>Node ID: </span>
|
||||||
|
{node.nodeId}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>Peer ID: </span>
|
||||||
|
{node.peerId}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span>Seen: </span>
|
||||||
|
{`${node.seen.toString()[0].toUpperCase()}${node.seen
|
||||||
|
.toString()
|
||||||
|
.slice(1)}`}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</DropDownList>
|
||||||
|
<DropDownList title="Record">
|
||||||
|
<div id="info-row">
|
||||||
|
<p>
|
||||||
|
<span>Record: </span>
|
||||||
|
{props.data.table.localNode.record}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</DropDownList>
|
||||||
|
</NodeInfoItemComponentWrapper>
|
||||||
|
)) || <></>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NodeInfoItemComponent;
|
||||||
|
|
||||||
|
const NodeInfoItemComponentWrapper = styled.div`
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
#info-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
padding: 8px;
|
||||||
|
margin: 5px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
div p:nth-child(1) {
|
||||||
|
text-align: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
div p:nth-child(2) {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-align: start;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
p span {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cid {
|
||||||
|
flex: 2;
|
||||||
|
}
|
||||||
|
`;
|
||||||
@ -1,104 +1,38 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { DebugNodeInfoModel } from "../../data/models/DebugNodeInfoModel";
|
import { NodeInfoModel } from "../../data/models/NodeInfoModel";
|
||||||
import DropDownList from "../layout/dropDownList/DropDownList";
|
import DropDownList from "../layout/dropDownList/DropDownList";
|
||||||
|
|
||||||
function NodeInfoItemComponent(props: {
|
function NodeInfoItemComponent(props: {
|
||||||
data: DebugNodeInfoModel | undefined;
|
data: NodeInfoModel | undefined;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
(props.data && (
|
(props.data && (
|
||||||
<NodeInfoItemComponentWrapper>
|
<NodeInfoItemComponentWrapper>
|
||||||
<div id="info-row">
|
<div id="info-row">
|
||||||
<p>
|
<p>
|
||||||
<span>Adresses: </span>
|
<span>TotalBlocks: </span>
|
||||||
{props.data.addrs.join(", ")}
|
{props.data.totalBlocks}
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span>Codex Version: </span>
|
|
||||||
{`${props.data.codex.version} (${props.data.codex.revision})`}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="info-row">
|
<div id="info-row">
|
||||||
<p>
|
<p>
|
||||||
<span>ID: </span>
|
<span>QuotaMaxBytes: </span>
|
||||||
{props.data.id}
|
{props.data.quotaMaxBytes}
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span>Repo: </span>
|
|
||||||
{props.data.repo}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="info-row">
|
<div id="info-row">
|
||||||
<p>
|
<p>
|
||||||
<span>SPR: </span>
|
<span>QuotaUsedBytes: </span>
|
||||||
{props.data.spr}
|
{props.data.quotaUsedBytes}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div id="info-row">
|
||||||
<h3>Local Node</h3>
|
<p>
|
||||||
<div id="info-row">
|
<span>QuotaReservedBytes: </span>
|
||||||
<p>
|
{props.data.quotaReservedBytes}
|
||||||
<span>Address: </span>
|
</p>
|
||||||
{props.data.table.localNode.address}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span>Node ID: </span>
|
|
||||||
{props.data.table.localNode.nodeId}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div id="info-row">
|
|
||||||
<p>
|
|
||||||
<span>Peer ID: </span>
|
|
||||||
{props.data.table.localNode.peerId}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span>Seen: </span>
|
|
||||||
{`${props.data.table.localNode.seen
|
|
||||||
.toString()[0]
|
|
||||||
.toUpperCase()}${props.data.table.localNode.seen
|
|
||||||
.toString()
|
|
||||||
.slice(1)}`}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<DropDownList title="Nodes">
|
|
||||||
{props.data.table.nodes.map((node, index) => (
|
|
||||||
<div key={index}>
|
|
||||||
<h3>Node {index + 1}</h3>
|
|
||||||
<div id="info-row">
|
|
||||||
<p>
|
|
||||||
<span>Address: </span>
|
|
||||||
{node.address}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span>Node ID: </span>
|
|
||||||
{node.nodeId}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div id="info-row">
|
|
||||||
<p>
|
|
||||||
<span>Peer ID: </span>
|
|
||||||
{node.peerId}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span>Seen: </span>
|
|
||||||
{`${node.seen.toString()[0].toUpperCase()}${node.seen
|
|
||||||
.toString()
|
|
||||||
.slice(1)}`}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</DropDownList>
|
|
||||||
<DropDownList title="Record">
|
|
||||||
<div id="info-row">
|
|
||||||
<p>
|
|
||||||
<span>Record: </span>
|
|
||||||
{props.data.table.localNode.record}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</DropDownList>
|
|
||||||
</NodeInfoItemComponentWrapper>
|
</NodeInfoItemComponentWrapper>
|
||||||
)) || <></>
|
)) || <></>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -4,6 +4,7 @@ type AvailabilityModel = {
|
|||||||
duration: string;
|
duration: string;
|
||||||
minPrice: string;
|
minPrice: string;
|
||||||
maxCollateral: string;
|
maxCollateral: string;
|
||||||
|
expiry: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AvailabilityModel;
|
export default AvailabilityModel;
|
||||||
12
frontend/src/data/models/NodeInfoModel.ts
Normal file
12
frontend/src/data/models/NodeInfoModel.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export interface NodeInfoModel {
|
||||||
|
totalBlocks: number;
|
||||||
|
quotaMaxBytes: number;
|
||||||
|
quotaUsedBytes: number;
|
||||||
|
quotaReservedBytes: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Convert {
|
||||||
|
public static toNodeInfoModel(json: string): NodeInfoModel {
|
||||||
|
return JSON.parse(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@ import {
|
|||||||
Convert,
|
Convert,
|
||||||
DebugNodeInfoModel,
|
DebugNodeInfoModel,
|
||||||
} from "../../data/models/DebugNodeInfoModel";
|
} from "../../data/models/DebugNodeInfoModel";
|
||||||
import NodeInfoItemComponent from "../../components/nodeInfoItem/NodeInfoItemComponent";
|
import NodeInfoItemComponent from "../../components/debugInfoItem/debugInfoItem";
|
||||||
import Header from "../../components/layout/partials/Header";
|
import Header from "../../components/layout/partials/Header";
|
||||||
import { useDexyStore } from "../../store";
|
import { useDexyStore } from "../../store";
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ function OfferStorage() {
|
|||||||
const [duration, setDuration,] = useState("file");
|
const [duration, setDuration,] = useState("file");
|
||||||
const [minPrice, setMinPrice,] = useState("file");
|
const [minPrice, setMinPrice,] = useState("file");
|
||||||
const [maxCollateral, setMaxCollateral,] = useState("file");
|
const [maxCollateral, setMaxCollateral,] = useState("file");
|
||||||
|
const [expiry, setExpiry,] = useState("file");
|
||||||
|
|
||||||
|
|
||||||
function upload(cid: string) {
|
function upload(cid: string) {
|
||||||
@ -27,7 +28,8 @@ function OfferStorage() {
|
|||||||
size: size,
|
size: size,
|
||||||
duration: duration,
|
duration: duration,
|
||||||
minPrice: minPrice,
|
minPrice: minPrice,
|
||||||
maxCollateral: maxCollateral
|
maxCollateral: maxCollateral,
|
||||||
|
expiry: expiry
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -75,6 +77,12 @@ function OfferStorage() {
|
|||||||
placeholder="MaxCollateral"
|
placeholder="MaxCollateral"
|
||||||
onChange={(e) => setMaxCollateral(e.target.value)}
|
onChange={(e) => setMaxCollateral(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
<div id="divider"></div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Expiry"
|
||||||
|
onChange={(e) => setExpiry(e.target.value)}
|
||||||
|
/>
|
||||||
<button onClick={() => upload(ftdCid)}>Download</button>
|
<button onClick={() => upload(ftdCid)}>Download</button>
|
||||||
</OfferStorageWrapper>
|
</OfferStorageWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
69
frontend/src/pages/node/NodePage.tsx
Normal file
69
frontend/src/pages/node/NodePage.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
import {
|
||||||
|
Convert,
|
||||||
|
NodeInfoModel,
|
||||||
|
} from "../../data/models/NodeInfoModel";
|
||||||
|
import NodeInfoItemComponent from "../../components/nodeInfoItem/NodeInfoItemComponent";
|
||||||
|
import Header from "../../components/layout/partials/Header";
|
||||||
|
import { useDexyStore } from "../../store";
|
||||||
|
|
||||||
|
function NodeInfoPage() {
|
||||||
|
const { nodeInfo } = useDexyStore();
|
||||||
|
|
||||||
|
const [statusInfo, setStatusInfo] = React.useState<
|
||||||
|
NodeInfoModel | undefined
|
||||||
|
>();
|
||||||
|
useEffect(() => {
|
||||||
|
axios
|
||||||
|
.get(
|
||||||
|
`/api/codex/v1/space`,
|
||||||
|
{
|
||||||
|
headers:
|
||||||
|
(nodeInfo.auth && {
|
||||||
|
Authorization:
|
||||||
|
(nodeInfo.auth && "Basic " + btoa(nodeInfo.auth)) || "",
|
||||||
|
}) ||
|
||||||
|
{},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
setStatusInfo(
|
||||||
|
Convert.toNodeInfoModel(JSON.stringify(response.data))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}, [nodeInfo]);
|
||||||
|
|
||||||
|
console.log(statusInfo);
|
||||||
|
return (
|
||||||
|
<NodeInfoPageWrapper>
|
||||||
|
<Header title="Node Info" />
|
||||||
|
<main>{statusInfo && <NodeInfoItemComponent data={statusInfo!!} />}</main>
|
||||||
|
</NodeInfoPageWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NodeInfoPage;
|
||||||
|
|
||||||
|
const NodeInfoPageWrapper = styled.div`
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
main {
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll {
|
||||||
|
}
|
||||||
|
`;
|
||||||
Loading…
x
Reference in New Issue
Block a user