feat(ui): Phase 57 - remote context UX (Option A) + network layer fixes

Task 1 - Network layer fixes:
- AppStoreView: replace raw fetch() with apiFetch() on /templates and
  /templates/deploy so x-node-id header is injected for proxy routing
- GlobalObservabilityView: replace raw fetch() with apiFetch() on
  /stacks and /logs/global
- HostConsole: append ?nodeId= to WebSocket URL so the upgrade handler
  correctly routes the PTY session to the active remote node

Task 2 - Scoped context two-tier UX (Option A / Portainer-style):
- EditorLayout: add a context pill in the top header bar showing the
  active node name (pulsing blue for remote, green for local)
- HostConsole: header now reads "Host Console - [Node Name]"
- ResourcesView: title now reads "Resources Hub - [Node Name]" for remote
- GlobalObservabilityView: floating node badge in top-left corner for remote
- AppStoreView: deploy sheet shows "Deploying to: [Node Name]" badge
- SettingsModal: remote nodes only see System Limits + Developer tabs;
  global-only tabs (Account, Appearance, Notifications, Nodes) are hidden;
  header subtitle shows remote node name
This commit is contained in:
SaelixCode
2026-03-19 20:39:57 -04:00
parent e027a94492
commit 04c770c198
7 changed files with 117 additions and 40 deletions
+17 -1
View File
@@ -796,7 +796,22 @@ export default function EditorLayout() {
{/* Main Content Area */}
<div className="flex-1 flex flex-col overflow-hidden">
{/* Top Header Bar */}
<div className="h-16 flex items-center justify-end px-6 border-b border-border gap-4">
<div className="h-16 flex items-center justify-between px-6 border-b border-border gap-4">
{/* Node Context Pill — visible only when a remote node is active */}
<div className="flex-shrink-0">
{activeNode?.type === 'remote' ? (
<div className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-blue-500/10 border border-blue-500/20 text-blue-400 text-sm font-medium">
<span className="w-2 h-2 rounded-full bg-blue-400 animate-pulse shrink-0" />
{activeNode.name}
</div>
) : (
<div className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-muted/50 border border-border text-muted-foreground text-sm">
<span className="w-2 h-2 rounded-full bg-green-500 shrink-0" />
{activeNode?.name ?? 'Local'}
</div>
)}
</div>
<div className="flex items-center gap-4">
{/* Home Button */}
<Button
variant="outline"
@@ -942,6 +957,7 @@ export default function EditorLayout() {
</ScrollArea>
</PopoverContent>
</Popover>
</div>{/* end right-side buttons */}
</div>
{/* Main Workspace */}