Skip to content

feat(ui): Headlamp K8s ResourceClasses, CommonComponents & app-bar actions - #5385

Merged
devantler merged 1 commit into
mainfrom
claude/headlamp-k8s-classes
Jun 22, 2026
Merged

feat(ui): Headlamp K8s ResourceClasses, CommonComponents & app-bar actions#5385
devantler merged 1 commit into
mainfrom
claude/headlamp-k8s-classes

Conversation

@devantler

Copy link
Copy Markdown
Contributor

Builds on the now-merged kube-proxy (#5379) and Headlamp plugin foundation (#5370) — both in main. The diff here is 5 frontend files.

What

Extends the window.pluginLib Headlamp-compat facade so plugins that list and render cluster resources run unmodified — the next slice of Phase 4c after the proxy:

  • K8s.ResourceClasses.<Kind>.useList() — the Headlamp K8s class hierarchy: a useList()-bearing class per common core/apps/batch/networking kind, yielding KubeObject instances (metadata/spec/status/getName()/getNamespace()), backed by the read-only kube-proxy and scoped to the live active cluster.
  • CommonComponents.SectionBox / SectionHeader — Headlamp's titled layout panels, KSail-styled (no Material UI dependency).
  • registerAppBarAction now accepts a bare ReactNode — the canonical headlamp-plugin scaffold form (registerAppBarAction(<span>Hello</span>)) — rendered in the app bar via a new PluginAppBarActions header slot (DRYed with PluginDetailSections through a shared helper).

Verified live on a kind cluster

A faithful Headlamp-shaped plugin (hand-written: the @kinvolk/headlamp-plugin toolchain can't build under Node 26 locally, so this references the exact pluginLib globals a real bundle would) rendered end-to-end against a real apiserver, with zero errors:

  • K8s.ResourceClasses.Pod.useList()9 live pods (matched kubectl ground truth) inside a SectionBox
  • the app-bar action (registerAppBarAction(<ReactNode>)) in the header
  • sidebar entry + route, and the detail-view section (regressions)

Scope

The heavier UI externals — Material UI / Redux / React-Router (a lazily-loaded pluginLib chunk so KSail's own bundle stays lean) — remain staged for a follow-up increment. A plugin that imports those does not run yet; one that uses React + register* + the K8s data layer + CommonComponents does.

web/ui only (MegaLinter-excluded); the gate is tsc + vite build, both green.

🤖 Generated with Claude Code

…tions

Extend the window.pluginLib Headlamp-compat facade so plugins that list and render cluster resources run unmodified:

- K8s.ResourceClasses.<Kind>.useList() class hierarchy (KubeObject instances) over the read-only kube-proxy, covering the common core/apps/batch/networking kinds, scoped to the live active cluster.
- CommonComponents.SectionBox/SectionHeader (KSail-styled, no MUI dependency).
- registerAppBarAction now accepts a bare ReactNode (the canonical headlamp-plugin scaffold form), rendered via a new PluginAppBarActions header slot (DRYed with PluginDetailSections through a shared helper).

Verified end-to-end on a kind cluster: a faithful Headlamp-shaped plugin rendered ResourceClasses.Pod.useList() -> 9 live pods inside a SectionBox, plus the app-bar action, sidebar/route, and detail section -- zero errors. The heavier MUI/Redux/React-Router externals remain staged for a follow-up increment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@devantler
devantler marked this pull request as ready for review June 22, 2026 15:59
@devantler
devantler merged commit 7c87999 into main Jun 22, 2026
33 checks passed
@devantler
devantler deleted the claude/headlamp-k8s-classes branch June 22, 2026 19:04
@github-project-automation github-project-automation Bot moved this from 🫴 Ready to ✅ Done in 🌊 Project Board Jun 22, 2026
devantler added a commit that referenced this pull request Jun 23, 2026
The Headlamp-compat list surfaces added in #5385 inlined the same
cluster-scoped fetch-on-change React effect in two places —
makeResourceClass.useList (k8s.ts) and makeK8sShim.useResourceList
(pluginLib.ts) — differing only in the item type, the fetch call, and the
extra effect deps. jscpd (MegaLinter COPYPASTE, threshold 0%) flagged the
two blocks as clones, failing the `🧹 Lint - mega-linter` check on every
open PR (MegaLinter full-scans the repo on each PR's merge ref).

Extract the shared effect into a generic useClusterScopedList<T>(getCluster,
fetchList, deps) hook and have both call sites delegate to it. Behaviour is
preserved: same [items, error] return, same cluster-keyed re-fetch, same
extra deps (kind/namespace for useResourceList). Drops the now-unused React
import from k8s.ts.

Validated: web/ui `tsc --noEmit` clean; jscpd reports 0 clones (was 2).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant