ui: shared ClusterSwitcher + Radar loading icon#548
Merged
nadaverell merged 1 commit intomainfrom Apr 27, 2026
Merged
Conversation
ClusterSwitcher (@skyhook-io/k8s-ui): generic trigger+dropdown primitive shared by OSS Radar's kubeconfig context switcher and Radar Hub's cluster picker. Both call sites previously diverged — Hub showed the raw kubeconfig context with a "Cluster:" prefix and no truncation, overflowing into the connected indicator and view tabs on narrower screens. The primitive parses, truncates (max-w-[120px] sm:max-w-[220px]), supports search/keyboard nav, group headers, status dots, badges, footer slots, and href-based or callback selection. Re-exported from @skyhook-io/radar-app for embedders. OSS ContextSwitcher rewrite drops ~290 lines by consuming the primitive while keeping kubeconfig parsing, group sort (GKE → EKS → AKS → Other), active-session confirmation modal, in-cluster mode badge, and switch-error toast fallback. Now also surfaces a toast when fetchSessionCounts fails instead of silently switching and killing port-forwards/terminals. Loading icon: replace lucide Loader2 spinner with the Radar-branded SVG (sweep arm + pinging blips) across AuthBarrier, connecting/switching overlays, AuditView, CostView, HomeView, ResourcesView, image/pod filesystem modals, and the traffic-test wizard. SVG ships through k8s-ui's package.json `exports` so Hub can consume the same asset.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ClusterSwitcher(in@skyhook-io/k8s-ui, re-exported from@skyhook-io/radar-app) replaces two divergent cluster-picker UIs. OSS Radar'sContextSwitcherrewrites on top of it; Radar Hub'sHubClusterSwitcherwill too in a follow-up Hub PR. Hub's picker previously rendered the rawgke_<account>_<region>_<cluster>context with aCluster:prefix and no truncation — overflowing into the connection indicator and the view tabs on narrower screens. The primitive enforcesmax-w-[120px] sm:max-w-[220px] truncate.lucideLoader2spinner with the Radar-branded SVG (sweep arm + pinging blips) across the auth barrier, connecting/switching overlays, Audit, Cost, Home, Resources, the pod/image filesystem modals, and the traffic-test wizard. SVG lives in@skyhook-io/k8s-ui(exports: ./assets/radar/radar-icon-loading.svg) so Hub consumes the same asset.Why
The picker divergence wasn't just cosmetic — Hub had no overflow protection, dropped active-session confirmation, dropped search, and would render with a different brand color than OSS once
--color-brand-*tokens diverged. Pulling the primitive into k8s-ui means both apps stay in sync, and the OSS rewrite drops ~290 lines.While here: the OSS
ContextSwitcherpreviously swallowedfetchSessionCountsfailures with aconsole.errorand silently switched, killing port-forwards/terminals without warning. It now surfaces a toast.Notable design decisions
hrefon aClusterSwitcherItemtakes precedence over the parent'sonSelect— documented in JSDoc rather than hidden behind a discriminated union (two consumers don't justify the type complexity).ESCand click-outside listeners attach only while the dropdown is open, so a stacked modal (the active-sessions confirm dialog) doesn't get its escape key intercepted..selection/.selection-textclasses so the active row picks up Hub's brand color, not Radar-blue.Ship order
@skyhook-io/k8s-uimust publish first (radar-app peer-deps>=1.5.0); then radar-app. Hub's PR will pin the new versions.Test plan
npm run tscclean inweb/make frontendbuilds without warnings (other than pre-existing elkjs dynamic-import warning)Note
Medium Risk
Medium risk because it refactors the cluster context-switching UI and interaction flow (selection, grouping, session-confirmation) and replaces loading indicators across multiple views, which could introduce UX regressions or switching edge cases.
Overview
Introduces a reusable
ClusterSwitchercomponent in@skyhook-io/k8s-ui(and re-exports it from bothk8s-uiand@skyhook-io/radar-app) to standardize cluster/context picking with search, grouping, keyboard navigation, truncating trigger text, and optional error/footer slots.Refactors OSS Radar’s
ContextSwitcherto use the shared switcher, preserving the active-session confirmation prompt and improving failure handling by surfacing a toast when session-count checks fail (instead of silently switching).Adds a branded animated Radar SVG loading icon to
k8s-uiexports and swaps multipleLoader2spinners in bothk8s-ui(resources loading state) and the web app (auth redirect, connecting/switching overlays, audit/cost/home, filesystem modals, traffic wizard) to use the shared asset.Reviewed by Cursor Bugbot for commit 7b3a537. Bugbot is set up for automated code reviews on this repo. Configure here.