diff --git a/packages/devops/package.json b/packages/devops/package.json index afc9837a..7acfd1c1 100644 --- a/packages/devops/package.json +++ b/packages/devops/package.json @@ -1,6 +1,6 @@ { "name": "@bytelyst/devops", - "version": "0.1.2", + "version": "0.1.3", "type": "module", "description": "Runtime devops metadata (build info, uptime, health) — server collector + React UI", "exports": { diff --git a/packages/devops/src/ui.tsx b/packages/devops/src/ui.tsx index 5c5a7b83..3f22884f 100644 --- a/packages/devops/src/ui.tsx +++ b/packages/devops/src/ui.tsx @@ -231,18 +231,20 @@ interface KvRow { function KvTable({ rows }: { rows: KvRow[] }): React.ReactElement { return ( - - - {rows.map((r, i) => ( - - - - - ))} - -
- {r.key} - {r.value}
+
+ + + {rows.map((r, i) => ( + + + + + ))} + +
+ {r.key} + {r.value}
+
); } @@ -252,30 +254,32 @@ function DependenciesTable({ deps: NonNullable; }): React.ReactElement { return ( - - - - - - - - - - - {deps.map((d, i) => ( - - - - - +
+
NameStatusLatencyDetail
{d.name} - - {d.ok ? 'OK' : 'FAIL'} - - {d.latencyMs != null ? `${d.latencyMs} ms` : '—'}{d.detail ?? '—'}
+ + + + + + - ))} - -
NameStatusLatencyDetail
+ + + {deps.map((d, i) => ( + + {d.name} + + + {d.ok ? 'OK' : 'FAIL'} + + + {d.latencyMs != null ? `${d.latencyMs} ms` : '—'} + {d.detail ?? '—'} + + ))} + + + ); } @@ -289,7 +293,7 @@ function formatTimestamp(iso: string): string { } const styles: Record = { - root: { display: 'flex', flexDirection: 'column', gap: 12 }, + root: { display: 'flex', flexDirection: 'column', gap: 12, maxWidth: '100%', minWidth: 0 }, header: { display: 'flex', justifyContent: 'space-between', @@ -300,7 +304,7 @@ const styles: Record = { title: { fontSize: 16, fontWeight: 600, color: 'var(--foreground, inherit)' }, subtitle: { fontSize: 13, color: 'var(--muted-foreground, #6b7280)', marginTop: 4 }, muted: { fontSize: 12, color: 'var(--muted-foreground, #6b7280)' }, - headerActions: { display: 'flex', gap: 8, alignItems: 'center' }, + headerActions: { display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }, sourceToggle: { display: 'inline-flex', border: '1px solid var(--border, #e5e7eb)', @@ -332,6 +336,8 @@ const styles: Record = { display: 'flex', gap: 2, borderBottom: '1px solid var(--border, #e5e7eb)', + overflowX: 'auto', + whiteSpace: 'nowrap', }, tab: { padding: '8px 14px', @@ -341,14 +347,21 @@ const styles: Record = { borderBottom: '2px solid transparent', cursor: 'pointer', color: 'var(--muted-foreground, #6b7280)', + flexShrink: 0, }, tabActive: { color: 'var(--foreground, inherit)', borderBottomColor: 'var(--accent, #2563eb)', fontWeight: 500, }, - panel: { paddingTop: 8 }, - table: { width: '100%', borderCollapse: 'collapse', fontSize: 13 }, + panel: { paddingTop: 8, minWidth: 0 }, + tableWrap: { + width: '100%', + overflowX: 'auto', + overflowY: 'visible', + WebkitOverflowScrolling: 'touch', + }, + table: { width: '100%', borderCollapse: 'collapse', fontSize: 13, tableLayout: 'fixed' }, tr: { borderBottom: '1px solid var(--border, #f3f4f6)' }, th: { textAlign: 'left', @@ -357,14 +370,22 @@ const styles: Record = { padding: '8px 12px 8px 0', verticalAlign: 'top', width: '30%', + minWidth: 120, + }, + td: { + padding: '8px 0', + verticalAlign: 'top', + color: 'var(--foreground, inherit)', + overflowWrap: 'anywhere', + wordBreak: 'break-word', }, - td: { padding: '8px 0', verticalAlign: 'top', color: 'var(--foreground, inherit)' }, code: { fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace', fontSize: 12, background: 'color-mix(in oklab, var(--foreground, #000) 5%, transparent)', padding: '2px 6px', borderRadius: 4, + wordBreak: 'break-all', }, pre: { fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace', @@ -374,6 +395,8 @@ const styles: Record = { borderRadius: 6, overflow: 'auto', maxHeight: 480, + whiteSpace: 'pre-wrap', + wordBreak: 'break-word', }, badge: { display: 'inline-block',