Skip to content

Commit 04af5b6

Browse files
committed
fix: refine pool decommission interactions
1 parent 1dac89e commit 04af5b6

2 files changed

Lines changed: 40 additions & 18 deletions

File tree

app/(dashboard)/pool-decommission/page.tsx

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export default function PoolDecommissionPage() {
8787
const [submitting, setSubmitting] = useState(false)
8888
const [error, setError] = useState<string | null>(null)
8989
const [activePoolId, setActivePoolId] = useState("")
90+
const [selectedPoolId, setSelectedPoolId] = useState("")
9091
const [confirmingPoolId, setConfirmingPoolId] = useState("")
9192
const [overview, setOverview] = useState<PoolsOverview>({
9293
pools: [] as PoolSummary[],
@@ -127,13 +128,16 @@ export default function PoolDecommissionPage() {
127128
if (!activePoolId && nextOverview.pools[0]?.id) {
128129
setActivePoolId(nextOverview.pools[0].id)
129130
}
131+
if (!selectedPoolId && nextOverview.pools[0]?.id) {
132+
setSelectedPoolId(nextOverview.pools[0].id)
133+
}
130134
} catch (loadError) {
131135
setError((loadError as Error).message || t("Load Failed"))
132136
} finally {
133137
if (showSpinner) setLoading(false)
134138
}
135139
},
136-
[activePoolId, getDecommissionStatus, getPoolsOverview, getRebalanceStatus, t],
140+
[activePoolId, getDecommissionStatus, getPoolsOverview, getRebalanceStatus, selectedPoolId, t],
137141
)
138142

139143
useEffect(() => {
@@ -166,6 +170,7 @@ export default function PoolDecommissionPage() {
166170
const canCancelActive = activePoolId
167171
? getPoolDisplayState(activeStatus, overview.supportState, rebalanceState) === "running"
168172
: false
173+
const selectedPoolName = overview.pools.find((pool) => pool.id === selectedPoolId)?.name ?? "--"
169174

170175
const handleStart = async (poolId: string) => {
171176
setSubmitting(true)
@@ -311,16 +316,16 @@ export default function PoolDecommissionPage() {
311316
) : (
312317
<>
313318
<div className="grid gap-4 md:grid-cols-4">
314-
<div>
315-
<p className="text-xs text-muted-foreground">{t("Rebalance Status")}</p>
316-
<p className="text-sm font-medium">{rebalanceState}</p>
317-
</div>
318319
<div>
319320
<p className="text-xs text-muted-foreground">{t("Active Pool")}</p>
320321
<p className="truncate text-sm font-medium">
321322
{overview.pools.find((pool) => pool.id === activePoolId)?.name ?? "--"}
322323
</p>
323324
</div>
325+
<div>
326+
<p className="text-xs text-muted-foreground">{t("Selected Pool")}</p>
327+
<p className="truncate text-sm font-medium">{selectedPoolName}</p>
328+
</div>
324329
<div>
325330
<p className="text-xs text-muted-foreground">{t("Progress")}</p>
326331
<p className="text-sm font-medium">{Math.round(activeStatus?.progressPercent ?? 0)}%</p>
@@ -352,16 +357,16 @@ export default function PoolDecommissionPage() {
352357
</TableRow>
353358
) : (
354359
poolRows.map(({ pool, status: rowStatus, displayState: rowState }) => {
355-
const canRequestStart =
356-
!submitting && ["ready", "failed", "canceled", "completed"].includes(rowState)
360+
const hasDecommissionStarted = Boolean(rowStatus)
361+
const canRequestStart = !submitting && rowState === "ready"
357362
const canConfirm = !submitting && rowState === "confirming"
358363
const canCancel = !submitting && rowState === "running"
359364

360365
return (
361366
<TableRow
362367
key={pool.id}
363-
data-state={pool.id === activePoolId ? "selected" : undefined}
364-
onClick={() => setActivePoolId(pool.id)}
368+
data-state={pool.id === selectedPoolId ? "selected" : undefined}
369+
onClick={() => setSelectedPoolId(pool.id)}
365370
>
366371
<TableCell className="max-w-[320px] truncate">{pool.name}</TableCell>
367372
<TableCell>
@@ -371,15 +376,19 @@ export default function PoolDecommissionPage() {
371376
</TableCell>
372377
<TableCell>{formatBytesValue(pool.used)}</TableCell>
373378
<TableCell className="min-w-32">
374-
<div className="flex items-center gap-2">
375-
<Progress value={rowStatus?.progressPercent ?? 0} className="h-2 w-20" />
376-
<span className="text-xs text-muted-foreground">
377-
{Math.round(rowStatus?.progressPercent ?? 0)}%
378-
</span>
379-
</div>
379+
{hasDecommissionStarted ? (
380+
<div className="flex items-center gap-2">
381+
<Progress value={rowStatus?.progressPercent ?? 0} className="h-2 w-20" />
382+
<span className="text-xs text-muted-foreground">
383+
{Math.round(rowStatus?.progressPercent ?? 0)}%
384+
</span>
385+
</div>
386+
) : (
387+
"--"
388+
)}
380389
</TableCell>
381-
<TableCell>{rowStatus?.objects ?? "--"}</TableCell>
382-
<TableCell>{formatBytesValue(rowStatus?.bytes)}</TableCell>
390+
<TableCell>{hasDecommissionStarted ? (rowStatus?.objects ?? "--") : "--"}</TableCell>
391+
<TableCell>{hasDecommissionStarted ? formatBytesValue(rowStatus?.bytes) : "--"}</TableCell>
383392
<TableCell>
384393
<div className="flex justify-end gap-2">
385394
{rowState === "confirming" ? (
@@ -414,10 +423,11 @@ export default function PoolDecommissionPage() {
414423
<Button
415424
size="sm"
416425
variant="outline"
417-
disabled={!canRequestStart}
426+
disabled={!canRequestStart || hasDecommissionStarted}
418427
onClick={(event) => {
419428
event.stopPropagation()
420429
setActivePoolId(pool.id)
430+
setSelectedPoolId(pool.id)
421431
setConfirmingPoolId(pool.id)
422432
}}
423433
>

tests/lib/pool-decommission-page.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,15 @@ test("pool decommission page renders pool selection as a table instead of a sele
1111
assert.match(source, /<Table\b/)
1212
assert.match(source, /poolRows\.map/)
1313
})
14+
15+
test("pool decommission page keeps status panel independent from list clicks and hides idle progress", () => {
16+
const source = fs.readFileSync("app/(dashboard)/pool-decommission/page.tsx", "utf8")
17+
18+
assert.doesNotMatch(source, /{t\("Rebalance Status"\)}/)
19+
assert.match(source, /onClick=\{\(\) => setSelectedPoolId\(pool\.id\)\}/)
20+
assert.doesNotMatch(source, /onClick=\{\(\) => setActivePoolId\(pool\.id\)\}/)
21+
assert.match(source, /const hasDecommissionStarted = Boolean\(rowStatus\)/)
22+
assert.match(source, /hasDecommissionStarted \?/)
23+
assert.match(source, /rowState === "ready"/)
24+
assert.doesNotMatch(source, /\["ready", "failed", "canceled", "completed"\]\.includes\(rowState\)/)
25+
})

0 commit comments

Comments
 (0)