Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
24aef6e
feat(provide_stat): add new page for provide stat
ChayanDass Jan 18, 2026
64f5631
feat(provide_stat):add tooltip to dht provide page
ChayanDass Jan 18, 2026
94c662b
feat(provide_stat):fix the ui and make the ui responsive
ChayanDass Jan 20, 2026
44105a8
style(dht-provide): align with ipfs-webui design patterns
lidel Jan 23, 2026
eb5366c
refactor(dht-provide): align UI labels with CLI output
lidel Jan 23, 2026
cc8ff61
style(dht-provide): replace title with description and docs link
lidel Jan 23, 2026
1ca76f0
fix(dht-provide): defensive data handling and improved workers tooltip
lidel Jan 23, 2026
dce9698
feat(dht-provide): update types for kubo API changes and add FullRT i…
lidel Jan 23, 2026
b0279e2
chore(deps): upgrade kubo-rpc-client to 6.1.0
lidel Jan 23, 2026
26185b8
docs(dht-provide): improve description with links to config and metri…
lidel Jan 23, 2026
9e9870d
fix(i18n): improve schedule tooltip wording
lidel Jan 23, 2026
4c30fd4
fix(i18n): use app locale for number formatting
lidel Jan 23, 2026
6259828
Merge remote-tracking branch 'origin/main' into feat/provide-stat
lidel Jan 23, 2026
466f732
fix(imports): use relative paths for storybook compatibility
lidel Jan 23, 2026
511ec39
test(e2e): add DHT provide diagnostics tests
lidel Jan 24, 2026
3a26b2a
test(e2e): fix flaky grid-view and files tests
lidel Jan 24, 2026
b2148f9
test(e2e): disable DHT bootstrapping for faster CI startup
lidel Jan 24, 2026
e4f7abe
test(e2e): add timeouts and remove CI-specific config
lidel Jan 24, 2026
454f1bc
revert: align CI and e2e tests with main branch
lidel Jan 26, 2026
6baf0eb
Merge remote-tracking branch 'origin/main' into feat/provide-stat
lidel Jan 26, 2026
5533bb1
fix(e2e): enable DHT provide tests with autoclient routing
lidel Jan 26, 2026
fc426af
fix(e2e): stabilize IPNS publish test
lidel Jan 27, 2026
2f9f071
fix(dht-provide): remove unused CurrentBatch, add avg CIDs/region
lidel Jan 27, 2026
9690ed9
fix(dht-provide): address review feedback, align labels with CLI
lidel Jan 28, 2026
8b0ce16
fix(dht-provide): specify pending CIDs for provide operation
guillaumemichel Jan 29, 2026
e858589
feat(kad-dht): specialized worker usage bar
guillaumemichel Jan 29, 2026
242b249
fix(kad-dht): failing test
guillaumemichel Jan 29, 2026
fb85c85
fix(dht-provide): small fixes and pause polling on hidden tab
lidel Feb 4, 2026
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
732 changes: 339 additions & 393 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"it-first": "^1.0.6",
"it-last": "^1.0.5",
"it-map": "^1.0.5",
"kubo-rpc-client": "^5.4.0",
"kubo-rpc-client": "^6.1.0",
"milliseconds": "^1.0.3",
"money-clip": "^3.0.5",
"multiformats": "^13.4.0",
Expand Down Expand Up @@ -171,7 +171,7 @@
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-mock": "^30.0.5",
"kubo": "^0.38.0",
"kubo": "^0.39.0",
"npm-run-all": "^4.1.5",
"nyc": "^15.1.0",
"os-browserify": "^0.3.0",
Expand Down
91 changes: 90 additions & 1 deletion public/locales/en/diagnostics.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"title": "Diagnostics",
"tabs": {
"logs": "Logs",
"retrieval-check": "Retrieval Check"
"retrieval-check": "Retrieval Check",
"dht-provide": "DHT Provide"
},
"logs": {
"title": "Node Logs",
Expand Down Expand Up @@ -93,5 +94,93 @@
"upgradeDescription": "To use the log level management features, you need to upgrade to a newer version of Kubo that supports getting log levels and tailing logs from the RPC API endpoint.",
"downloadKubo": "Download Kubo"
}
},
"dhtProvide": {
"title": "DHT Provide",
"node": "Node",
"unknown": "Unknown",
"cidLabel": "CID to provide",
"provideButton": "Trigger Provide",
"clear": "Clear",
"provideTriggered": "Provide triggered for {cid}",
"noCid": "Please enter a CID",
"description": "Trigger a background provide operation for a CID. This will announce the CID on the DHT so other peers can discover providers for it.",
"screen": {
"description": "Visual summary of the DHT provide sweep system. See <0>configuration guide</0> and <1>metric reference</1> for details.",
"loading": "Loading DHT provide stats…",
"notEnabled": "DHT Sweep provider is not enabled on this node.",
"failedToLoad": "Failed to load provide stats: {message}",
"refreshCountdown": "Refresh: {seconds}s",
"refreshOff": "Refresh: OFF",
"lastUpdated": "Last updated at {time}",
"workersWarning": "Workers at {percent}% capacity. If the queue grows, consider increasing Provide.DHT.MaxWorkers (current: {max})."
},
"connectivity": {
"title": "Connectivity",
"tooltip": "Overall health of the DHT provide subsystem: connectivity, uptime, and keyspace coverage.",
"status": "Status",
"online": "Online",
"offline": "Offline",
"sinceAgo": "{value}{unit} ago",
"justNow": "just now",
"uptime": "Uptime",
"keyspaceCoverage": "Keyspace",
"full": "Full",
"partial": "Partial",
"closedWarning": "Provider system is shutting down"
},
"schedule": {
"title": "Schedule",
"tooltip": "The reprovide cycle periodically re-announces groups of CIDs to the DHT.",
"reprovideInterval": "Reprovide interval",
"elapsed": "Elapsed",
"remaining": "Remaining",
"regions": "Regions",
"cidsScheduled": "CIDs this cycle",
"avgCidsPerRegion": "Avg CIDs/region",
"nextRegionPrefix": "Next region prefix",
"avgPrefixLength": "Avg prefix length",
"nextReprovide": "Next region start"
},
"queues": {
"title": "Queues",
"tooltip": "Pending items in the provide and reprovide queues.",
"pendingCids": "Pending CIDs (provide)",
"pendingRegionProvides": "Pending regions (provide)",
"pendingRegionReprovides": "Pending regions (reprovide)"
},
"operations": {
"title": "Operations",
"tooltip": "In-flight provide and reprovide operations, throughput rates, and cumulative statistics.",
"ongoingProvides": "Ongoing provides",
"ongoingReprovides": "Ongoing reprovides",
"provideRate": "Avg provide rate",
"reprovideRate": "Avg reprovide rate",
"totalCidsProvided": "Total CIDs provided",
"totalRecordsProvided": "Total records provided",
"totalProvideErrors": "Total provide errors",
"regionReprovideDuration": "Region reprovide duration",
"avgCidsPerReprovide": "Avg CIDs/reprovide"
},
"workers": {
"title": "Workers",
"tooltip": "Breakdown of worker status by type: periodic workers handle scheduled reprovides, burst workers handle initial provides.",
"active": "Active",
"periodic": "Periodic",
"burst": "Burst",
"queued": "Queued (periodic / burst)",
"maxConnsPerWorker": "Max connections/worker"
},
"network": {
"title": "Network",
"tooltip": "DHT network metrics: peer counts, reachability, and record holders.",
"peerSwept": "Peers swept",
"reachablePeers": "Reachable peers",
"avgRecordHolders": "Avg record holders",
"avgRegionSize": "Avg region size",
"replicationFactor": "Replication factor",
"fullKeyspaceCoverage": "Full keyspace coverage",
"fullRT": "Accelerated DHT client"
}
}
}
2 changes: 1 addition & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class App extends Component {
<FilesExploreForm onBrowse={doFilesNavigateTo} />
</div>
<div className='dn flex-ns flex-auto items-center justify-end'>
<TourHelper />
{!url.startsWith('/diagnostics') && <TourHelper />}
<Connected className='joyride-app-status' />
</div>
</div>
Expand Down
104 changes: 104 additions & 0 deletions src/components/card/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React from 'react'
import { Box } from '../box/Box'

/**
* Card root
*/
export const Card: React.FC<{
className?: string
style?: React.CSSProperties
children: React.ReactNode
}> = ({ className = '', style, children }) => {
return (
<Box
className={`ba b--black-10 br2 bg-white ${className}`}
style={{ padding: 0, ...style }}
>
{children}
</Box>
)
}

/**
* Card header
*/
export const CardHeader: React.FC<{
className?: string
children: React.ReactNode
}> = ({ className = '', children }) => {
return (
<div className={`pa3 bb b--black-10 ${className}`}>
{children}
</div>
)
}

/**
* Card title
*/
export const CardTitle: React.FC<{
className?: string
children: React.ReactNode
}> = ({ className = '', children }) => {
return (
<div className={`ttu tracked f6 fw4 teal ${className}`}>
{children}
</div>
)
}

/**
* Card description
*/
export const CardDescription: React.FC<{
className?: string
children: React.ReactNode
}> = ({ className = '', children }) => {
return (
<div className={`f7 gray mt1 ${className}`}>
{children}
</div>
)
}

/**
* Card action (top-right area)
*/
export const CardAction: React.FC<{
className?: string
children: React.ReactNode
}> = ({ className = '', children }) => {
return (
<div className={`absolute top-1 right-1 ${className}`}>
{children}
</div>
)
}

/**
* Card content
*/
export const CardContent: React.FC<{
className?: string
children: React.ReactNode
}> = ({ className = '', children }) => {
return (
<div className={`pa3 ${className}`}>
{children}
</div>
)
}

/**
* Card footer
*/
export const CardFooter: React.FC<{
className?: string
children: React.ReactNode
}> = ({ className = '', children }) => {
return (
<div className={`pa3 bt b--black-10 ${className}`}>
{children}
</div>
)
}
22 changes: 22 additions & 0 deletions src/components/metric-row/MetricRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'

export const MetricRow: React.FC<{
label: string
value: React.ReactNode
highlight?: boolean
className?: string
}> = ({ label, value, highlight = false, className = '' }) => {
return (
<div className={`flex justify-between items-center mb2 ${className}`}>
<span className='f6'>
{label}
</span>

<span className={`f6 ${highlight ? 'fw6 green' : ''}`}>
{value}
</span>
</div>
)
}

export default MetricRow
7 changes: 4 additions & 3 deletions src/components/tooltip/icon-tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ interface IconTooltipProps {
text: string
position: 'top' | 'bottom' | 'left' | 'right'
forceShow?: boolean
className?: string
}

const IconTooltip: React.FC<IconTooltipProps> = ({ children, text, position, forceShow = false }) => {
const IconTooltip: React.FC<IconTooltipProps> = ({ children, text, position, forceShow = false, className = '' }) => {
const [show, setShow] = useState(false)

const onMouseOver = () => setShow(true)
Expand Down Expand Up @@ -114,7 +115,7 @@ const IconTooltip: React.FC<IconTooltipProps> = ({ children, text, position, for
const tooltipDisplayClass = useMemo(() => (show || forceShow) ? 'db' : 'dn', [show, forceShow])

return (
<div className="relative" style={{ display: 'inline-block' }}>
<div className={`relative ${className}`} style={{ display: 'inline-block' }}>
<div
onMouseOver={onMouseOver}
onMouseLeave={onMouseLeave}
Expand All @@ -125,7 +126,7 @@ const IconTooltip: React.FC<IconTooltipProps> = ({ children, text, position, for
</div>
<div
style={tooltipStyles}
className={`white z-max bg-navy-muted br2 pv2 ph3 f6 lh-copy fw5 absolute sans-serif noselect ${tooltipDisplayClass}`}
className={`white z-max bg-navy-muted br2 pv2 ph3 f6 lh-copy fw5 absolute sans-serif noselect ttn ${tooltipDisplayClass}`}
>
<div className='bg-navy-muted db bg-navy-muted absolute' style={arrowStyles} />
{text}
Expand Down
9 changes: 9 additions & 0 deletions src/contexts/ProvideStat/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { KuboRPCClient } from 'kubo-rpc-client'
import type { ProvideStatOptions, ProvideStats } from './types'

export async function getProvideStats (
ipfs: KuboRPCClient,
options: ProvideStatOptions = { all: true }
): Promise<ProvideStats> {
return ipfs.provide.stat(options)
}
5 changes: 5 additions & 0 deletions src/contexts/ProvideStat/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Export the context provider and hook
export { ProvideProvider, useProvide } from './provide-context'

export * from './types'
export * from './api'
Loading