mirror of
https://github.com/logos-storage/logos-storage-frontend.git
synced 2026-01-02 05:13:13 +00:00
ADD storage information to node
This commit is contained in:
parent
a05e2472fa
commit
d6cc20fefa
@ -8,4 +8,4 @@ services:
|
||||
ports:
|
||||
- "3000:80"
|
||||
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 SettingsPage from "./pages/settings/SettingsPage";
|
||||
import MarketplacePage from "./pages/marketplace/Marketplace";
|
||||
import NodeInfoPage from "./pages/node/NodePage";
|
||||
|
||||
function PlacehoderPage(props: { name: string }) {
|
||||
return (
|
||||
@ -29,7 +30,7 @@ export default function App() {
|
||||
<Route path="/settings" element={<SettingsPage />} />
|
||||
<Route path="/marketplace" element={<MarketplacePage/>}/>
|
||||
<Route path="/" element={<DataPage />} />
|
||||
<Route path="/node" element={PlacehoderPage({ name: "Node" })} />
|
||||
<Route path="/node" element={<NodeInfoPage/>} />
|
||||
<Route path="/debug" element={DebugPage()} />
|
||||
</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 styled from "styled-components";
|
||||
import { DebugNodeInfoModel } from "../../data/models/DebugNodeInfoModel";
|
||||
import { NodeInfoModel } from "../../data/models/NodeInfoModel";
|
||||
import DropDownList from "../layout/dropDownList/DropDownList";
|
||||
|
||||
function NodeInfoItemComponent(props: {
|
||||
data: DebugNodeInfoModel | undefined;
|
||||
data: NodeInfoModel | 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})`}
|
||||
<span>TotalBlocks: </span>
|
||||
{props.data.totalBlocks}
|
||||
</p>
|
||||
</div>
|
||||
<div id="info-row">
|
||||
<p>
|
||||
<span>ID: </span>
|
||||
{props.data.id}
|
||||
</p>
|
||||
<p>
|
||||
<span>Repo: </span>
|
||||
{props.data.repo}
|
||||
<span>QuotaMaxBytes: </span>
|
||||
{props.data.quotaMaxBytes}
|
||||
</p>
|
||||
</div>
|
||||
<div id="info-row">
|
||||
<p>
|
||||
<span>SPR: </span>
|
||||
{props.data.spr}
|
||||
<span>QuotaUsedBytes: </span>
|
||||
{props.data.quotaUsedBytes}
|
||||
</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 id="info-row">
|
||||
<p>
|
||||
<span>QuotaReservedBytes: </span>
|
||||
{props.data.quotaReservedBytes}
|
||||
</p>
|
||||
</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>
|
||||
)) || <></>
|
||||
);
|
||||
|
||||
@ -4,6 +4,7 @@ type AvailabilityModel = {
|
||||
duration: string;
|
||||
minPrice: string;
|
||||
maxCollateral: string;
|
||||
expiry: string;
|
||||
};
|
||||
|
||||
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,
|
||||
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 { useDexyStore } from "../../store";
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ function OfferStorage() {
|
||||
const [duration, setDuration,] = useState("file");
|
||||
const [minPrice, setMinPrice,] = useState("file");
|
||||
const [maxCollateral, setMaxCollateral,] = useState("file");
|
||||
const [expiry, setExpiry,] = useState("file");
|
||||
|
||||
|
||||
function upload(cid: string) {
|
||||
@ -27,7 +28,8 @@ function OfferStorage() {
|
||||
size: size,
|
||||
duration: duration,
|
||||
minPrice: minPrice,
|
||||
maxCollateral: maxCollateral
|
||||
maxCollateral: maxCollateral,
|
||||
expiry: expiry
|
||||
})
|
||||
}
|
||||
)
|
||||
@ -75,6 +77,12 @@ function OfferStorage() {
|
||||
placeholder="MaxCollateral"
|
||||
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>
|
||||
</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