mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-09 10:21:03 +00:00
fix: truncate long error text in fleet prune estimate per-node rows (#1802)
Unreachable nodes rendered their error string in a shrink-0 span with no width bound, so a verbose daemon or proxy error pushed the row past the card edge. Bound the error span to 55% and ellipsize, matching the existing pattern in the label-and-stop card; the full message stays available via the row title tooltip.
This commit is contained in:
@@ -126,6 +126,31 @@ it('shows 0 reclaimable · partial when successful targets report zero bytes', a
|
||||
expect(screen.getByText('PART')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('truncates a long unreachable error without clipping reachable byte counts', async () => {
|
||||
const longError = `Pilot tunnel is disconnected: ${'x'.repeat(400)}`;
|
||||
const twoNodes = [...nodes, { id: 2, name: 'edge', status: 'offline' }] as unknown as FleetNode[];
|
||||
mockedFetch.mockImplementation((url: string) => {
|
||||
if (url === '/fleet/prune/estimate') {
|
||||
return Promise.resolve(jsonResponse(200, {
|
||||
totalBytes: 4096,
|
||||
perNode: [
|
||||
{ nodeId: 1, nodeName: 'central', reclaimableBytes: 4096, reachable: true },
|
||||
{ nodeId: 2, nodeName: 'edge', reclaimableBytes: 0, reachable: false, error: longError },
|
||||
],
|
||||
}));
|
||||
}
|
||||
return Promise.resolve(jsonResponse(404, {}));
|
||||
});
|
||||
|
||||
render(<FleetPruneCard nodes={twoNodes} />);
|
||||
const errorSpan = await screen.findByText(longError);
|
||||
expect(errorSpan.className).toContain('truncate');
|
||||
expect(errorSpan.className).toContain('max-w-[55%]');
|
||||
expect(screen.getByTitle(longError)).toBeInTheDocument();
|
||||
const byteSpan = screen.getByText('4 KB');
|
||||
expect(byteSpan.className).not.toContain('truncate');
|
||||
});
|
||||
|
||||
it('drops the unlock footer once dry run review is valid', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockedFetch.mockImplementation((url: string) => {
|
||||
|
||||
@@ -416,7 +416,7 @@ function EstimateSection({ estimate }: { estimate: EstimateState }) {
|
||||
{node.reachable ? (node.partial ? 'PART' : 'OK') : '--'}
|
||||
</span>
|
||||
<span className="min-w-0 flex-1 truncate font-mono text-[11px] text-stat-value">{node.nodeName}</span>
|
||||
<span className={cn(KICKER, 'shrink-0 tabular-nums', node.reachable ? 'text-stat-subtitle' : 'text-stat-icon')}>
|
||||
<span className={cn(KICKER, 'shrink-0 tabular-nums', node.reachable ? 'text-stat-subtitle' : 'max-w-[55%] truncate text-stat-icon')}>
|
||||
{node.reachable ? formatBytes(node.reclaimableBytes) : (node.error ?? 'unreachable')}
|
||||
</span>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user