Repository navigation
Detail pages and logs fit at laptop widths; Pending Pods and scheduling causes read plainly - #2074
Conversation
âĶtop widths, two action groups The drawer and expanded headers put the name, copy button and status on one line. The tab strip drops its icons only while the tabs don't fit, keeps the active tab in view and lets scope controls wrap. The actions bar splits object and utility actions into two wrapping groups. Opt-in header props for host pages come along, inert until a host passes them.
âĶogs loaded At laptop widths the toolbar wraps its display and utility controls as a group instead of squeezing labels or pushing Export and Clear off screen. The capture time and any notice share one status line. Export and Clear are disabled while nothing is loaded. Long lines break between words before breaking inside one, a structured line keeps its field count whole, and a PostgreSQL record shows its own message.
âĶending Pod has no usage yet A container that hasn't started is neutral instead of red Not Ready or amber Pending; only a reported failure is red. When the metrics API answers but the Pod has never run, Resource Usage says so instead of claiming Radar cannot read metrics.k8s.io. The Pod metrics history response gains metricsAPIReachable.
âĶe issues by reason Drawer issue rows show the scheduler's reasons in plain words on their own line, every cause kept, with the raw message in the details. Issue rows on Home and the Issues page take the reason's title when the category would name the wrong operation.
âĶ after the client gave up A view-filter switch now waits 15s instead of 5s. After a timeout the client reads the server's scope and reports success if the pick was applied. A cache-scoped switch refreshes every query except the scope it just wrote, without cancelling refetches in flight.
A Pod row is unhealthy when a container just exited with an error and degraded when the Pod just lost readiness, instead of waiting out the standing-state grace periods. A clean container exit still reads as completion.
Filtering the resources sidebar keeps the workspace views whose label matches, or all of them when the term names the category or one of its API groups. Arrow keys and Enter reach the views too. The views heading reads Views.
âĶhe accent token Also stops passing a namespace name as a console format string.
While the resource loads there is no status to report; calling the host's renderer then either throws or shows a false 'not reported'.
A --namespace-scope rescope publishes its target before the cache rebuild finishes and can still roll back, so a matching scope doesn't prove it succeeded.
PR Summary by QodoMake shared detail pages and logs fit laptop widths
AI Description
Diagram
High-Level Assessment
Files changed (46)
|
Code Review by Qodo
1. Streaming controls keep a fixed green background
|
A later change while the Pod is still unready used to fall back to the standing-state grace and read healthy, ending the incident early. Readiness counts as lost when it went false after a running container had started; at startup it went false first.
The lookahead rescanned the rest of the message at every comma, so a long custom scheduler message took seconds and blocked the drawer. One backward pass keeps the same rule: no split where the next bracket ahead closes.
Sharing the title line with the drawer controls left a long name about 300px whenever Investigate showed, so a Pod name lost its distinguishing suffix. The drawer keeps main's layout: kind and status beside the controls, the name and namespace below. A host's status badge and object actions still render there.
Under restartPolicy Always a container exiting 0 is restarting, not completing, and a restarted container's previous run also proves readiness was lost rather than still to come.
Carved out of #1922. This is the shared detail-page UI from that PR: every resource kind gets it, so it is reviewed here on its own rather than inside a CloudNativePG change. Merge before #1922, whose CloudNativePG pages pass the opt-in header props carried here.
What users see
Expanded view: tabs on one line at laptop widths
At 1280px the tab strip used to wrap the actions bar onto two rows and leave Rollback or Delete on a line of their own. Tabs now drop their icons only while they don't fit, and the strip keeps the active tab in view. Scope controls wrap instead of pushing tabs out, and the tabs get a focus ring. The actions bar puts object actions (Set image, Restart, Rollback) and utility actions (compare, delete) in two groups that wrap as groups.
Before / after, Deployment at 1280Ã800:
Drawer header: unchanged
#1922 puts the drawer's name on the title line beside the header buttons. That saves a line for short names, but when the labelled Investigate button shows, the name gets about 300px: a Pod name such as
su-unschedulable-7d98c9cc76-4rdf7was cut tosu-unschedulable-7d98c9cc76âĶ. So the drawer keeps main's layout here: kind and status beside the controls, then the name on its own full-width line. The hooks #1922's pages use there still work: a host's status badge, and object actions in the actions bar.Pending Pods say what is actually going on
ImagePullBackOfforCrashLoopBackOff) is red;ContainerCreatingandPodInitializingstay neutral.metricsAPIReachable.Before / after, unschedulable Pod with an init container (the cluster's metrics-server is healthy):
Logs
{N fields}whole, and a CloudNativePG PostgreSQL record shows the database's message.WorkloadLogsViewergainsinitialContainer, plus opt-insemptySourceStateanddisableSourceControlsWithoutSource.Issue titles
Issue rows on Home and the Issues page take the reason's title when the category would name the wrong operation. Today that is CloudNativePG WAL archiving and last-backup issues, which main titles "Backup failed".
Namespace switch
No visible change on a view-filter switch: both builds send the same six requests after picking a namespace. What changes:
--namespace-scope) refreshes every query except the scope it just wrote, without cancelling refetches in flight.Timeline
A Pod row is tagged by the state the change produced: unhealthy when a container just exited with an error, degraded from the moment the Pod lost readiness until it returns. Before, it waited out the standing-state grace periods. A clean container exit still reads as completion, and a Pod still starting up keeps its grace.
Smaller fixes
text-blue-*.Radar Hub and library consumers
All changes to
@skyhook-io/k8s-uiand@skyhook-io/radar-appare additive:WorkloadViewgains the opt-in host propstitlePrefix,inlineBadges,namespaceNote,renderStatusBadge,statusNote,hideKindBadge,subheader,tabOrder,specTabandrenderHeaderActions.WorkloadExtraTabgainsbadge.DetailShellgainssubheaderandwrapHeader;ResourceActionsBargainsleadingActions.IssueRowandResourceIssuesSectiongaincompact.LogCore.emptyMessagewidens fromstringtoReactNode.MetricsUnavailableNoticegainsnoUsageYet.issueTitle,issueReasonTitle,tokenizeJson.summarizeSchedulerMessagegains an optional{ plain }argument.Version skew. Hub runs the newest UI against older Radars:
metricsAPIReachableis absent there, so a Pending Pod keeps the old metrics notice.causefalls back to the raw scheduler message. The plain-words summary handles that too (see the deviations).The expanded header and tab strip change for Hub users exactly as they do in Radar.
radar-appnow importsissueTitlefromk8s-ui. This ships ink8s-ui1.17.0, which the peer floor (>=1.17.0) already requires.Deviations from #1922
Code is copied verbatim from #1922 at
01f2a97abexcept:leadingActionsand the non-shrinking utility buttons stay, and the drawer case inWorkloadView.spec.test.tsxnow checks that the name has its own line.ResourcesSidebar.tsxleaves outcountLowerBoundand its test. It needsfacts/certaintyGlyph, which stays in CloudNativePG: incident workflows, guarded operations and guided recovery #1922.status-tone.tsxcarries onlytoneTextClass, which the logs status line uses.toneFillClass,worseToneand their exports stay in CloudNativePG: incident workflows, guarded operations and guided recovery #1922.server.gocarries only themetricsAPIReachablehunk. The CNPG routes and the move tointernal/integrationstay.server_smoke_test.gocarriesTestPodMetricsHistoryAPIReachability.client.tscarriespodMetricsQuery,metricsAPIReachableand the namespace-switch hunks.useIssues(enabled),useSubjectIssues, the memoizeduseRadarFeature, the new PVC usage statuses andApplyResourceResult.uidstay; they belong to the other carve-outs or to CNPG.IssuesView.tsxandResourceIssuesSection.tsx(with its test), and the one-linecompact={!expanded}in webWorkloadView.tsx.summarizeSchedulerMessage(âĶ, { plain: true })also handles the scheduler phrasing in current Kubernetes. On EKS 1.34 the message reads6 node(s) had untolerated taint(s), 8 node(s) didn't match Pod's node affinity/selector. no new claims to deallocate, preemption: âĶ, and CloudNativePG: incident workflows, guarded operations and guided recovery #1922's version returned6 node(s) had untolerated taint(s); 8 node(s) didn't match Pod's node affinity/selector. no new claims to deallocate;(raw clauses and a trailing;). It now returns6 nodes have taints the Pod does not tolerate; 8 nodes do not match the Podâs node affinity or selector. The test uses that message. The phrase is removed with a plain match: CodeQL flagged the first version's\s*as polynomial on long runs of spaces./[,;](?![^\[\]{}]*[\]}])/) rescanned the rest of the message at every comma, so a 240 KB custom-scheduler message took about 7 s and blocked the drawer. The one-pass split keeps the same rule: no split where the next bracket ahead closes. A test covers a 10,000-clause message.PodRenderer.test.tsx.restartPolicy: Always), and a restarted container's previous run counts as proof that readiness was lost. Before, a liveness restart that exited cleanly turned the row green while the Pod was still unready.WorkloadViewasks a host'srenderStatusBadgefor a badge only once the resource has loaded. In CloudNativePG: incident workflows, guarded operations and guided recovery #1922 it was called withundefinedduring loading: a callback that reads fields throws, and the CloudNativePG Cluster badge read "Phase Not reported" until the object arrived. Test:waits for the resource before asking a host for its status badge.--namespace-scoperescope publishes its target before the cache rebuild finishes (reinitializeNamespaceScopesets the override beforeInitAllSubsystems) and can still roll back, so a matching scope doesn't prove it succeeded. Test:client.namespaceSwitch.hook.test.tsx.Left in #1922
The drawer title-line layout stays there until it adapts to long names. The rest is opt-in only or CloudNativePG-specific:
AreaChart(shadedRanges),CreateResourceDialog(onBack,initialMode,lockMode),DockContext/TerminalTab(shell,sessionNote),AlertBanner.action,.btn-secondary;ResourcesView.renderKindViewand the web wiring toweb/src/integrations;facts,problems,FoldSection,RefLink,grantandActionConfirmDialogcomponents;stripTrailingSlashesrefactor and DESIGN.md's facts section.Testing
go build ./... && go test ./...,make tsc, k8s-uitsc+ vitest (245 files, 4,486 tests), web vitest (167 files, 1,998 tests), andnpm run lintall pass. Lint reports 0 errors and the same 489 warnings as main.Before/after on a live EKS 1.34 cluster. Main and this branch ran side by side against the same cluster at 1280Ã800 and 1920Ã1080, in light and dark. Captures:
ClickHouseInstallation);All captures showed the "What users see" changes above. Export and Clear were disabled on the empty logs view, and the namespace switch sent identical requests on both builds.
Not exercised live:
client.namespaceSwitch.test.ts).After this merges
#1922 merges main and takes main's version of every file here, including main's drawer header in
WorkloadView.tsx(owner decision): it does not re-apply its title-line drawer layout. Its own changes toResourcesSidebar.tsx(countLowerBound),status-tone.tsx,server.go,client.tsand webWorkloadView.tsxgo back on top. It also picks up the scheduler-summary fix above.