feat:
--GUI CHANGE(NodeDetailsDashboard)
This commit is contained in:
1 parent
14e6981853
commit
9543a22b1a
3 files changed
+187
-59
No files matched your search
+150
@@ -883,3 +883,153 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Proportional spacing with readable text limits on very large/small screens. */
|
||||||
|
.main-content:has(.node-details-page) {
|
||||||
|
padding: 1.2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-details-page {
|
||||||
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
|
container-type: inline-size;
|
||||||
|
font-size: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-details-page > .page-header {
|
||||||
|
gap: 1%;
|
||||||
|
margin-bottom: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-details-page > .page-header h1 {
|
||||||
|
font-size: clamp(1.25rem, 2.2cqw, 1.75rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-details-page .secondary-button {
|
||||||
|
min-height: 2.2em;
|
||||||
|
padding: 0.35em 0.8em;
|
||||||
|
font-size: clamp(0.65rem, 0.9cqw, 0.75rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
column-gap: 0.8%;
|
||||||
|
row-gap: 0.8cqw;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard > section {
|
||||||
|
min-width: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 2.5%;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 5px;
|
||||||
|
background: var(--bg);
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard .page-header {
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.3em 2%;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
padding-bottom: 2%;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard h2 {
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
font-size: clamp(0.7rem, 1cqw, 0.85rem);
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard p,
|
||||||
|
.node-metrics-dashboard a {
|
||||||
|
font-size: clamp(0.625rem, 0.8cqw, 0.7rem);
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard .page-actions {
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard .database-connection-metrics {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
column-gap: 2%;
|
||||||
|
row-gap: 0.35cqw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard .database-connection-metric {
|
||||||
|
min-width: 0;
|
||||||
|
gap: 0.2em;
|
||||||
|
padding: 4%;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard .database-connection-metric h3 {
|
||||||
|
font-size: clamp(0.625rem, 0.8cqw, 0.7rem);
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard .database-connection-metric strong {
|
||||||
|
font-size: clamp(0.9rem, 1.3cqw, 1.15rem);
|
||||||
|
line-height: 1.2;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-replication-panel {
|
||||||
|
grid-column: span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-replication-panel .nodes-table-wrap {
|
||||||
|
margin-top: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-replication-panel .nodes-table {
|
||||||
|
min-width: 0;
|
||||||
|
font-size: clamp(0.625rem, 0.8cqw, 0.7rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-replication-panel .nodes-table th,
|
||||||
|
.node-replication-panel .nodes-table td,
|
||||||
|
.node-replication-panel .nodes-table caption {
|
||||||
|
padding: 1% 1.5%;
|
||||||
|
font-size: inherit;
|
||||||
|
white-space: normal;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-metrics-dashboard .status-message {
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-width: 100%;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
padding: 1% 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@container (min-width: 1200px) {
|
||||||
|
.node-metrics-dashboard {
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@container (max-width: 780px) {
|
||||||
|
.node-metrics-dashboard {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
row-gap: 1.2cqw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@container (max-width: 460px) {
|
||||||
|
.node-metrics-dashboard {
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
row-gap: 2cqw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-replication-panel {
|
||||||
|
grid-column: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-59
@@ -1,16 +1,8 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Navigate, Route, Routes, useMatch, useNavigate, useParams } from 'react-router-dom'
|
import { Navigate, Route, Routes, useMatch, useNavigate, useParams } from 'react-router-dom'
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import NodeConnections from './NodeConnections'
|
import NodeDetailsDashboard from './NodeDetailsDashboard'
|
||||||
import NodeActiveConnections from './NodeActiveConnections'
|
|
||||||
import NodePerformance from './NodePerformance'
|
|
||||||
import NodeTupleActivity from './NodeTupleActivity'
|
|
||||||
import NodeWalGenerated from './NodeWalGenerated'
|
|
||||||
import NodeWalSize from './NodeWalSize'
|
|
||||||
import NodeDeadTuples from './NodeDeadTuples'
|
import NodeDeadTuples from './NodeDeadTuples'
|
||||||
import NodeLocksDeadlocks from './NodeLocksDeadlocks'
|
|
||||||
import NodeDatabaseSize from './NodeDatabaseSize'
|
|
||||||
import NodeIndexSize from './NodeIndexSize'
|
|
||||||
import NodeLargestTables from './NodeLargestTables'
|
import NodeLargestTables from './NodeLargestTables'
|
||||||
import NodeHardware from './NodeHardware'
|
import NodeHardware from './NodeHardware'
|
||||||
import ClusterNodeCard from './ClusterNodeCard'
|
import ClusterNodeCard from './ClusterNodeCard'
|
||||||
@@ -619,7 +611,7 @@ function Workspace({ page: activePage }: { page: PageId | 'node-details' | 'larg
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{activePage === 'node-details' && clusterDetails && (
|
{activePage === 'node-details' && clusterDetails && (
|
||||||
<section className="content-panel" id="node-details">
|
<section className="content-panel node-details-page" id="node-details">
|
||||||
<div className="page-header">
|
<div className="page-header">
|
||||||
<h1>{clusterDetails.nodes.find((node) => node.uuid === nodeId)?.node_name ?? 'Node not found'}</h1>
|
<h1>{clusterDetails.nodes.find((node) => node.uuid === nodeId)?.node_name ?? 'Node not found'}</h1>
|
||||||
<button
|
<button
|
||||||
@@ -631,55 +623,12 @@ function Workspace({ page: activePage }: { page: PageId | 'node-details' | 'larg
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{nodeId && clusterDetails.nodes.some((node) => node.uuid === nodeId) && (
|
{nodeId && clusterDetails.nodes.some((node) => node.uuid === nodeId) && (
|
||||||
<>
|
<NodeDetailsDashboard
|
||||||
<NodeActiveConnections
|
key={`${clusterId}/${nodeId}`}
|
||||||
key={`metrics/${clusterId}/${nodeId}`}
|
clusterId={clusterId!}
|
||||||
nodeId={nodeId}
|
nodeId={nodeId}
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
||||||
/>
|
/>
|
||||||
<NodePerformance
|
|
||||||
key={`performance/${clusterId}/${nodeId}`}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeTupleActivity
|
|
||||||
key={`tuple-activity/${clusterId}/${nodeId}`}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeWalGenerated
|
|
||||||
key={`wal-generated/${clusterId}/${nodeId}`}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeWalSize
|
|
||||||
key={`wal-size/${clusterId}/${nodeId}`}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeDeadTuples
|
|
||||||
key={`dead-tuples/${clusterId}/${nodeId}`}
|
|
||||||
clusterId={clusterId!}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeLocksDeadlocks
|
|
||||||
key={`locks-deadlocks/${clusterId}/${nodeId}`}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeDatabaseSize
|
|
||||||
key={`database-size/${clusterId}/${nodeId}`}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeIndexSize
|
|
||||||
key={`index-size/${clusterId}/${nodeId}`}
|
|
||||||
nodeId={nodeId}
|
|
||||||
nodeName={clusterDetails.nodes.find((node) => node.uuid === nodeId)!.node_name}
|
|
||||||
/>
|
|
||||||
<NodeConnections key={`${clusterId}/${nodeId}`} nodeId={nodeId} />
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import NodeActiveConnections from './NodeActiveConnections'
|
||||||
|
import NodePerformance from './NodePerformance'
|
||||||
|
import NodeDatabaseSize from './NodeDatabaseSize'
|
||||||
|
import NodeIndexSize from './NodeIndexSize'
|
||||||
|
import NodeTupleActivity from './NodeTupleActivity'
|
||||||
|
import NodeWalGenerated from './NodeWalGenerated'
|
||||||
|
import NodeWalSize from './NodeWalSize'
|
||||||
|
import NodeDeadTuples from './NodeDeadTuples'
|
||||||
|
import NodeLocksDeadlocks from './NodeLocksDeadlocks'
|
||||||
|
import NodeConnections from './NodeConnections'
|
||||||
|
|
||||||
|
export default function NodeDetailsDashboard(props: { nodeId: string; nodeName: string; clusterId: string }) {
|
||||||
|
return (
|
||||||
|
<section className="node-metrics-dashboard" aria-label="Node details dashboard">
|
||||||
|
<NodeActiveConnections {...props} />
|
||||||
|
<NodePerformance {...props} />
|
||||||
|
<NodeTupleActivity {...props} />
|
||||||
|
<NodeDatabaseSize {...props} />
|
||||||
|
<NodeIndexSize {...props} />
|
||||||
|
<NodeWalGenerated {...props} />
|
||||||
|
<NodeWalSize {...props} />
|
||||||
|
<NodeLocksDeadlocks {...props} />
|
||||||
|
<NodeDeadTuples {...props} />
|
||||||
|
<section className="node-replication-panel" aria-label="Replication connections">
|
||||||
|
<NodeConnections nodeId={props.nodeId} />
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in new issue
Block a user