mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-18 22:36:19 +00:00
feat: Remote Nodes Foundation (Strategy B) - Add nodes table with auto-seeded default local node in DatabaseService - Create NodeRegistry service for multi-instance Docker daemon connections - Add 6 Node management API endpoints (CRUD + test connection) - Create NodeManager component with table UI and connection testing - Add NodeContext for frontend-wide active node state management - Add node switcher dropdown to sidebar (visible when >1 node) - Add Nodes tab to Settings Hub
This commit is contained in:
@@ -12,7 +12,8 @@ import { Slider } from '@/components/ui/slider';
|
||||
import { toast } from 'sonner';
|
||||
import { apiFetch } from '@/lib/api';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Shield, Activity, Bell, Palette, Moon, Sun, Code } from 'lucide-react';
|
||||
import { Shield, Activity, Bell, Palette, Moon, Sun, Code, Server } from 'lucide-react';
|
||||
import { NodeManager } from './NodeManager';
|
||||
|
||||
interface Agent {
|
||||
type: 'discord' | 'slack' | 'webhook';
|
||||
@@ -28,7 +29,7 @@ interface SettingsModalProps {
|
||||
}
|
||||
|
||||
export function SettingsModal({ isOpen, onClose, isDarkMode, setIsDarkMode }: SettingsModalProps) {
|
||||
const [activeSection, setActiveSection] = useState<'account' | 'system' | 'notifications' | 'appearance' | 'developer'>('account');
|
||||
const [activeSection, setActiveSection] = useState<'account' | 'system' | 'notifications' | 'appearance' | 'developer' | 'nodes'>('account');
|
||||
|
||||
// Auth State
|
||||
const [authData, setAuthData] = useState({ oldPassword: '', newPassword: '', confirmPassword: '' });
|
||||
@@ -221,7 +222,7 @@ export function SettingsModal({ isOpen, onClose, isDarkMode, setIsDarkMode }: Se
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
||||
<DialogContent className="sm:max-w-[800px] h-[600px] flex p-0 font-sans shadow-lg bg-background border-border overflow-hidden gap-0">
|
||||
<DialogContent className="sm:max-w-[900px] h-[650px] flex p-0 font-sans shadow-lg bg-background border-border overflow-hidden gap-0">
|
||||
{/* Sidebar */}
|
||||
<div className="w-[200px] bg-muted/20 border-r border-border flex flex-col p-4 shrink-0">
|
||||
<div className="font-semibold text-lg mb-6 text-foreground tracking-tight">Settings Hub</div>
|
||||
@@ -266,6 +267,14 @@ export function SettingsModal({ isOpen, onClose, isDarkMode, setIsDarkMode }: Se
|
||||
<Code className="w-4 h-4 mr-2" />
|
||||
Developer
|
||||
</Button>
|
||||
<Button
|
||||
variant={activeSection === 'nodes' ? 'secondary' : 'ghost'}
|
||||
className="w-full justify-start font-medium"
|
||||
onClick={() => setActiveSection('nodes')}
|
||||
>
|
||||
<Server className="w-4 h-4 mr-2" />
|
||||
Nodes
|
||||
</Button>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -478,6 +487,10 @@ export function SettingsModal({ isOpen, onClose, isDarkMode, setIsDarkMode }: Se
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeSection === 'nodes' && (
|
||||
<NodeManager />
|
||||
)}
|
||||
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
Reference in New Issue
Block a user