From b8437e8780d6e7eeb8f9f2a9a0570e71abb700c6 Mon Sep 17 00:00:00 2001 From: Anso Date: Fri, 1 May 2026 00:10:56 -0400 Subject: [PATCH] =?UTF-8?q?feat(fleet):=20=C2=A716=20orchestrator=20tab=20?= =?UTF-8?q?foundation=20(Deployments,=20Federation,=20Secrets)=20(#856)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reserves three navigable but non-functional tab slots on the Fleet page so each future orchestrator surface can land as a tab content swap rather than a navigation redesign. Each tab opens a coming-soon placeholder card listing the planned actions for that surface. --- frontend/src/components/FleetView.tsx | 48 +++++++++++++ .../components/fleet/FleetSoonPlaceholder.tsx | 67 +++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 frontend/src/components/fleet/FleetSoonPlaceholder.tsx diff --git a/frontend/src/components/FleetView.tsx b/frontend/src/components/FleetView.tsx index da643be2..a5136602 100644 --- a/frontend/src/components/FleetView.tsx +++ b/frontend/src/components/FleetView.tsx @@ -4,6 +4,7 @@ import { Layers, Wifi, WifiOff, Search, ArrowUpDown, AlertTriangle, Play, Square, RotateCcw, ExternalLink, Camera, Download, Loader2, Check, CircleCheck, CircleAlert, Globe, Monitor, X, LayoutGrid, Network, SlidersHorizontal, + Send, KeyRound, } from 'lucide-react'; import { FleetMasthead } from './fleet/FleetMasthead'; import { FleetTopology } from './fleet/FleetTopology'; @@ -28,6 +29,7 @@ import { useLicense } from '@/context/LicenseContext'; import { PaidGate } from './PaidGate'; import FleetSnapshots from './FleetSnapshots'; import { FleetConfiguration } from './fleet/FleetConfiguration'; +import { FleetSoonPlaceholder, SoonBadge } from './fleet/FleetSoonPlaceholder'; import { toast } from '@/components/ui/toast-store'; import { LabelDot } from './LabelPill'; import { type Label as StackLabel, type LabelColor } from './label-types'; @@ -1047,6 +1049,25 @@ export function FleetView({ onNavigateToNode }: FleetViewProps) { Status + + + + Deployments + + + + + + Federation + + + + + + Secrets + + +
@@ -1346,6 +1367,33 @@ export function FleetView({ onNavigateToNode }: FleetViewProps) { + + } + kicker="Deployments · Coming soon" + title="Push stacks across the fleet" + description="Push a stack from local to a remote in one move. Side-by-side compose diff, env reconciliation, volume migration plan." + plannedActions={['Push stack', 'Promote env', 'Diff config', 'Plan migration']} + /> + + + } + kicker="Federation · Coming soon" + title="The fleet as one logical surface" + description="Pin policies, drain a node for maintenance, weight-aware scheduling. This stack runs on whichever node has capacity." + plannedActions={['Pin policy', 'Drain node', 'Cordon', 'Capacity plan']} + /> + + + } + kicker="Secrets · Coming soon" + title="One source of truth for env, creds and certs" + description="Push to selected nodes, rotate centrally, audit who-saw-what. Solves silent drift across copies." + plannedActions={['Sync env', 'Rotate', 'Audit', 'Pin to nodes']} + /> + {/* Reconnecting overlay shown when local node is updating */} diff --git a/frontend/src/components/fleet/FleetSoonPlaceholder.tsx b/frontend/src/components/fleet/FleetSoonPlaceholder.tsx new file mode 100644 index 00000000..24136477 --- /dev/null +++ b/frontend/src/components/fleet/FleetSoonPlaceholder.tsx @@ -0,0 +1,67 @@ +import type { ReactNode } from 'react'; + +export function SoonBadge() { + return ( + + SOON + + ); +} + +interface FleetSoonPlaceholderProps { + icon: ReactNode; + kicker: string; + title: string; + description: string; + plannedActions: string[]; +} + +export function FleetSoonPlaceholder({ + icon, + kicker, + title, + description, + plannedActions, +}: FleetSoonPlaceholderProps) { + return ( +
+
+
+
+ + {icon} + + {kicker} +
+ + Coming soon + +
+ +

+ {title} +

+ +

+ {description} +

+ +
+ + Planned actions + +
+ {plannedActions.map((action) => ( + + {action} + + ))} +
+
+
+
+ ); +}