mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-21 23:56:39 +00:00
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:
@@ -8,6 +8,8 @@ import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Search, Rocket, Loader2, Info, ExternalLink, Github, Star } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { apiFetch } from '@/lib/api';
|
||||
import { useNodes } from '@/context/NodeContext';
|
||||
|
||||
export interface TemplateEnv {
|
||||
name: string;
|
||||
@@ -36,6 +38,7 @@ interface AppStoreViewProps {
|
||||
}
|
||||
|
||||
export function AppStoreView({ onDeploySuccess }: AppStoreViewProps) {
|
||||
const { activeNode } = useNodes();
|
||||
const [templates, setTemplates] = useState<Template[]>([]);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
|
||||
@@ -59,7 +62,7 @@ export function AppStoreView({ onDeploySuccess }: AppStoreViewProps) {
|
||||
|
||||
const fetchTemplates = async () => {
|
||||
try {
|
||||
const res = await fetch('/api/templates');
|
||||
const res = await apiFetch('/templates');
|
||||
if (!res.ok) throw new Error('Failed to fetch templates');
|
||||
const data = await res.json();
|
||||
setTemplates(data || []);
|
||||
@@ -156,9 +159,8 @@ export function AppStoreView({ onDeploySuccess }: AppStoreViewProps) {
|
||||
});
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/templates/deploy', {
|
||||
const res = await apiFetch('/templates/deploy', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
stackName: stackName.trim(),
|
||||
template: modifiedTemplate,
|
||||
@@ -255,6 +257,13 @@ export function AppStoreView({ onDeploySuccess }: AppStoreViewProps) {
|
||||
{selectedTemplate && (
|
||||
<div className="flex flex-col h-full">
|
||||
<SheetHeader className="mb-6 text-left">
|
||||
{activeNode?.type === 'remote' && (
|
||||
<div className="mb-2">
|
||||
<Badge variant="secondary" className="text-xs font-normal">
|
||||
Deploying to: {activeNode.name}
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="w-16 h-16 rounded bg-white p-1 flex-shrink-0 flex items-center justify-center overflow-hidden border">
|
||||
{!imgErrors[selectedTemplate.title] && selectedTemplate.logo ? (
|
||||
|
||||
Reference in New Issue
Block a user