Documentation

Source-of-truth docs, references, plans, and product material across Harbor surfaces.

Commercial And Brand

NodeUI Refactor Notes

This refactor split the Harbor NodeUI monolith into an app shell, page-level feature modules, and shared helpers without intentionally changing user-facing behavior.

commercial and brandnodeuirefactornotes
Source: nodeui-refactor-notes.md

NodeUI Refactor Notes

Summary

This refactor split the Harbor NodeUI monolith into an app shell, page-level feature modules, and shared helpers without intentionally changing user-facing behavior.

The primary goal was to stop apps/harbor-ui/src/App.tsx from being the render wall and navigation/controller surface for the entire app.

What moved where

App shell

- now only re-exports the real app entrypoint

- top-level app bootstrap

- shell layout and page composition

- top navigation and page switching UI

- shared success/error/banner rendering

- page switch registry

- controller context boundary for feature pages

  • apps/harbor-ui/src/App.tsx
  • apps/harbor-ui/src/app/App.tsx
  • apps/harbor-ui/src/app/AppShell.tsx
  • apps/harbor-ui/src/app/TopNav.tsx
  • apps/harbor-ui/src/app/GlobalBanners.tsx
  • apps/harbor-ui/src/app/pageRegistry.tsx
  • apps/harbor-ui/src/app/AppControllerContext.tsx

Shared helpers

- Harbor client creation and node-target auth wiring

- display formatting, labels, Dock sync text, plan text

- managed node target normalization and status helpers

  • apps/harbor-ui/src/shared/api/createClient.ts
  • apps/harbor-ui/src/shared/lib/formatters.ts
  • apps/harbor-ui/src/shared/lib/nodeTargets.ts

Feature pages

  • apps/harbor-ui/src/features/home/HomePage.tsx
  • apps/harbor-ui/src/features/manager/ManagerPage.tsx
  • apps/harbor-ui/src/features/ports/PortsPage.tsx
  • apps/harbor-ui/src/features/ports/PortWorkspacePage.tsx
  • apps/harbor-ui/src/features/fleet/FleetPage.tsx
  • apps/harbor-ui/src/features/executions/ExecutionsPage.tsx
  • apps/harbor-ui/src/features/audit/AuditPage.tsx
  • apps/harbor-ui/src/features/security/SecurityPage.tsx
  • apps/harbor-ui/src/features/settings/SettingsPage.tsx
  • apps/harbor-ui/src/features/plan/PlanPage.tsx

Ports feature split

The ports workflow is now explicitly divided into a list/create surface and a selected-port workspace surface.

- composes: - components/PortTools.tsx - components/PortList.tsx - components/AddPortPanel.tsx

- composes: - components/PortSummarySection.tsx - components/LiveActionsSection.tsx - components/ActionDetailsSection.tsx - components/ExecuteActionSection.tsx - components/ApprovalsSection.tsx - components/DraftWorkspaceSection.tsx - components/DraftListSection.tsx - components/LatestDockImportSection.tsx

- owns the ports list/workspace state, Dock sync state, OAuth polling, action execution inputs, draft authoring flow, and port mutation handlers

- owns agent profile/token state, profile detail loading, override editing, token filtering, and security actions

- owns manager config/policy state, managed-worker inventory, bootstrap flows, and manager action handlers

- owns audit filtering, selected event state, approval detail state, and approval resolution flow

- owns Fleet enrollment state, pairing inputs, managed-target state, and cloud enrollment actions

- owns local config draft state, operator-auth/session flows, remote access key management, notification filters, and backup export actions

- owns execution filters, selected execution state, delivery loading, cancellation, and execution refresh behavior

- owns Dock catalog shelf state, featured/newest/trending entry lists, and Hub refresh behavior

- owns cloning/reset helpers for node-local config drafts used by Settings and Executions

  • apps/harbor-ui/src/features/ports/PortsPage.tsx
  • apps/harbor-ui/src/features/ports/PortWorkspacePage.tsx
  • apps/harbor-ui/src/features/ports/usePortsDomain.ts
  • apps/harbor-ui/src/features/security/useSecurityDomain.ts
  • apps/harbor-ui/src/features/manager/useManagerDomain.ts
  • apps/harbor-ui/src/features/audit/useAuditDomain.ts
  • apps/harbor-ui/src/features/fleet/useFleetDomain.ts
  • apps/harbor-ui/src/features/settings/useNodeSettingsDomain.ts
  • apps/harbor-ui/src/features/executions/useExecutionsDomain.ts
  • apps/harbor-ui/src/features/dock/useDockCatalogDomain.ts
  • apps/harbor-ui/src/shared/lib/nodeConfig.ts

Feature-local helpers

  • apps/harbor-ui/src/features/home/homeUtils.ts
  • apps/harbor-ui/src/features/security/securityUtils.ts
  • apps/harbor-ui/src/features/ports/portUtils.ts

Intentional deviations from the original target shape

  • The page-oriented architecture is in place, but cross-page coordination still flows through apps/harbor-ui/src/app/useAppController.tsx.
  • ports, security, manager, audit, fleet, settings, executions, and dock now own their state/handlers in feature-domain hooks and are composed by the app controller.
  • Page hooks such as usePortsPage, usePortWorkspace, useManagerPage, and useSecurityPage are still adapters over the shared controller boundary rather than independent per-page providers.
  • I kept the existing class names and page flow instead of trying to normalize layout patterns during the same pass.

Technical debt left behind

  • apps/harbor-ui/src/app/useAppController.tsx is still the main cross-page coordinator for node targeting, overview refresh, polling, and shared derived view models, even though it is now down to roughly 1.3k lines instead of being the full monolith.
  • Some page hooks are still thin wrappers and can be deepened later into real feature controllers or narrowed selectors.
  • Cross-feature refresh behavior still routes through the shared controller, even though most domain logic now lives with the features that own it.

Suggested next refactor targets

  1. Move more feature-specific refresh/load logic closer to each domain hook so the top-level controller only owns cross-page concerns.
  2. Narrow the page hooks from full-context adapters into feature-shaped selectors once the remaining controller domains are split.
  3. Apply the same feature-domain/controller pattern to the other apps after validating the Harbor UI layout over a few commits.

Validation

  • pnpm --filter @harbor/harbor-ui typecheck
  • pnpm --filter @harbor/harbor-ui build
  • pnpm --filter @harbor/harbor-ui lint
  • pnpm -r build

The current lint script is intentionally lightweight in this milestone, so TypeScript and the production build remain the main correctness checks.