mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-25 17:57:06 +00:00
feat: RBAC, atomic deployments, and fleet-wide backups (Pro) (#181)
* feat: add RBAC viewer accounts, atomic deployments, and fleet-wide backups (Pro) Introduces three Pro-tier features: - RBAC: Multi-user system with admin/viewer roles, user management UI, automatic migration from single-admin credentials, viewer restrictions across the entire UI (read-only editor, hidden action buttons) - Atomic Deployments: Pre-deploy file backup to .sencho-backup/, automatic rollback on health probe failure, manual rollback button, health probes added to stack updates, webhook-triggered deploys use atomic rollback - Fleet-Wide Backups: Point-in-time snapshots of compose files across all nodes (local + remote), stored centrally in SQLite, per-stack restore with optional redeploy, graceful handling of offline nodes * fix(settings): use correct ProGate prop name in UsersSection * fix(settings): remove unused isPro prop from UsersSection * fix(auth): fetch user info after login and setup so isAdmin is set correctly
This commit is contained in:
@@ -15,6 +15,7 @@ import { Trash2, HelpCircle, AlertTriangle, Info, CheckCircle2, Loader2 } from '
|
||||
import { toast } from 'sonner';
|
||||
import { apiFetch } from '@/lib/api';
|
||||
import { useNodes } from '@/context/NodeContext';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
|
||||
interface StackAlert {
|
||||
id?: number;
|
||||
@@ -39,6 +40,7 @@ interface AgentStatus {
|
||||
}
|
||||
|
||||
export function StackAlertSheet({ isOpen, onClose, stackName }: StackAlertSheetProps) {
|
||||
const { isAdmin } = useAuth();
|
||||
const { activeNode } = useNodes();
|
||||
const isRemote = activeNode?.type === 'remote';
|
||||
|
||||
@@ -266,7 +268,7 @@ export function StackAlertSheet({ isOpen, onClose, stackName }: StackAlertSheetP
|
||||
Trigger after {alert.duration_mins}m • Cooldown: {alert.cooldown_mins}m
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
{isAdmin && <Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-muted-foreground hover:text-destructive shrink-0"
|
||||
@@ -274,7 +276,7 @@ export function StackAlertSheet({ isOpen, onClose, stackName }: StackAlertSheetP
|
||||
disabled={isLoading}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</Button>}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
@@ -284,7 +286,7 @@ export function StackAlertSheet({ isOpen, onClose, stackName }: StackAlertSheetP
|
||||
<hr />
|
||||
|
||||
{/* Add New Alert Form */}
|
||||
<div className="space-y-4">
|
||||
{isAdmin && <div className="space-y-4">
|
||||
<h4 className="text-sm font-semibold">Add New Rule</h4>
|
||||
|
||||
<div className="space-y-2">
|
||||
@@ -419,7 +421,7 @@ export function StackAlertSheet({ isOpen, onClose, stackName }: StackAlertSheetP
|
||||
'Add Rule'
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
</SheetContent>
|
||||
|
||||
Reference in New Issue
Block a user