add instruction and srs
453
src/web/dashboard-code.html
Normal file
@@ -0,0 +1,453 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Backup Appliance - Monitoring & Logs</title>
|
||||
<!-- Material Symbols -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Google Fonts: Manrope -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#111a22", /* Matching the example code background */
|
||||
"card-dark": "#1a2632", /* Slightly lighter than bg */
|
||||
"border-dark": "#324d67",
|
||||
"text-secondary": "#92adc9",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"],
|
||||
"mono": ["JetBrains Mono", "monospace"],
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Custom scrollbar for log viewer */
|
||||
.custom-scrollbar::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
.custom-scrollbar::-webkit-scrollbar-track {
|
||||
background: #111a22;
|
||||
}
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: #476685;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-slate-900 dark:text-white font-display overflow-hidden">
|
||||
<div class="flex h-screen w-full">
|
||||
<!-- SIDEBAR -->
|
||||
<aside class="w-64 flex flex-col border-r border-border-dark bg-background-dark flex-shrink-0 z-20">
|
||||
<div class="p-6 flex flex-col gap-1">
|
||||
<h1 class="text-white text-lg font-bold leading-normal tracking-tight">Backup Appliance</h1>
|
||||
<p class="text-text-secondary text-xs font-mono">v4.2.0-stable</p>
|
||||
</div>
|
||||
<nav class="flex-1 overflow-y-auto px-4 space-y-2">
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">dashboard</span>
|
||||
<span class="text-sm font-medium">Dashboard</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">hard_drive</span>
|
||||
<span class="text-sm font-medium">Storage</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">network_check</span>
|
||||
<span class="text-sm font-medium">Network</span>
|
||||
</a>
|
||||
<!-- Active State -->
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg bg-[#233648] text-primary border border-primary/20" href="#">
|
||||
<span class="material-symbols-outlined text-[24px] fill-current">monitoring</span>
|
||||
<span class="text-sm font-bold">Monitor & Logs</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">settings</span>
|
||||
<span class="text-sm font-medium">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
<div class="p-4 border-t border-border-dark">
|
||||
<div class="flex items-center gap-3 p-2 rounded-lg bg-card-dark border border-border-dark">
|
||||
<div class="h-8 w-8 rounded-full bg-primary flex items-center justify-center text-white font-bold text-xs">AD</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-xs font-bold text-white">Admin User</span>
|
||||
<span class="text-[10px] text-text-secondary">admin@local</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- MAIN CONTENT -->
|
||||
<main class="flex-1 flex flex-col min-w-0 bg-background-dark overflow-hidden relative">
|
||||
<!-- HEADER -->
|
||||
<header class="flex-none px-6 py-5 border-b border-border-dark bg-background-dark/95 backdrop-blur z-10">
|
||||
<div class="flex flex-wrap justify-between items-end gap-3 max-w-[1600px] mx-auto">
|
||||
<div class="flex flex-col gap-1">
|
||||
<h2 class="text-white text-3xl font-black tracking-tight">System Monitor</h2>
|
||||
<p class="text-text-secondary text-sm">Real-time telemetry, ZFS health, and system event logs</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-2 px-3 py-2 bg-card-dark rounded-lg border border-border-dark">
|
||||
<span class="relative flex h-2 w-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-2 w-2 bg-emerald-500"></span>
|
||||
</span>
|
||||
<span class="text-xs font-medium text-emerald-400">System Healthy</span>
|
||||
</div>
|
||||
<button class="flex items-center gap-2 h-10 px-4 bg-card-dark hover:bg-[#233648] border border-border-dark text-white text-sm font-bold rounded-lg transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px]">refresh</span>
|
||||
<span>Refresh: 5s</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- SCROLLABLE CONTENT AREA -->
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar p-6">
|
||||
<div class="flex flex-col gap-6 max-w-[1600px] mx-auto pb-10">
|
||||
<!-- TOP STATS ROW -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<!-- CPU -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">CPU Load</p>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[20px]">memory</span>
|
||||
</div>
|
||||
<div class="flex items-end gap-3 mt-1">
|
||||
<p class="text-white text-3xl font-bold">12%</p>
|
||||
<span class="text-emerald-500 text-sm font-medium mb-1 flex items-center">
|
||||
<span class="material-symbols-outlined text-[16px]">trending_down</span> 2%
|
||||
</span>
|
||||
</div>
|
||||
<!-- Mini Sparkline visualization -->
|
||||
<div class="h-1.5 w-full bg-[#233648] rounded-full mt-3 overflow-hidden">
|
||||
<div class="h-full bg-primary w-[12%] rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RAM -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">RAM Usage</p>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[20px]">memory_alt</span>
|
||||
</div>
|
||||
<div class="flex items-end gap-3 mt-1">
|
||||
<p class="text-white text-3xl font-bold">8.4 <span class="text-lg text-text-secondary font-medium">GB</span></p>
|
||||
<span class="text-text-secondary text-xs mb-2">/ 32 GB</span>
|
||||
</div>
|
||||
<div class="h-1.5 w-full bg-[#233648] rounded-full mt-3 overflow-hidden">
|
||||
<div class="h-full bg-emerald-500 w-[26%] rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ZFS Health -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">ZFS Pool Status</p>
|
||||
<span class="material-symbols-outlined text-emerald-500 text-[20px]">check_circle</span>
|
||||
</div>
|
||||
<div class="flex items-end gap-3 mt-1">
|
||||
<p class="text-white text-3xl font-bold">Online</p>
|
||||
<span class="text-text-secondary text-sm font-medium mb-1">No Errors</span>
|
||||
</div>
|
||||
<div class="flex gap-1 mt-3">
|
||||
<div class="h-1.5 flex-1 bg-emerald-500 rounded-l-full"></div>
|
||||
<div class="h-1.5 flex-1 bg-emerald-500"></div>
|
||||
<div class="h-1.5 flex-1 bg-emerald-500"></div>
|
||||
<div class="h-1.5 flex-1 bg-emerald-500 rounded-r-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Uptime -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">System Uptime</p>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[20px]">schedule</span>
|
||||
</div>
|
||||
<div class="mt-1">
|
||||
<p class="text-white text-3xl font-bold">14d 2h 12m</p>
|
||||
</div>
|
||||
<p class="text-text-secondary text-xs mt-3">Last reboot: Manual Patching</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MIDDLE SECTION: CHARTS & DISKS -->
|
||||
<div class="grid grid-cols-1 xl:grid-cols-3 gap-6">
|
||||
<!-- CHARTS COLUMN (2/3) -->
|
||||
<div class="xl:col-span-2 flex flex-col gap-6">
|
||||
<!-- Network Chart -->
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl p-6 shadow-sm">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h3 class="text-white text-lg font-bold">Network Throughput</h3>
|
||||
<p class="text-text-secondary text-sm">Inbound vs Outbound (eth0)</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-white text-2xl font-bold leading-tight">1.2 Gbps</p>
|
||||
<p class="text-emerald-500 text-sm">Peak: 2.1 Gbps</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-[200px] w-full relative">
|
||||
<!-- Simulated SVG Chart -->
|
||||
<svg class="w-full h-full" preserveaspectratio="none" viewbox="0 0 1000 200">
|
||||
<defs>
|
||||
<lineargradient id="gradientPrimary" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#137fec" stop-opacity="0.2"></stop>
|
||||
<stop offset="100%" stop-color="#137fec" stop-opacity="0"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<!-- Outbound Line -->
|
||||
<path d="M0,150 Q100,140 200,100 T400,120 T600,80 T800,140 T1000,100" fill="none" stroke="#92adc9" stroke-dasharray="5,5" stroke-width="2"></path>
|
||||
<!-- Inbound Area -->
|
||||
<path d="M0,120 Q150,150 300,50 T600,80 T900,40 L1000,60 V200 H0 Z" fill="url(#gradientPrimary)"></path>
|
||||
<path d="M0,120 Q150,150 300,50 T600,80 T900,40 L1000,60" fill="none" stroke="#137fec" stroke-width="3"></path>
|
||||
</svg>
|
||||
<!-- X-Axis Labels -->
|
||||
<div class="flex justify-between text-text-secondary text-xs mt-2 font-mono">
|
||||
<span>10:00</span>
|
||||
<span>10:15</span>
|
||||
<span>10:30</span>
|
||||
<span>10:45</span>
|
||||
<span>11:00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ZFS ARC Chart -->
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl p-6 shadow-sm">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h3 class="text-white text-lg font-bold">ZFS ARC Hit Ratio</h3>
|
||||
<p class="text-text-secondary text-sm">Cache efficiency</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-white text-2xl font-bold leading-tight">94%</p>
|
||||
<p class="text-text-secondary text-sm">Target: >90%</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-[150px] w-full relative">
|
||||
<!-- Simulated SVG Chart -->
|
||||
<svg class="w-full h-full" preserveaspectratio="none" viewbox="0 0 1000 150">
|
||||
<path d="M0,40 L100,40 L105,80 L110,40 L300,35 L305,90 L310,35 L600,30 L605,100 L610,30 L1000,25" fill="none" stroke="#10b981" stroke-width="2"></path>
|
||||
</svg>
|
||||
<div class="w-full h-[1px] bg-border-dark absolute top-[20%]"></div>
|
||||
<div class="absolute top-[20%] right-0 text-xs text-text-secondary -mt-5">95%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- DISK HEATMAP COLUMN (1/3) -->
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl p-6 h-full shadow-sm flex flex-col">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="text-white text-lg font-bold">Disk Health</h3>
|
||||
<span class="bg-[#233648] text-white text-xs px-2 py-1 rounded border border-border-dark">Pool 1</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-4 gap-3 flex-1 content-start">
|
||||
<!-- Healthy Disks -->
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center group relative cursor-help">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da0</span>
|
||||
<div class="absolute bottom-full mb-2 hidden group-hover:block bg-black text-white text-xs p-2 rounded whitespace-nowrap z-10">Serial: Z802JKA</div>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da1</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da2</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da3</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da4</span>
|
||||
</div>
|
||||
<!-- Warning Disk -->
|
||||
<div class="aspect-square bg-[#332a18] border border-yellow-700/50 rounded flex flex-col items-center justify-center relative">
|
||||
<span class="absolute top-1 right-1 h-2 w-2 rounded-full bg-yellow-500 animate-pulse"></span>
|
||||
<span class="material-symbols-outlined text-yellow-500">warning</span>
|
||||
<span class="text-[10px] text-yellow-500 font-mono mt-1">da5</span>
|
||||
</div>
|
||||
<!-- Healthy Disks -->
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da6</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da7</span>
|
||||
</div>
|
||||
<!-- Empty/Spare Slots -->
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 pt-4 border-t border-border-dark">
|
||||
<div class="flex justify-between text-sm text-text-secondary">
|
||||
<span>Total Capacity</span>
|
||||
<span class="text-white font-bold">64 TB</span>
|
||||
</div>
|
||||
<div class="w-full bg-[#233648] h-2 rounded-full mt-2 overflow-hidden">
|
||||
<div class="bg-primary h-full w-[65%]"></div>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs text-text-secondary mt-1">
|
||||
<span>Used: 41.6 TB</span>
|
||||
<span>Free: 22.4 TB</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- BOTTOM SECTION: TABS & LOGS -->
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl shadow-sm overflow-hidden flex flex-col h-[400px]">
|
||||
<!-- Tabs Header -->
|
||||
<div class="flex border-b border-border-dark bg-[#161f29]">
|
||||
<button class="px-6 py-4 text-sm font-bold text-primary border-b-2 border-primary bg-card-dark">
|
||||
Active Jobs <span class="ml-2 bg-primary/20 text-primary px-1.5 py-0.5 rounded text-xs">2</span>
|
||||
</button>
|
||||
<button class="px-6 py-4 text-sm font-medium text-text-secondary hover:text-white transition-colors">
|
||||
System Logs
|
||||
</button>
|
||||
<button class="px-6 py-4 text-sm font-medium text-text-secondary hover:text-white transition-colors">
|
||||
Alerts History
|
||||
</button>
|
||||
<div class="flex-1 flex justify-end items-center px-4">
|
||||
<div class="relative">
|
||||
<span class="material-symbols-outlined absolute left-2 top-1.5 text-text-secondary text-[18px]">search</span>
|
||||
<input class="bg-[#111a22] border border-border-dark rounded-md py-1 pl-8 pr-3 text-sm text-white focus:outline-none focus:border-primary w-48 transition-all" placeholder="Search logs..." type="text"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tab Content: Active Jobs + Logs Combined View for design -->
|
||||
<div class="flex-1 overflow-hidden flex flex-col">
|
||||
<!-- Jobs Section -->
|
||||
<div class="p-0">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead class="bg-[#1a2632] text-xs uppercase text-text-secondary font-medium sticky top-0 z-10">
|
||||
<tr>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Job Name</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Type</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark w-1/3">Progress</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Speed</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-sm divide-y divide-border-dark">
|
||||
<!-- Active Job 1 -->
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-4 font-medium text-white">Daily Backup: VM-Cluster-01</td>
|
||||
<td class="px-6 py-4 text-text-secondary">Replication</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-full bg-[#111a22] rounded-full h-2 overflow-hidden">
|
||||
<div class="bg-primary h-full rounded-full w-[45%] relative overflow-hidden">
|
||||
<div class="absolute inset-0 bg-white/20 animate-[pulse_2s_infinite]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-xs font-mono text-white">45%</span>
|
||||
</div>
|
||||
<p class="text-[10px] text-text-secondary mt-1">ETA: 1h 12m</p>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-text-secondary font-mono">145 MB/s</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-primary/20 text-primary">
|
||||
Running
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Active Job 2 -->
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-4 font-medium text-white">ZFS Scrub: Pool-01</td>
|
||||
<td class="px-6 py-4 text-text-secondary">Maintenance</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-full bg-[#111a22] rounded-full h-2 overflow-hidden">
|
||||
<div class="bg-primary h-full rounded-full w-[78%] relative overflow-hidden"></div>
|
||||
</div>
|
||||
<span class="text-xs font-mono text-white">78%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-text-secondary font-mono">1.2 GB/s</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-primary/20 text-primary">
|
||||
Running
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Logs Section Header (Visual Separator) -->
|
||||
<div class="px-6 py-2 bg-[#161f29] border-y border-border-dark flex items-center justify-between">
|
||||
<h4 class="text-xs uppercase text-text-secondary font-bold tracking-wider">Recent System Events</h4>
|
||||
<button class="text-xs text-primary hover:text-white transition-colors">View All Logs</button>
|
||||
</div>
|
||||
<!-- Logs Table -->
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar bg-[#111a22]">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<tbody class="text-sm font-mono divide-y divide-border-dark/50">
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:45:22</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-emerald-500">INFO</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">systemd</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">Started User Manager for UID 1000.</td>
|
||||
</tr>
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:45:15</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-yellow-500">WARN</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">smartd</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">Device: /dev/ada5, SMART Usage Attribute: 194 Temperature_Celsius changed from 38 to 41</td>
|
||||
</tr>
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:44:58</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-emerald-500">INFO</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">kernel</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">ix0: link state changed to UP</td>
|
||||
</tr>
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:42:10</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-emerald-500">INFO</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">zfs</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">zfs_arc_reclaim_thread: reclaiming 157286400 bytes ...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body></html>
|
||||
BIN
src/web/dashboard.png
Normal file
|
After Width: | Height: | Size: 272 KiB |
401
src/web/iscsi-management-code.html
Normal file
@@ -0,0 +1,401 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>iSCSI Management - Backup Appliance</title>
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#101922",
|
||||
"card-dark": "#16202a",
|
||||
"border-dark": "#2a3b4d",
|
||||
"text-secondary": "#92adc9"
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"],
|
||||
"mono": ["Noto Sans Mono", "monospace"]
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Custom scrollbar for webkit */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #111a22;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #46607a;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark font-display text-white overflow-hidden">
|
||||
<div class="flex h-screen w-full overflow-hidden">
|
||||
<!-- Side Navigation -->
|
||||
<div class="w-64 flex-shrink-0 flex flex-col bg-card-dark border-r border-border-dark h-full">
|
||||
<div class="flex flex-col h-full p-4">
|
||||
<!-- Header Profile -->
|
||||
<div class="flex gap-3 items-center mb-8 px-2">
|
||||
<div class="bg-center bg-no-repeat aspect-square bg-cover rounded-full size-10 border border-border-dark" data-alt="User avatar abstract pattern" style='background-image: url("https://lh3.googleusercontent.com/aida-public/AB6AXuCJzKcwFPccDv__mDYernJcx4x-1RaTn-w6K_hxr0iUUTE3xdGfUTI_hhfzMV2mhqO9cVPahE5gX6S4QuOr3teWZ1YH0wvsh1rSWwefN2m2PQEr8-51Z9mHsAlwkXnBK_LsLe7oXWMJT-HP55P30D8y_M1GeCJIFpEPpM9dkrJCB_lG9yx6MCCQsWKySuAKZCGuFnmHPXhyLqNjCzdfwtZfbiOHdvL7f39qstx3_MgW4D0QAvnp4_q0rksyLt6Iu9grimhngf42C_M");'></div>
|
||||
<div class="flex flex-col">
|
||||
<h1 class="text-white text-base font-bold leading-normal">Backup Appliance</h1>
|
||||
<p class="text-text-secondary text-xs font-normal leading-normal">Host: backup-z01</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Navigation Links -->
|
||||
<nav class="flex flex-col gap-2 flex-1">
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-white/5 hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white" style="font-size: 24px;">dashboard</span>
|
||||
<span class="text-sm font-medium leading-normal">Dashboard</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg bg-primary/20 text-white border border-primary/20" href="#">
|
||||
<span class="material-symbols-outlined text-primary" style="font-size: 24px;">hard_drive</span>
|
||||
<span class="text-sm font-bold leading-normal">Storage</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-white/5 hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white" style="font-size: 24px;">share</span>
|
||||
<span class="text-sm font-medium leading-normal">Network</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-white/5 hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white" style="font-size: 24px;">settings</span>
|
||||
<span class="text-sm font-medium leading-normal">System</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-white/5 hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white" style="font-size: 24px;">description</span>
|
||||
<span class="text-sm font-medium leading-normal">Logs</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-white/5 hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white" style="font-size: 24px;">terminal</span>
|
||||
<span class="text-sm font-medium leading-normal">Terminal</span>
|
||||
</a>
|
||||
</nav>
|
||||
<div class="mt-auto pt-4 border-t border-border-dark">
|
||||
<a class="flex items-center gap-3 px-3 py-2 text-text-secondary hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined" style="font-size: 20px;">logout</span>
|
||||
<span class="text-sm font-medium">Logout</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Main Content Area -->
|
||||
<div class="flex-1 flex flex-col h-full overflow-hidden relative">
|
||||
<!-- Scrollable Container -->
|
||||
<div class="flex-1 overflow-y-auto p-8">
|
||||
<div class="max-w-[1200px] mx-auto flex flex-col gap-6">
|
||||
<!-- Breadcrumbs -->
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<a class="text-text-secondary text-sm font-medium hover:text-white transition-colors" href="#">Storage</a>
|
||||
<span class="material-symbols-outlined text-text-secondary" style="font-size: 16px;">chevron_right</span>
|
||||
<span class="text-white text-sm font-medium">iSCSI Management</span>
|
||||
</div>
|
||||
<!-- Page Heading -->
|
||||
<div class="flex flex-wrap justify-between items-end gap-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<h1 class="text-white text-3xl font-extrabold leading-tight tracking-tight">iSCSI Management</h1>
|
||||
<p class="text-text-secondary text-base font-normal">Manage targets, portals, and initiator access control lists.</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<button class="flex items-center gap-2 px-4 h-10 rounded-lg bg-card-dark border border-border-dark hover:bg-white/5 text-white text-sm font-semibold transition-colors">
|
||||
<span class="material-symbols-outlined" style="font-size: 20px;">settings</span>
|
||||
<span>Global Settings</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-2 px-4 h-10 rounded-lg bg-primary hover:bg-blue-600 text-white text-sm font-bold shadow-lg shadow-blue-900/20 transition-colors">
|
||||
<span class="material-symbols-outlined" style="font-size: 20px;">add</span>
|
||||
<span>Create Target</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stats Cards -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div class="flex flex-col gap-1 rounded-xl p-5 bg-card-dark border border-border-dark shadow-sm">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<p class="text-text-secondary text-sm font-medium uppercase tracking-wider">Service Status</p>
|
||||
<span class="material-symbols-outlined text-green-500" style="font-size: 24px;">check_circle</span>
|
||||
</div>
|
||||
<p class="text-white text-2xl font-bold">Running</p>
|
||||
<p class="text-green-500 text-xs font-medium mt-1">Uptime: 14d 2h</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1 rounded-xl p-5 bg-card-dark border border-border-dark shadow-sm">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<p class="text-text-secondary text-sm font-medium uppercase tracking-wider">Port Binding</p>
|
||||
<span class="material-symbols-outlined text-text-secondary" style="font-size: 24px;">dns</span>
|
||||
</div>
|
||||
<p class="text-white text-2xl font-bold">3260</p>
|
||||
<p class="text-text-secondary text-xs font-medium mt-1">Listening on 0.0.0.0</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1 rounded-xl p-5 bg-card-dark border border-border-dark shadow-sm">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<p class="text-text-secondary text-sm font-medium uppercase tracking-wider">Active Sessions</p>
|
||||
<span class="material-symbols-outlined text-primary" style="font-size: 24px;">swap_horiz</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-2">
|
||||
<p class="text-white text-2xl font-bold">12</p>
|
||||
<span class="text-green-500 text-sm font-medium flex items-center">
|
||||
<span class="material-symbols-outlined" style="font-size: 16px;">arrow_upward</span> 2
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-text-secondary text-xs font-medium mt-1">Total throughput: 450 MB/s</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tabs & Filters -->
|
||||
<div class="flex flex-col bg-card-dark border border-border-dark rounded-xl overflow-hidden shadow-sm">
|
||||
<!-- Tabs Header -->
|
||||
<div class="border-b border-border-dark px-6">
|
||||
<div class="flex gap-8">
|
||||
<button class="relative py-4 text-primary font-bold text-sm tracking-wide">
|
||||
Targets
|
||||
<div class="absolute bottom-0 left-0 w-full h-0.5 bg-primary rounded-t-full"></div>
|
||||
</button>
|
||||
<button class="relative py-4 text-text-secondary hover:text-white font-medium text-sm tracking-wide transition-colors">
|
||||
Portals
|
||||
</button>
|
||||
<button class="relative py-4 text-text-secondary hover:text-white font-medium text-sm tracking-wide transition-colors">
|
||||
Initiators
|
||||
</button>
|
||||
<button class="relative py-4 text-text-secondary hover:text-white font-medium text-sm tracking-wide transition-colors">
|
||||
Extents
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Toolbar -->
|
||||
<div class="p-4 flex items-center justify-between gap-4 border-b border-border-dark/50 bg-[#141d26]">
|
||||
<div class="relative flex-1 max-w-md">
|
||||
<span class="absolute left-3 top-1/2 -translate-y-1/2 material-symbols-outlined text-text-secondary" style="font-size: 20px;">search</span>
|
||||
<input class="w-full bg-[#0f161d] border border-border-dark rounded-lg pl-10 pr-4 py-2 text-sm text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all placeholder-text-secondary/50" placeholder="Search targets by alias or IQN..." type="text"/>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-2 px-3 py-1.5 rounded-md bg-[#0f161d] border border-border-dark">
|
||||
<span class="text-xs text-text-secondary font-medium">Filter:</span>
|
||||
<select class="bg-transparent text-xs text-white font-medium focus:outline-none cursor-pointer">
|
||||
<option>All Status</option>
|
||||
<option>Online</option>
|
||||
<option>Offline</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Targets List -->
|
||||
<div class="flex flex-col">
|
||||
<!-- Row 1: Expanded -->
|
||||
<div class="group border-b border-border-dark bg-white/[0.02]">
|
||||
<!-- Main Row -->
|
||||
<div class="flex items-center p-4 gap-4 hover:bg-white/5 transition-colors cursor-pointer border-l-4 border-primary">
|
||||
<div class="p-2 rounded-md bg-primary/10 text-primary">
|
||||
<span class="material-symbols-outlined" style="font-size: 24px;">dns</span>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0 flex flex-col gap-1">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-white font-bold text-sm">backup-target-01</span>
|
||||
<span class="px-2 py-0.5 rounded-full bg-green-500/20 text-green-400 text-[10px] font-bold uppercase tracking-wide border border-green-500/20">Online</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 group/iqn">
|
||||
<span class="text-text-secondary font-mono text-xs truncate">iqn.2023-10.lan.backup:target01</span>
|
||||
<button class="opacity-0 group-hover/iqn:opacity-100 text-text-secondary hover:text-white transition-opacity" title="Copy IQN">
|
||||
<span class="material-symbols-outlined" style="font-size: 14px;">content_copy</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden md:flex items-center gap-8 mr-4">
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] uppercase text-text-secondary font-bold tracking-wider">LUNs</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-text-secondary" style="font-size: 16px;">hard_drive</span>
|
||||
<span class="text-white text-sm font-bold">3</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] uppercase text-text-secondary font-bold tracking-wider">Auth</span>
|
||||
<span class="text-white text-sm font-medium">CHAP</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="p-2 hover:bg-white/10 rounded-full text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined" style="font-size: 24px;">expand_less</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Expanded Detail Panel -->
|
||||
<div class="px-4 pb-4 pt-0">
|
||||
<div class="bg-[#0f161d] border border-border-dark rounded-lg p-4 grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<!-- Left: LUNs -->
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-xs font-bold text-text-secondary uppercase tracking-wider">Attached LUNs</h4>
|
||||
<button class="text-primary text-xs font-bold hover:underline">+ Add LUN</button>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<!-- LUN Item -->
|
||||
<div class="flex items-center justify-between p-3 rounded bg-card-dark border border-border-dark hover:border-border-dark/80 transition-colors">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-blue-500/10 text-blue-400 p-1.5 rounded">
|
||||
<span class="material-symbols-outlined" style="font-size: 18px;">pie_chart</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-white text-xs font-bold">LUN 0</span>
|
||||
<span class="text-text-secondary text-[10px]">zvol/tank/vm-backups/win-server</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="text-white text-xs font-mono">500 GB</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- LUN Item -->
|
||||
<div class="flex items-center justify-between p-3 rounded bg-card-dark border border-border-dark hover:border-border-dark/80 transition-colors">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-blue-500/10 text-blue-400 p-1.5 rounded">
|
||||
<span class="material-symbols-outlined" style="font-size: 18px;">pie_chart</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-white text-xs font-bold">LUN 1</span>
|
||||
<span class="text-text-secondary text-[10px]">file/mnt/tank/iso-store</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="text-white text-xs font-mono">2.5 TB</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right: ACLs & Config -->
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-xs font-bold text-text-secondary uppercase tracking-wider">Access Control</h4>
|
||||
<button class="text-primary text-xs font-bold hover:underline">Edit Policy</button>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 h-full">
|
||||
<div class="p-3 rounded bg-card-dark border border-border-dark flex flex-col gap-2">
|
||||
<div class="flex justify-between items-center pb-2 border-b border-border-dark/50">
|
||||
<span class="text-text-secondary text-xs">Auth Method</span>
|
||||
<span class="text-white text-xs font-bold">CHAP Mutual</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center py-1">
|
||||
<span class="text-text-secondary text-xs">Initiator Group</span>
|
||||
<span class="text-primary text-xs font-bold cursor-pointer hover:underline">group-esxi-cluster-01</span>
|
||||
</div>
|
||||
<div class="mt-2 bg-[#0f161d] p-2 rounded border border-border-dark/30">
|
||||
<p class="text-[10px] text-text-secondary mb-1">Allowed Initiators (3):</p>
|
||||
<p class="text-[10px] font-mono text-white/80">iqn.1998-01.com.vmware:esx01-4a2b...</p>
|
||||
<p class="text-[10px] font-mono text-white/80">iqn.1998-01.com.vmware:esx02-9c3d...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Action Footer in Expanded View -->
|
||||
<div class="col-span-1 lg:col-span-2 flex justify-end gap-2 mt-2 pt-3 border-t border-border-dark/50">
|
||||
<button class="px-3 py-1.5 rounded text-xs font-bold text-red-400 hover:bg-red-400/10 transition-colors">Delete Target</button>
|
||||
<button class="px-3 py-1.5 rounded text-xs font-bold text-text-secondary hover:bg-white/10 transition-colors">View Metrics</button>
|
||||
<button class="px-3 py-1.5 rounded bg-primary text-white text-xs font-bold hover:bg-blue-600 transition-colors">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Row 2: Collapsed -->
|
||||
<div class="group border-b border-border-dark bg-transparent">
|
||||
<div class="flex items-center p-4 gap-4 hover:bg-white/5 transition-colors cursor-pointer border-l-4 border-transparent hover:border-border-dark">
|
||||
<div class="p-2 rounded-md bg-border-dark/50 text-text-secondary">
|
||||
<span class="material-symbols-outlined" style="font-size: 24px;">dns</span>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0 flex flex-col gap-1">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-white font-bold text-sm">archive-cold-storage</span>
|
||||
<span class="px-2 py-0.5 rounded-full bg-yellow-500/20 text-yellow-500 text-[10px] font-bold uppercase tracking-wide border border-yellow-500/20">Idle</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 group/iqn">
|
||||
<span class="text-text-secondary font-mono text-xs truncate">iqn.2023-10.lan.backup:archive002</span>
|
||||
<button class="opacity-0 group-hover/iqn:opacity-100 text-text-secondary hover:text-white transition-opacity">
|
||||
<span class="material-symbols-outlined" style="font-size: 14px;">content_copy</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden md:flex items-center gap-8 mr-4">
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] uppercase text-text-secondary font-bold tracking-wider">LUNs</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-text-secondary" style="font-size: 16px;">hard_drive</span>
|
||||
<span class="text-white text-sm font-bold">1</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] uppercase text-text-secondary font-bold tracking-wider">Auth</span>
|
||||
<span class="text-white text-sm font-medium">None</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="p-2 hover:bg-white/10 rounded-full text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined" style="font-size: 24px;">expand_more</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Row 3: Collapsed -->
|
||||
<div class="group border-b border-border-dark bg-transparent">
|
||||
<div class="flex items-center p-4 gap-4 hover:bg-white/5 transition-colors cursor-pointer border-l-4 border-transparent hover:border-border-dark">
|
||||
<div class="p-2 rounded-md bg-border-dark/50 text-text-secondary">
|
||||
<span class="material-symbols-outlined" style="font-size: 24px;">dns</span>
|
||||
</div>
|
||||
<div class="flex-1 min-w-0 flex flex-col gap-1">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-white font-bold text-sm">dev-sandbox-target</span>
|
||||
<span class="px-2 py-0.5 rounded-full bg-red-500/20 text-red-400 text-[10px] font-bold uppercase tracking-wide border border-red-500/20">Offline</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 group/iqn">
|
||||
<span class="text-text-secondary font-mono text-xs truncate">iqn.2023-10.lan.backup:sandbox-dev</span>
|
||||
<button class="opacity-0 group-hover/iqn:opacity-100 text-text-secondary hover:text-white transition-opacity">
|
||||
<span class="material-symbols-outlined" style="font-size: 14px;">content_copy</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden md:flex items-center gap-8 mr-4">
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] uppercase text-text-secondary font-bold tracking-wider">LUNs</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-text-secondary" style="font-size: 16px;">hard_drive</span>
|
||||
<span class="text-text-secondary text-sm font-bold">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<span class="text-[10px] uppercase text-text-secondary font-bold tracking-wider">Auth</span>
|
||||
<span class="text-white text-sm font-medium">CHAP</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="p-2 hover:bg-white/10 rounded-full text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined" style="font-size: 24px;">expand_more</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pagination / Footer of table -->
|
||||
<div class="p-4 bg-[#141d26] border-t border-border-dark flex items-center justify-between">
|
||||
<p class="text-xs text-text-secondary">Showing 1-3 of 3 targets</p>
|
||||
<div class="flex gap-2">
|
||||
<button class="p-1 rounded text-text-secondary hover:text-white hover:bg-white/10 disabled:opacity-50">
|
||||
<span class="material-symbols-outlined" style="font-size: 20px;">chevron_left</span>
|
||||
</button>
|
||||
<button class="p-1 rounded text-text-secondary hover:text-white hover:bg-white/10">
|
||||
<span class="material-symbols-outlined" style="font-size: 20px;">chevron_right</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
BIN
src/web/iscsi-management.png
Normal file
|
After Width: | Height: | Size: 270 KiB |
470
src/web/shares-management-code.html
Normal file
@@ -0,0 +1,470 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Shares Management</title>
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<!-- Theme Configuration -->
|
||||
<script>
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#111a22", /* Matched to component background for consistency */
|
||||
"surface-dark": "#192633",
|
||||
"border-dark": "#324d67",
|
||||
"text-secondary": "#92adc9",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"]
|
||||
},
|
||||
borderRadius: {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Manrope', sans-serif;
|
||||
}
|
||||
/* Custom scrollbar for webkit */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #111a22;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #137fec;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-slate-900 dark:text-white overflow-hidden">
|
||||
<div class="relative flex h-screen w-full flex-row overflow-hidden">
|
||||
<!-- SideNavBar -->
|
||||
<div class="hidden lg:flex w-72 flex-col border-r border-border-dark bg-background-dark flex-shrink-0">
|
||||
<div class="flex h-full flex-col justify-between p-4">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex gap-3 px-2 py-2">
|
||||
<div class="bg-center bg-no-repeat aspect-square bg-cover rounded-full size-10 bg-primary/20 flex items-center justify-center text-primary" data-alt="System Logo">
|
||||
<span class="material-symbols-outlined">dns</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h1 class="text-white text-base font-medium leading-normal">Backup Appliance</h1>
|
||||
<p class="text-text-secondary text-sm font-normal leading-normal">System Admin</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-px bg-border-dark my-1"></div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-surface-dark cursor-pointer text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">dashboard</span>
|
||||
<p class="text-sm font-medium leading-normal">Dashboard</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-surface-dark cursor-pointer text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">hard_drive</span>
|
||||
<p class="text-sm font-medium leading-normal">Storage</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-surface-dark cursor-pointer text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">share</span>
|
||||
<p class="text-sm font-medium leading-normal">Networking</p>
|
||||
</div>
|
||||
<!-- Active State -->
|
||||
<div class="flex items-center gap-3 px-3 py-2 rounded-lg bg-primary text-white shadow-lg shadow-primary/20">
|
||||
<span class="material-symbols-outlined">folder_shared</span>
|
||||
<p class="text-sm font-medium leading-normal">Shares</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-surface-dark cursor-pointer text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">desktop_windows</span>
|
||||
<p class="text-sm font-medium leading-normal">Virtualization</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-surface-dark cursor-pointer text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">settings</span>
|
||||
<p class="text-sm font-medium leading-normal">System</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="flex w-full cursor-pointer items-center justify-center overflow-hidden rounded-lg h-10 px-4 bg-surface-dark hover:bg-border-dark text-white text-sm font-bold leading-normal tracking-[0.015em] transition-colors gap-2">
|
||||
<span class="material-symbols-outlined text-[20px]">logout</span>
|
||||
<span class="truncate">Logout</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Main Content -->
|
||||
<div class="flex flex-1 flex-col h-full overflow-hidden relative">
|
||||
<!-- Header Section -->
|
||||
<div class="flex-shrink-0 border-b border-border-dark bg-background-dark/95 backdrop-blur z-10">
|
||||
<div class="flex flex-col gap-4 p-6 pb-4">
|
||||
<div class="flex flex-wrap justify-between gap-3 items-center">
|
||||
<div class="flex flex-col gap-1">
|
||||
<h2 class="text-white text-3xl font-black leading-tight tracking-[-0.033em]">Shares Management</h2>
|
||||
<div class="flex items-center gap-2 text-text-secondary text-sm">
|
||||
<span>Storage</span>
|
||||
<span class="material-symbols-outlined text-[14px]">chevron_right</span>
|
||||
<span>Shares</span>
|
||||
<span class="material-symbols-outlined text-[14px]">chevron_right</span>
|
||||
<span class="text-white">Overview</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="flex cursor-pointer items-center justify-center overflow-hidden rounded-lg h-10 px-4 bg-primary hover:bg-blue-600 text-white text-sm font-bold leading-normal transition-colors gap-2">
|
||||
<span class="material-symbols-outlined">add</span>
|
||||
<span class="truncate">Create New Share</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Status Stats -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-2">
|
||||
<div class="flex flex-col gap-1 rounded-lg p-4 border border-border-dark bg-surface-dark/50">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-xs font-bold uppercase tracking-wider">SMB Service</p>
|
||||
<div class="size-2 rounded-full bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]"></div>
|
||||
</div>
|
||||
<p class="text-white text-xl font-bold leading-tight">Running</p>
|
||||
<p class="text-emerald-500 text-xs mt-1">Port 445 Active</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1 rounded-lg p-4 border border-border-dark bg-surface-dark/50">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-xs font-bold uppercase tracking-wider">NFS Service</p>
|
||||
<div class="size-2 rounded-full bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]"></div>
|
||||
</div>
|
||||
<p class="text-white text-xl font-bold leading-tight">Running</p>
|
||||
<p class="text-emerald-500 text-xs mt-1">Port 2049 Active</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1 rounded-lg p-4 border border-border-dark bg-surface-dark/50">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-xs font-bold uppercase tracking-wider">Throughput</p>
|
||||
<span class="material-symbols-outlined text-text-secondary">speed</span>
|
||||
</div>
|
||||
<p class="text-white text-xl font-bold leading-tight">565 MB/s</p>
|
||||
<p class="text-text-secondary text-xs mt-1">14 Clients Connected</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Master-Detail Layout -->
|
||||
<div class="flex flex-1 overflow-hidden">
|
||||
<!-- Left Panel: Shares List (Master) -->
|
||||
<div class="w-full lg:w-[400px] flex flex-col border-r border-border-dark bg-background-dark flex-shrink-0">
|
||||
<!-- Search -->
|
||||
<div class="p-4 border-b border-border-dark bg-background-dark sticky top-0 z-10">
|
||||
<div class="relative">
|
||||
<input class="w-full bg-surface-dark border border-border-dark rounded-lg pl-10 pr-4 py-2.5 text-sm text-white focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary placeholder-text-secondary" placeholder="Filter datasets..."/>
|
||||
<span class="material-symbols-outlined absolute left-3 top-2.5 text-text-secondary">search</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- List Items -->
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<!-- Tree Item 1 -->
|
||||
<div class="group flex flex-col border-b border-border-dark/50 cursor-pointer hover:bg-surface-dark transition-colors">
|
||||
<div class="px-4 py-3 flex items-start gap-3">
|
||||
<span class="material-symbols-outlined text-text-secondary mt-1">folder_open</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<h3 class="text-sm font-medium text-white truncate">pool/tank/home</h3>
|
||||
</div>
|
||||
<p class="text-xs text-text-secondary truncate mb-2">/mnt/tank/home</p>
|
||||
<div class="flex gap-2">
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-bold bg-emerald-500/10 text-emerald-500 border border-emerald-500/20">SMB</span>
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-bold bg-emerald-500/10 text-emerald-500 border border-emerald-500/20">NFS</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[18px]">chevron_right</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tree Item 2 (Selected) -->
|
||||
<div class="group flex flex-col border-b border-border-dark/50 cursor-pointer bg-primary/10 border-l-4 border-l-primary relative">
|
||||
<div class="px-4 py-3 flex items-start gap-3 pl-3">
|
||||
<span class="material-symbols-outlined text-primary mt-1">dns</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<h3 class="text-sm font-bold text-white truncate">pool/tank/vm_storage</h3>
|
||||
</div>
|
||||
<p class="text-xs text-primary/80 truncate mb-2">/mnt/tank/vm_storage</p>
|
||||
<div class="flex gap-2">
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-bold bg-surface-dark text-text-secondary border border-border-dark">SMB</span>
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-bold bg-emerald-500/10 text-emerald-500 border border-emerald-500/20">NFS</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tree Item 3 -->
|
||||
<div class="group flex flex-col border-b border-border-dark/50 cursor-pointer hover:bg-surface-dark transition-colors">
|
||||
<div class="px-4 py-3 flex items-start gap-3">
|
||||
<span class="material-symbols-outlined text-text-secondary mt-1">folder_open</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<h3 class="text-sm font-medium text-white truncate">pool/tank/backups</h3>
|
||||
</div>
|
||||
<p class="text-xs text-text-secondary truncate mb-2">/mnt/tank/backups</p>
|
||||
<div class="flex gap-2">
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-bold bg-emerald-500/10 text-emerald-500 border border-emerald-500/20">SMB</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[18px]">chevron_right</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tree Item 4 -->
|
||||
<div class="group flex flex-col border-b border-border-dark/50 cursor-pointer hover:bg-surface-dark transition-colors">
|
||||
<div class="px-4 py-3 flex items-start gap-3">
|
||||
<span class="material-symbols-outlined text-text-secondary mt-1">folder_open</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<h3 class="text-sm font-medium text-white truncate">pool/tank/media</h3>
|
||||
</div>
|
||||
<p class="text-xs text-text-secondary truncate mb-2">/mnt/tank/media</p>
|
||||
<div class="flex gap-2">
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-bold bg-emerald-500/10 text-emerald-500 border border-emerald-500/20">SMB</span>
|
||||
<span class="px-1.5 py-0.5 rounded text-[10px] font-bold bg-emerald-500/10 text-emerald-500 border border-emerald-500/20">NFS</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[18px]">chevron_right</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 border-t border-border-dark bg-background-dark text-center">
|
||||
<p class="text-xs text-text-secondary">Showing 4 of 12 datasets</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right Panel: Details (Detail) -->
|
||||
<div class="flex-1 flex flex-col h-full overflow-hidden bg-background-light dark:bg-[#0d141c]">
|
||||
<!-- Detail Header -->
|
||||
<div class="p-6 pb-0 flex flex-col gap-6">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<div class="bg-primary p-2 rounded-lg text-white">
|
||||
<span class="material-symbols-outlined block">dns</span>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold text-white">vm_storage</h2>
|
||||
<p class="text-text-secondary text-sm font-mono">pool/tank/vm_storage</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button class="flex items-center justify-center rounded-lg h-9 px-4 border border-border-dark text-white text-sm font-medium hover:bg-surface-dark transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px] mr-2">history</span>
|
||||
Revert
|
||||
</button>
|
||||
<button class="flex items-center justify-center rounded-lg h-9 px-4 bg-primary text-white text-sm font-bold shadow-lg shadow-primary/20 hover:bg-blue-600 transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px] mr-2">save</span>
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Toggles Panel -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<!-- SMB Toggle -->
|
||||
<div class="flex items-center justify-between p-4 rounded-xl border border-border-dark bg-surface-dark/40">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded-lg bg-surface-dark text-text-secondary">
|
||||
<span class="material-symbols-outlined">folder_shared</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-white">SMB Protocol</span>
|
||||
<span class="text-xs text-text-secondary">Windows File Sharing</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Switch OFF -->
|
||||
<div class="relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out bg-slate-700 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background-dark">
|
||||
<span class="sr-only">Use setting</span>
|
||||
<span class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out translate-x-0"></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- NFS Toggle -->
|
||||
<div class="flex items-center justify-between p-4 rounded-xl border border-primary/50 bg-primary/5">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded-lg bg-primary/20 text-primary">
|
||||
<span class="material-symbols-outlined">cloud_queue</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-white">NFS Protocol</span>
|
||||
<span class="text-xs text-text-secondary">Unix/Linux File Sharing</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Switch ON -->
|
||||
<div class="relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out bg-primary focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background-dark">
|
||||
<span class="sr-only">Use setting</span>
|
||||
<span class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out translate-x-5"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tabs -->
|
||||
<div class="border-b border-border-dark mt-2">
|
||||
<div class="flex gap-6">
|
||||
<button class="pb-3 border-b-2 border-primary text-primary text-sm font-bold flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-[18px]">tune</span>
|
||||
Configuration
|
||||
</button>
|
||||
<button class="pb-3 border-b-2 border-transparent text-text-secondary hover:text-white text-sm font-medium flex items-center gap-2 transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px]">lock</span>
|
||||
Permissions (ACL)
|
||||
</button>
|
||||
<button class="pb-3 border-b-2 border-transparent text-text-secondary hover:text-white text-sm font-medium flex items-center gap-2 transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px]">lan</span>
|
||||
Connected Clients
|
||||
<span class="bg-surface-dark text-white text-[10px] px-1.5 py-0.5 rounded-full ml-1">8</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tab Content: Configuration -->
|
||||
<div class="flex-1 overflow-y-auto p-6">
|
||||
<div class="max-w-4xl flex flex-col gap-6">
|
||||
<!-- NFS Settings Card -->
|
||||
<div class="rounded-xl border border-border-dark bg-surface-dark overflow-hidden">
|
||||
<div class="px-5 py-4 border-b border-border-dark flex justify-between items-center bg-[#1c2a39]">
|
||||
<h3 class="text-sm font-bold text-white flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-[20px]">settings_ethernet</span>
|
||||
NFS Configuration
|
||||
</h3>
|
||||
<span class="text-xs text-emerald-500 font-medium px-2 py-1 bg-emerald-500/10 rounded border border-emerald-500/20">Active</span>
|
||||
</div>
|
||||
<div class="p-5 flex flex-col gap-5">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-xs font-semibold text-text-secondary uppercase">Allowed Subnets / IPs</label>
|
||||
<div class="flex gap-2">
|
||||
<input class="flex-1 bg-background-dark border border-border-dark rounded-lg px-3 py-2 text-sm text-white focus:border-primary focus:ring-1 focus:ring-primary font-mono" type="text" value="192.168.10.0/24"/>
|
||||
<button class="p-2 bg-surface-dark hover:bg-border-dark border border-border-dark rounded-lg text-white">
|
||||
<span class="material-symbols-outlined">add</span>
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-xs text-text-secondary">CIDR notation supported. Use comma for multiple entries.</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-xs font-semibold text-text-secondary uppercase">Map Root User</label>
|
||||
<div class="relative">
|
||||
<select class="w-full bg-background-dark border border-border-dark rounded-lg px-3 py-2 text-sm text-white focus:border-primary focus:ring-1 focus:ring-primary appearance-none">
|
||||
<option>root (User ID 0)</option>
|
||||
<option>admin</option>
|
||||
<option>nobody</option>
|
||||
</select>
|
||||
<span class="material-symbols-outlined absolute right-3 top-2.5 text-text-secondary pointer-events-none">expand_more</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-xs font-semibold text-text-secondary uppercase">Security Profile</label>
|
||||
<div class="flex gap-2">
|
||||
<label class="flex items-center gap-2 px-3 py-2 rounded-lg border border-border-dark bg-background-dark cursor-pointer flex-1">
|
||||
<input checked="" class="text-primary focus:ring-primary bg-surface-dark border-border-dark" name="sec" type="radio"/>
|
||||
<span class="text-sm text-white">sys (Default)</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 px-3 py-2 rounded-lg border border-border-dark bg-background-dark cursor-pointer flex-1">
|
||||
<input class="text-primary focus:ring-primary bg-surface-dark border-border-dark" name="sec" type="radio"/>
|
||||
<span class="text-sm text-white">krb5</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-xs font-semibold text-text-secondary uppercase">Sync Mode</label>
|
||||
<div class="relative">
|
||||
<select class="w-full bg-background-dark border border-border-dark rounded-lg px-3 py-2 text-sm text-white focus:border-primary focus:ring-1 focus:ring-primary appearance-none">
|
||||
<option>Standard</option>
|
||||
<option>Always Sync</option>
|
||||
<option>Disabled (Async)</option>
|
||||
</select>
|
||||
<span class="material-symbols-outlined absolute right-3 top-2.5 text-text-secondary pointer-events-none">expand_more</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Advanced Attributes -->
|
||||
<div class="rounded-xl border border-border-dark bg-surface-dark overflow-hidden">
|
||||
<button class="w-full px-5 py-4 flex justify-between items-center hover:bg-[#1c2a39] transition-colors text-left">
|
||||
<h3 class="text-sm font-bold text-white flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-text-secondary text-[20px]">tune</span>
|
||||
Advanced Attributes
|
||||
</h3>
|
||||
<span class="material-symbols-outlined text-text-secondary">expand_more</span>
|
||||
</button>
|
||||
<!-- Collapsed content placeholder (imagine this expands) -->
|
||||
<div class="p-5 border-t border-border-dark flex flex-wrap gap-4">
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input class="rounded border-border-dark bg-background-dark text-primary focus:ring-primary h-4 w-4" type="checkbox"/>
|
||||
<span class="text-sm text-white">Read Only</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input checked="" class="rounded border-border-dark bg-background-dark text-primary focus:ring-primary h-4 w-4" type="checkbox"/>
|
||||
<span class="text-sm text-white">Enable Compression (LZ4)</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input class="rounded border-border-dark bg-background-dark text-primary focus:ring-primary h-4 w-4" type="checkbox"/>
|
||||
<span class="text-sm text-white">Enable Deduplication</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Connected Clients Preview -->
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex justify-between items-end">
|
||||
<h3 class="text-base font-bold text-white">Top Active Clients</h3>
|
||||
<a class="text-sm text-primary hover:text-blue-400 font-medium" href="#">View all clients</a>
|
||||
</div>
|
||||
<div class="rounded-lg border border-border-dark overflow-hidden bg-surface-dark">
|
||||
<table class="w-full text-sm text-left">
|
||||
<thead class="bg-background-dark text-text-secondary font-medium border-b border-border-dark">
|
||||
<tr>
|
||||
<th class="px-4 py-3">IP Address</th>
|
||||
<th class="px-4 py-3">User</th>
|
||||
<th class="px-4 py-3">Protocol</th>
|
||||
<th class="px-4 py-3 text-right">Throughput</th>
|
||||
<th class="px-4 py-3 text-right">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-white divide-y divide-border-dark">
|
||||
<tr>
|
||||
<td class="px-4 py-3 font-mono">192.168.10.105</td>
|
||||
<td class="px-4 py-3">esxi-host-01</td>
|
||||
<td class="px-4 py-3"><span class="bg-primary/20 text-primary px-1.5 py-0.5 rounded text-xs font-bold">NFS</span></td>
|
||||
<td class="px-4 py-3 text-right font-mono text-text-secondary">420 MB/s</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<button class="text-text-secondary hover:text-red-400" title="Disconnect">
|
||||
<span class="material-symbols-outlined text-[18px]">block</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-4 py-3 font-mono">192.168.10.106</td>
|
||||
<td class="px-4 py-3">esxi-host-02</td>
|
||||
<td class="px-4 py-3"><span class="bg-primary/20 text-primary px-1.5 py-0.5 rounded text-xs font-bold">NFS</span></td>
|
||||
<td class="px-4 py-3 text-right font-mono text-text-secondary">105 MB/s</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
<button class="text-text-secondary hover:text-red-400" title="Disconnect">
|
||||
<span class="material-symbols-outlined text-[18px]">block</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
BIN
src/web/shares-management.png
Normal file
|
After Width: | Height: | Size: 310 KiB |
454
src/web/snapshots-management-code.html
Normal file
@@ -0,0 +1,454 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Data Protection - Snapshot Manager</title>
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;700&display=swap" rel="stylesheet"/>
|
||||
<!-- Icons -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<!-- Theme Configuration -->
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#101922",
|
||||
"surface-dark": "#16202a",
|
||||
"border-dark": "#324d67",
|
||||
"text-secondary": "#92adc9"
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"]
|
||||
},
|
||||
borderRadius: {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Custom scrollbar for webkit browsers */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #111a22;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #4a6b8a;
|
||||
}
|
||||
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
.icon-filled {
|
||||
font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-white font-display overflow-hidden h-screen flex">
|
||||
<!-- Global Navigation Sidebar -->
|
||||
<aside class="w-64 bg-[#111a22] border-r border-border-dark flex flex-col h-full flex-shrink-0 z-20">
|
||||
<div class="flex items-center gap-3 p-4 border-b border-border-dark">
|
||||
<div class="bg-center bg-no-repeat bg-cover rounded-full h-10 w-10 shrink-0" data-alt="Abstract blue tech logo gradient" style='background-image: url("https://lh3.googleusercontent.com/aida-public/AB6AXuB3AJm6_-45EJVrywcu9Bfe2jgJC8qjm02SwZMeiJvN8_sR9UYfiwtNYebUlJFuP2X_D9_ppCQPe6xK-FAVaH4q8ObtjuWBNX73GsveMYbuBDyGctR1Fhu5jPiN_OcSBT4OAGPPDTBegjCgyZ2RTkV9GLzyiNeTZluUshePm7h1Rn4fdv1ZgXSWL7LAorhKLC6mrw6TdcdJfeNTBNzOs_8cvJHY_Vu-0Vi8xu_lWm2kjCjtSbGDRJRmxs1hzNOG5xQTNy2OfGm7luM");'></div>
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<h1 class="text-white text-base font-bold leading-normal truncate">Backup Appliance</h1>
|
||||
<p class="text-text-secondary text-xs font-normal leading-normal truncate">v24.04.1-SCALE</p>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="flex flex-col gap-2 p-3 overflow-y-auto flex-1">
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-white/5 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white">dashboard</span>
|
||||
<p class="text-text-secondary group-hover:text-white text-sm font-medium">Dashboard</p>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-white/5 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white">hard_drive</span>
|
||||
<p class="text-text-secondary group-hover:text-white text-sm font-medium">Storage</p>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-white/5 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white">network_check</span>
|
||||
<p class="text-text-secondary group-hover:text-white text-sm font-medium">Network</p>
|
||||
</a>
|
||||
<!-- Active State -->
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg bg-[#233648] text-white" href="#">
|
||||
<span class="material-symbols-outlined icon-filled text-primary">shield</span>
|
||||
<p class="text-white text-sm font-medium">Data Protection</p>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-white/5 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white">settings</span>
|
||||
<p class="text-text-secondary group-hover:text-white text-sm font-medium">System</p>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-white/5 transition-colors group mt-auto" href="#">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-white">logout</span>
|
||||
<p class="text-text-secondary group-hover:text-white text-sm font-medium">Logout</p>
|
||||
</a>
|
||||
</nav>
|
||||
</aside>
|
||||
<!-- Main Content Layout (Tree + Details) -->
|
||||
<div class="flex flex-1 h-full overflow-hidden">
|
||||
<!-- Dataset Tree View (Secondary Sidebar) -->
|
||||
<aside class="w-72 bg-surface-dark border-r border-border-dark flex flex-col h-full overflow-hidden hidden md:flex">
|
||||
<div class="p-4 border-b border-border-dark flex justify-between items-center">
|
||||
<h3 class="text-sm font-bold text-white uppercase tracking-wider">Datasets</h3>
|
||||
<button class="text-text-secondary hover:text-white">
|
||||
<span class="material-symbols-outlined text-lg">filter_list</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-1 overflow-y-auto p-2">
|
||||
<!-- Tree Item: Root -->
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex items-center gap-2 px-2 py-1.5 rounded bg-primary/20 text-white cursor-pointer">
|
||||
<span class="material-symbols-outlined text-sm text-text-secondary">expand_more</span>
|
||||
<span class="material-symbols-outlined text-primary text-lg">dns</span>
|
||||
<span class="text-sm font-medium truncate">tank</span>
|
||||
</div>
|
||||
<!-- Children -->
|
||||
<div class="pl-4 flex flex-col gap-1 border-l border-border-dark ml-3 my-1">
|
||||
<!-- Item 1 (Active) -->
|
||||
<div class="flex items-center gap-2 px-2 py-1.5 rounded bg-[#324d67] text-white cursor-pointer relative">
|
||||
<div class="absolute w-1 h-full left-0 bg-primary rounded-l"></div>
|
||||
<span class="material-symbols-outlined text-sm text-text-secondary">expand_more</span>
|
||||
<span class="material-symbols-outlined text-yellow-500 text-lg">folder</span>
|
||||
<span class="text-sm font-medium truncate">data</span>
|
||||
<!-- Usage bar mini -->
|
||||
<div class="ml-auto w-12 h-1 bg-black/40 rounded-full overflow-hidden">
|
||||
<div class="h-full bg-green-500 w-[65%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Nested Child -->
|
||||
<div class="pl-4 flex flex-col gap-1 border-l border-border-dark ml-3 my-1">
|
||||
<div class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-white/5 text-text-secondary hover:text-white cursor-pointer transition-colors">
|
||||
<span class="w-4"></span>
|
||||
<span class="material-symbols-outlined text-lg">folder</span>
|
||||
<span class="text-sm truncate">projects</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-white/5 text-text-secondary hover:text-white cursor-pointer transition-colors">
|
||||
<span class="w-4"></span>
|
||||
<span class="material-symbols-outlined text-lg">folder</span>
|
||||
<span class="text-sm truncate">archives</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Item 2 -->
|
||||
<div class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-white/5 text-text-secondary hover:text-white cursor-pointer transition-colors">
|
||||
<span class="material-symbols-outlined text-sm text-text-secondary">chevron_right</span>
|
||||
<span class="material-symbols-outlined text-blue-400 text-lg">featured_play_list</span>
|
||||
<span class="text-sm font-medium truncate">vms-storage</span>
|
||||
</div>
|
||||
<!-- Item 3 -->
|
||||
<div class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-white/5 text-text-secondary hover:text-white cursor-pointer transition-colors">
|
||||
<span class="material-symbols-outlined text-sm text-text-secondary">chevron_right</span>
|
||||
<span class="material-symbols-outlined text-purple-400 text-lg">storage</span>
|
||||
<span class="text-sm font-medium truncate">iscsi-target-01</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Bottom Action in Sidebar -->
|
||||
<div class="p-3 border-t border-border-dark">
|
||||
<button class="w-full py-2 px-3 rounded border border-border-dark text-sm text-text-secondary hover:text-white hover:bg-white/5 flex items-center justify-center gap-2 transition-colors">
|
||||
<span class="material-symbols-outlined text-lg">add</span>
|
||||
Add Dataset
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- Main Action Area -->
|
||||
<main class="flex-1 flex flex-col h-full bg-background-dark overflow-y-auto relative">
|
||||
<!-- Breadcrumbs -->
|
||||
<div class="px-8 pt-6 pb-2">
|
||||
<div class="flex flex-wrap gap-2 items-center">
|
||||
<a class="text-text-secondary text-sm font-medium hover:text-primary transition-colors flex items-center gap-1" href="#">
|
||||
<span class="material-symbols-outlined text-lg">hard_drive</span> Storage
|
||||
</a>
|
||||
<span class="text-text-secondary text-sm">/</span>
|
||||
<a class="text-text-secondary text-sm font-medium hover:text-primary transition-colors" href="#">ZFS Pools</a>
|
||||
<span class="text-text-secondary text-sm">/</span>
|
||||
<span class="text-white text-sm font-medium px-2 py-0.5 rounded bg-surface-dark border border-border-dark">tank/data</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Page Header -->
|
||||
<div class="px-8 py-4 flex flex-wrap justify-between gap-6 items-end">
|
||||
<div class="flex flex-col gap-2 max-w-2xl">
|
||||
<h1 class="text-white tracking-tight text-3xl font-bold">Snapshot Manager</h1>
|
||||
<p class="text-text-secondary text-sm leading-relaxed">Manage automated snapshots, retention policies, and replication tasks for the <span class="text-white font-mono bg-surface-dark px-1 rounded">tank/data</span> dataset.</p>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<button class="flex items-center gap-2 px-4 py-2 bg-surface-dark border border-border-dark rounded-lg text-white text-sm font-medium hover:bg-[#1c2a35] transition-colors">
|
||||
<span class="material-symbols-outlined text-lg">settings</span>
|
||||
Settings
|
||||
</button>
|
||||
<button class="flex items-center gap-2 px-4 py-2 bg-primary text-white rounded-lg text-sm font-medium hover:bg-blue-600 transition-colors shadow-lg shadow-blue-900/20">
|
||||
<span class="material-symbols-outlined text-lg">add_a_photo</span>
|
||||
Create Snapshot
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stats Cards -->
|
||||
<div class="px-8 pb-6">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<!-- Stat 1 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark/50 hover:bg-surface-dark transition-colors">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-xs font-bold uppercase tracking-wider">Total Snapshots</p>
|
||||
<span class="material-symbols-outlined text-primary text-xl">photo_library</span>
|
||||
</div>
|
||||
<p class="text-white text-2xl font-bold mt-1">1,245</p>
|
||||
<div class="flex items-center gap-1 mt-1 text-green-400 text-xs">
|
||||
<span class="material-symbols-outlined text-sm">trending_up</span>
|
||||
<span>+12 today</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stat 2 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark/50 hover:bg-surface-dark transition-colors">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-xs font-bold uppercase tracking-wider">Space Used</p>
|
||||
<span class="material-symbols-outlined text-yellow-500 text-xl">pie_chart</span>
|
||||
</div>
|
||||
<p class="text-white text-2xl font-bold mt-1">2.4 TB</p>
|
||||
<div class="w-full bg-[#111a22] rounded-full h-1.5 mt-2">
|
||||
<div class="bg-yellow-500 h-1.5 rounded-full" style="width: 45%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stat 3 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark/50 hover:bg-surface-dark transition-colors">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-xs font-bold uppercase tracking-wider">Reclaimable</p>
|
||||
<span class="material-symbols-outlined text-green-400 text-xl">recycling</span>
|
||||
</div>
|
||||
<p class="text-white text-2xl font-bold mt-1">420 GB</p>
|
||||
<p class="text-text-secondary text-xs mt-1">from expired policies</p>
|
||||
</div>
|
||||
<!-- Stat 4 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark/50 hover:bg-surface-dark transition-colors">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-xs font-bold uppercase tracking-wider">Next Scheduled</p>
|
||||
<span class="material-symbols-outlined text-purple-400 text-xl">schedule</span>
|
||||
</div>
|
||||
<p class="text-white text-2xl font-bold mt-1">14:00</p>
|
||||
<p class="text-text-secondary text-xs mt-1">Today (Auto-Daily)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tabs -->
|
||||
<div class="px-8 border-b border-border-dark flex gap-8">
|
||||
<button class="pb-3 text-sm font-medium text-primary border-b-2 border-primary">Snapshots List</button>
|
||||
<button class="pb-3 text-sm font-medium text-text-secondary hover:text-white transition-colors">Schedule & Policies</button>
|
||||
<button class="pb-3 text-sm font-medium text-text-secondary hover:text-white transition-colors">Replication Tasks</button>
|
||||
</div>
|
||||
<!-- Toolbar & Filters -->
|
||||
<div class="px-8 py-4 flex flex-wrap gap-4 items-center justify-between bg-surface-dark/30">
|
||||
<div class="relative flex-1 min-w-[200px] max-w-md">
|
||||
<span class="absolute left-3 top-1/2 -translate-y-1/2 material-symbols-outlined text-text-secondary">search</span>
|
||||
<input class="w-full bg-[#111a22] border border-border-dark text-white text-sm rounded-lg pl-10 pr-4 py-2 focus:ring-1 focus:ring-primary focus:border-primary outline-none transition-all placeholder:text-text-secondary/50" placeholder="Filter snapshots..." type="text"/>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button class="px-3 py-2 text-sm text-text-secondary hover:text-white border border-border-dark rounded bg-[#111a22] hover:bg-[#1c2a35] flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-lg">filter_alt</span> Filter
|
||||
</button>
|
||||
<button class="px-3 py-2 text-sm text-text-secondary hover:text-white border border-border-dark rounded bg-[#111a22] hover:bg-[#1c2a35] flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-lg">calendar_month</span> Date Range
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Data Table -->
|
||||
<div class="flex-1 px-8 pb-8 overflow-hidden flex flex-col">
|
||||
<div class="flex-1 overflow-auto rounded-lg border border-border-dark bg-[#111a22]">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead class="sticky top-0 z-10 bg-surface-dark text-xs font-semibold text-text-secondary uppercase tracking-wider">
|
||||
<tr>
|
||||
<th class="p-4 border-b border-border-dark w-10">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-0 focus:ring-offset-0" type="checkbox"/>
|
||||
</th>
|
||||
<th class="p-4 border-b border-border-dark">Snapshot Name</th>
|
||||
<th class="p-4 border-b border-border-dark">Created</th>
|
||||
<th class="p-4 border-b border-border-dark text-right">Used</th>
|
||||
<th class="p-4 border-b border-border-dark text-right">Referenced</th>
|
||||
<th class="p-4 border-b border-border-dark">Policy</th>
|
||||
<th class="p-4 border-b border-border-dark text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-sm divide-y divide-border-dark">
|
||||
<!-- Row 1 -->
|
||||
<tr class="hover:bg-white/5 transition-colors group">
|
||||
<td class="p-4">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-0 focus:ring-offset-0 opacity-50 group-hover:opacity-100" type="checkbox"/>
|
||||
</td>
|
||||
<td class="p-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-text-secondary">camera_alt</span>
|
||||
<span class="font-medium text-white font-mono">auto-2023-10-27-1400</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-4 text-text-secondary">Oct 27, 2023 14:00</td>
|
||||
<td class="p-4 text-right text-white font-mono">1.2 GB</td>
|
||||
<td class="p-4 text-right text-text-secondary font-mono">14.5 TB</td>
|
||||
<td class="p-4">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-500/10 text-blue-400 border border-blue-500/20">
|
||||
Hourly-Keep-24
|
||||
</span>
|
||||
</td>
|
||||
<td class="p-4 text-right">
|
||||
<button class="text-text-secondary hover:text-white p-1 rounded hover:bg-white/10">
|
||||
<span class="material-symbols-outlined text-lg">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 2 -->
|
||||
<tr class="hover:bg-white/5 transition-colors group">
|
||||
<td class="p-4">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-0 focus:ring-offset-0 opacity-50 group-hover:opacity-100" type="checkbox"/>
|
||||
</td>
|
||||
<td class="p-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-text-secondary">camera_alt</span>
|
||||
<span class="font-medium text-white font-mono">auto-2023-10-27-1300</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-4 text-text-secondary">Oct 27, 2023 13:00</td>
|
||||
<td class="p-4 text-right text-white font-mono">850 MB</td>
|
||||
<td class="p-4 text-right text-text-secondary font-mono">14.5 TB</td>
|
||||
<td class="p-4">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-500/10 text-blue-400 border border-blue-500/20">
|
||||
Hourly-Keep-24
|
||||
</span>
|
||||
</td>
|
||||
<td class="p-4 text-right">
|
||||
<button class="text-text-secondary hover:text-white p-1 rounded hover:bg-white/10">
|
||||
<span class="material-symbols-outlined text-lg">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 3: Manual Snapshot -->
|
||||
<tr class="hover:bg-white/5 transition-colors group">
|
||||
<td class="p-4">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-0 focus:ring-offset-0 opacity-50 group-hover:opacity-100" type="checkbox"/>
|
||||
</td>
|
||||
<td class="p-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-primary">person</span>
|
||||
<span class="font-medium text-white font-mono">pre-upgrade-backup</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-4 text-text-secondary">Oct 27, 2023 12:45</td>
|
||||
<td class="p-4 text-right text-white font-mono">4.1 GB</td>
|
||||
<td class="p-4 text-right text-text-secondary font-mono">14.5 TB</td>
|
||||
<td class="p-4">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-500/10 text-purple-400 border border-purple-500/20">
|
||||
Manual
|
||||
</span>
|
||||
</td>
|
||||
<td class="p-4 text-right">
|
||||
<div class="flex justify-end gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<button class="text-text-secondary hover:text-white p-1 rounded hover:bg-white/10" title="Clone">
|
||||
<span class="material-symbols-outlined text-lg">content_copy</span>
|
||||
</button>
|
||||
<button class="text-text-secondary hover:text-red-400 p-1 rounded hover:bg-red-400/10" title="Rollback">
|
||||
<span class="material-symbols-outlined text-lg">history</span>
|
||||
</button>
|
||||
<button class="text-text-secondary hover:text-white p-1 rounded hover:bg-white/10">
|
||||
<span class="material-symbols-outlined text-lg">more_vert</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 4 -->
|
||||
<tr class="hover:bg-white/5 transition-colors group">
|
||||
<td class="p-4">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-0 focus:ring-offset-0 opacity-50 group-hover:opacity-100" type="checkbox"/>
|
||||
</td>
|
||||
<td class="p-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-text-secondary">camera_alt</span>
|
||||
<span class="font-medium text-white font-mono">auto-2023-10-27-1200</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-4 text-text-secondary">Oct 27, 2023 12:00</td>
|
||||
<td class="p-4 text-right text-white font-mono">920 MB</td>
|
||||
<td class="p-4 text-right text-text-secondary font-mono">14.5 TB</td>
|
||||
<td class="p-4">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-500/10 text-blue-400 border border-blue-500/20">
|
||||
Hourly-Keep-24
|
||||
</span>
|
||||
</td>
|
||||
<td class="p-4 text-right">
|
||||
<button class="text-text-secondary hover:text-white p-1 rounded hover:bg-white/10">
|
||||
<span class="material-symbols-outlined text-lg">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 5: Locked -->
|
||||
<tr class="hover:bg-white/5 transition-colors group">
|
||||
<td class="p-4">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-text-secondary cursor-not-allowed opacity-50" disabled="" type="checkbox"/>
|
||||
</td>
|
||||
<td class="p-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-yellow-500">lock</span>
|
||||
<span class="font-medium text-white font-mono">daily-2023-10-26</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="p-4 text-text-secondary">Oct 26, 2023 00:00</td>
|
||||
<td class="p-4 text-right text-white font-mono">12.5 GB</td>
|
||||
<td class="p-4 text-right text-text-secondary font-mono">14.4 TB</td>
|
||||
<td class="p-4">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-500/10 text-green-400 border border-green-500/20">
|
||||
Daily-Keep-30
|
||||
</span>
|
||||
</td>
|
||||
<td class="p-4 text-right">
|
||||
<button class="text-text-secondary hover:text-white p-1 rounded hover:bg-white/10">
|
||||
<span class="material-symbols-outlined text-lg">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Pagination -->
|
||||
<div class="flex justify-between items-center py-4 border-t border-border-dark mt-2">
|
||||
<p class="text-xs text-text-secondary">Showing <span class="text-white font-medium">1-5</span> of <span class="text-white font-medium">1,245</span> snapshots</p>
|
||||
<div class="flex gap-2">
|
||||
<button class="px-3 py-1 text-xs font-medium text-text-secondary hover:text-white border border-border-dark rounded bg-surface-dark hover:bg-[#1c2a35] disabled:opacity-50">Previous</button>
|
||||
<button class="px-3 py-1 text-xs font-medium text-text-secondary hover:text-white border border-border-dark rounded bg-surface-dark hover:bg-[#1c2a35]">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Floating Feedback/Status Toast (Bottom Right) -->
|
||||
<div class="absolute bottom-6 right-8 max-w-sm w-full animate-pulse">
|
||||
<div class="bg-surface-dark border border-border-dark rounded-lg shadow-2xl p-4 flex items-start gap-3">
|
||||
<div class="p-1 rounded-full bg-blue-500/20 text-blue-400 shrink-0">
|
||||
<span class="material-symbols-outlined text-xl">sync</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="text-sm font-medium text-white">Replication in progress</p>
|
||||
<p class="text-xs text-text-secondary">Sending 'auto-2023-10-27-1400' to backup-server (45%)</p>
|
||||
<div class="w-full bg-[#111a22] h-1 rounded-full mt-1">
|
||||
<div class="bg-blue-500 h-1 rounded-full w-[45%]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="text-text-secondary hover:text-white ml-auto">
|
||||
<span class="material-symbols-outlined text-sm">close</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body></html>
|
||||
BIN
src/web/snapshots-management.png
Normal file
|
After Width: | Height: | Size: 312 KiB |
569
src/web/storage-management-code.html
Normal file
@@ -0,0 +1,569 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Storage Management - Cockpit</title>
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Icons -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<!-- Theme Configuration -->
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#101922",
|
||||
"surface-dark": "#1a242f",
|
||||
"surface-darker": "#111a22",
|
||||
"border-dark": "#324d67",
|
||||
"text-secondary": "#92adc9",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"]
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.375rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark font-display text-slate-900 dark:text-white antialiased overflow-hidden">
|
||||
<div class="flex h-screen w-full overflow-hidden">
|
||||
<!-- Sidebar -->
|
||||
<aside class="w-64 flex-shrink-0 border-r border-slate-200 dark:border-border-dark bg-white dark:bg-surface-darker flex flex-col justify-between p-4 z-20">
|
||||
<div class="flex flex-col gap-6">
|
||||
<!-- Brand -->
|
||||
<div class="flex flex-col px-2">
|
||||
<h1 class="text-slate-900 dark:text-white text-lg font-bold tracking-tight">Backup Appliance</h1>
|
||||
<p class="text-text-secondary text-xs font-medium">Cockpit Admin v2.4</p>
|
||||
</div>
|
||||
<!-- Navigation -->
|
||||
<nav class="flex flex-col gap-1">
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">speed</span>
|
||||
<span class="text-sm font-medium">Dashboard</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg bg-primary/10 text-primary dark:text-white dark:bg-[#233648]" href="#">
|
||||
<span class="material-symbols-outlined text-primary dark:text-white fill-1">hard_drive</span>
|
||||
<span class="text-sm font-bold">Storage</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">network_check</span>
|
||||
<span class="text-sm font-medium">Networking</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">group</span>
|
||||
<span class="text-sm font-medium">Accounts</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">menu_book</span>
|
||||
<span class="text-sm font-medium">Logs</span>
|
||||
</a>
|
||||
<div class="my-2 border-t border-slate-200 dark:border-border-dark"></div>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">terminal</span>
|
||||
<span class="text-sm font-medium">Terminal</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- User -->
|
||||
<div class="px-2 py-2 flex items-center gap-3 border-t border-slate-200 dark:border-border-dark pt-4">
|
||||
<div class="h-8 w-8 rounded-full bg-primary flex items-center justify-center text-white font-bold text-xs">AD</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold dark:text-white">Admin User</span>
|
||||
<span class="text-xs text-text-secondary">System Administrator</span>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- Main Content Area -->
|
||||
<main class="flex-1 flex flex-col h-full overflow-hidden relative bg-background-light dark:bg-background-dark">
|
||||
<!-- Header & Breadcrumbs -->
|
||||
<header class="flex-shrink-0 px-8 py-6 border-b border-slate-200 dark:border-border-dark bg-white/50 dark:bg-surface-darker/50 backdrop-blur-sm z-10">
|
||||
<div class="max-w-[1400px] mx-auto w-full flex flex-col gap-4">
|
||||
<!-- Breadcrumbs -->
|
||||
<nav class="flex items-center text-sm font-medium text-text-secondary">
|
||||
<a class="hover:text-primary transition-colors" href="#">Home</a>
|
||||
<span class="mx-2">/</span>
|
||||
<span class="text-slate-900 dark:text-white">Storage Management</span>
|
||||
</nav>
|
||||
<div class="flex flex-wrap items-end justify-between gap-4">
|
||||
<div class="flex flex-col gap-1">
|
||||
<h1 class="text-3xl font-extrabold text-slate-900 dark:text-white tracking-tight">Storage Pools</h1>
|
||||
<p class="text-text-secondary">Manage ZFS pools, datasets, and physical disks topology.</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<button class="flex items-center gap-2 px-4 py-2 rounded-lg border border-slate-300 dark:border-border-dark bg-white dark:bg-surface-dark text-slate-700 dark:text-white text-sm font-bold hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">refresh</span>
|
||||
Rescan Disks
|
||||
</button>
|
||||
<button class="flex items-center gap-2 px-4 py-2 rounded-lg bg-primary text-white text-sm font-bold hover:bg-primary/90 transition-colors shadow-lg shadow-primary/20">
|
||||
<span class="material-symbols-outlined text-[20px]">add_circle</span>
|
||||
Create Pool
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Scrollable Content -->
|
||||
<div class="flex-1 overflow-y-auto p-8">
|
||||
<div class="max-w-[1400px] mx-auto w-full flex flex-col gap-8 pb-10">
|
||||
<!-- Stats Overview -->
|
||||
<section class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<!-- Total Capacity -->
|
||||
<div class="bg-white dark:bg-surface-dark p-5 rounded-xl border border-slate-200 dark:border-border-dark shadow-sm">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<p class="text-text-secondary text-sm font-semibold uppercase tracking-wider">Total Capacity</p>
|
||||
<span class="material-symbols-outlined text-text-secondary">database</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-2">
|
||||
<h3 class="text-2xl font-bold dark:text-white">120.5 TB</h3>
|
||||
<span class="text-xs text-text-secondary">Raw</span>
|
||||
</div>
|
||||
<div class="mt-3 w-full bg-slate-100 dark:bg-slate-800 rounded-full h-1.5 overflow-hidden">
|
||||
<div class="bg-primary h-1.5 rounded-full" style="width: 38%"></div>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-text-secondary">38% Used (45 TB)</p>
|
||||
</div>
|
||||
<!-- Health Status -->
|
||||
<div class="bg-white dark:bg-surface-dark p-5 rounded-xl border border-slate-200 dark:border-border-dark shadow-sm">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<p class="text-text-secondary text-sm font-semibold uppercase tracking-wider">Health Status</p>
|
||||
<span class="material-symbols-outlined text-emerald-500">check_circle</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-2">
|
||||
<h3 class="text-2xl font-bold dark:text-white text-emerald-500">Optimal</h3>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-text-secondary">All pools are online</p>
|
||||
<p class="text-xs text-emerald-500 mt-1 font-medium">Last scrub: 2 hours ago</p>
|
||||
</div>
|
||||
<!-- Efficiency -->
|
||||
<div class="bg-white dark:bg-surface-dark p-5 rounded-xl border border-slate-200 dark:border-border-dark shadow-sm">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<p class="text-text-secondary text-sm font-semibold uppercase tracking-wider">Efficiency</p>
|
||||
<span class="material-symbols-outlined text-text-secondary">compress</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-2">
|
||||
<h3 class="text-2xl font-bold dark:text-white">1.45x</h3>
|
||||
<span class="text-xs text-text-secondary">Ratio</span>
|
||||
</div>
|
||||
<div class="flex gap-2 mt-3">
|
||||
<span class="px-2 py-0.5 rounded bg-blue-500/10 text-blue-500 text-[10px] font-bold">LZ4</span>
|
||||
<span class="px-2 py-0.5 rounded bg-purple-500/10 text-purple-500 text-[10px] font-bold">DEDUP ON</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Performance -->
|
||||
<div class="bg-white dark:bg-surface-dark p-5 rounded-xl border border-slate-200 dark:border-border-dark shadow-sm">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<p class="text-text-secondary text-sm font-semibold uppercase tracking-wider">ARC Hit Ratio</p>
|
||||
<span class="material-symbols-outlined text-text-secondary">memory</span>
|
||||
</div>
|
||||
<div class="flex items-baseline gap-2">
|
||||
<h3 class="text-2xl font-bold dark:text-white">98.2%</h3>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-text-secondary">Cache Usage: 58GB / 64GB</p>
|
||||
<div class="mt-2 flex gap-1">
|
||||
<div class="h-1 flex-1 bg-emerald-500 rounded-full"></div>
|
||||
<div class="h-1 flex-1 bg-emerald-500 rounded-full"></div>
|
||||
<div class="h-1 flex-1 bg-emerald-500 rounded-full"></div>
|
||||
<div class="h-1 flex-1 bg-emerald-500/30 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Active Pools Table -->
|
||||
<section class="flex flex-col gap-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-bold text-slate-900 dark:text-white">Active Pools</h2>
|
||||
<div class="flex gap-2">
|
||||
<div class="relative">
|
||||
<span class="material-symbols-outlined absolute left-2.5 top-1/2 -translate-y-1/2 text-text-secondary text-[20px]">search</span>
|
||||
<input class="pl-10 pr-4 py-1.5 bg-white dark:bg-surface-dark border border-slate-300 dark:border-border-dark rounded-lg text-sm text-slate-900 dark:text-white focus:ring-2 focus:ring-primary focus:border-transparent outline-none w-64 placeholder-text-secondary" placeholder="Search datasets..." type="text"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-surface-dark rounded-xl border border-slate-200 dark:border-border-dark overflow-hidden shadow-sm">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="bg-slate-50 dark:bg-[#1e2832] border-b border-slate-200 dark:border-border-dark">
|
||||
<th class="py-3 px-5 text-xs font-semibold uppercase tracking-wider text-text-secondary w-10"></th>
|
||||
<th class="py-3 px-5 text-xs font-semibold uppercase tracking-wider text-text-secondary">Name</th>
|
||||
<th class="py-3 px-5 text-xs font-semibold uppercase tracking-wider text-text-secondary">Status</th>
|
||||
<th class="py-3 px-5 text-xs font-semibold uppercase tracking-wider text-text-secondary">Used / Avail</th>
|
||||
<th class="py-3 px-5 text-xs font-semibold uppercase tracking-wider text-text-secondary">Topology</th>
|
||||
<th class="py-3 px-5 text-xs font-semibold uppercase tracking-wider text-text-secondary">Compression</th>
|
||||
<th class="py-3 px-5 text-xs font-semibold uppercase tracking-wider text-text-secondary text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-200 dark:divide-border-dark text-sm">
|
||||
<!-- Row 1: Parent Pool -->
|
||||
<tr class="group hover:bg-slate-50 dark:hover:bg-white/5 transition-colors cursor-pointer">
|
||||
<td class="py-4 px-5 text-text-secondary">
|
||||
<span class="material-symbols-outlined text-[20px] transition-transform rotate-90">arrow_right</span>
|
||||
</td>
|
||||
<td class="py-4 px-5">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-primary">dns</span>
|
||||
<div>
|
||||
<span class="font-bold text-slate-900 dark:text-white block">tank0</span>
|
||||
<span class="text-xs text-text-secondary">/mnt/tank0</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-5">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-bold bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500"></span>
|
||||
ONLINE
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-5">
|
||||
<div class="flex flex-col gap-1 w-32">
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-slate-900 dark:text-white font-medium">18.5 TB</span>
|
||||
<span class="text-text-secondary">42 TB</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-200 dark:bg-slate-700 rounded-full h-1.5">
|
||||
<div class="bg-primary h-1.5 rounded-full" style="width: 44%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-5 text-text-secondary">RAIDZ2 (6 disks)</td>
|
||||
<td class="py-4 px-5 text-text-secondary">LZ4</td>
|
||||
<td class="py-4 px-5 text-right">
|
||||
<button class="p-1.5 rounded-md hover:bg-slate-200 dark:hover:bg-slate-700 text-text-secondary transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Child Dataset 1 -->
|
||||
<tr class="bg-slate-50/50 dark:bg-[#151d26] hover:bg-slate-100 dark:hover:bg-[#1a242f] transition-colors">
|
||||
<td class="py-3 px-5"></td>
|
||||
<td class="py-3 px-5 pl-10">
|
||||
<div class="flex items-center gap-3 relative before:content-[''] before:absolute before:-left-4 before:top-1/2 before:-translate-y-1/2 before:w-3 before:h-px before:bg-border-dark before:opacity-50">
|
||||
<span class="material-symbols-outlined text-text-secondary text-[18px]">folder</span>
|
||||
<span class="font-medium text-slate-700 dark:text-slate-200">projects_vol</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3 px-5 text-text-secondary text-xs">Mounted</td>
|
||||
<td class="py-3 px-5">
|
||||
<div class="flex flex-col gap-1 w-32">
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-slate-700 dark:text-slate-300 font-medium">12 TB</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3 px-5 text-text-secondary text-xs">—</td>
|
||||
<td class="py-3 px-5 text-text-secondary text-xs">ZSTD-3</td>
|
||||
<td class="py-3 px-5 text-right">
|
||||
<button class="p-1 rounded-md hover:bg-slate-200 dark:hover:bg-slate-700 text-text-secondary transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px]">settings</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Child Dataset 2 -->
|
||||
<tr class="bg-slate-50/50 dark:bg-[#151d26] hover:bg-slate-100 dark:hover:bg-[#1a242f] transition-colors border-b border-slate-200 dark:border-border-dark/50">
|
||||
<td class="py-3 px-5"></td>
|
||||
<td class="py-3 px-5 pl-10">
|
||||
<div class="flex items-center gap-3 relative before:content-[''] before:absolute before:-left-4 before:top-1/2 before:-translate-y-1/2 before:w-3 before:h-px before:bg-border-dark before:opacity-50">
|
||||
<span class="material-symbols-outlined text-text-secondary text-[18px]">folder_shared</span>
|
||||
<span class="font-medium text-slate-700 dark:text-slate-200">backups_smb</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3 px-5 text-text-secondary text-xs">Shared (SMB)</td>
|
||||
<td class="py-3 px-5">
|
||||
<div class="flex flex-col gap-1 w-32">
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-slate-700 dark:text-slate-300 font-medium">6.5 TB</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3 px-5 text-text-secondary text-xs">—</td>
|
||||
<td class="py-3 px-5 text-text-secondary text-xs">GZIP-9</td>
|
||||
<td class="py-3 px-5 text-right">
|
||||
<button class="p-1 rounded-md hover:bg-slate-200 dark:hover:bg-slate-700 text-text-secondary transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px]">settings</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 2: Secondary Pool -->
|
||||
<tr class="group hover:bg-slate-50 dark:hover:bg-white/5 transition-colors cursor-pointer">
|
||||
<td class="py-4 px-5 text-text-secondary">
|
||||
<span class="material-symbols-outlined text-[20px] transition-transform">arrow_right</span>
|
||||
</td>
|
||||
<td class="py-4 px-5">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-orange-500">warning</span>
|
||||
<div>
|
||||
<span class="font-bold text-slate-900 dark:text-white block">archive_legacy</span>
|
||||
<span class="text-xs text-text-secondary">/mnt/archive</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-5">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-bold bg-orange-500/10 text-orange-600 dark:text-orange-400 border border-orange-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-orange-500 animate-pulse"></span>
|
||||
DEGRADED
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-5">
|
||||
<div class="flex flex-col gap-1 w-32">
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-slate-900 dark:text-white font-medium">8.2 TB</span>
|
||||
<span class="text-text-secondary">10 TB</span>
|
||||
</div>
|
||||
<div class="w-full bg-slate-200 dark:bg-slate-700 rounded-full h-1.5">
|
||||
<div class="bg-orange-500 h-1.5 rounded-full" style="width: 82%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-5 text-text-secondary">MIRROR (2 disks)</td>
|
||||
<td class="py-4 px-5 text-text-secondary">LZ4</td>
|
||||
<td class="py-4 px-5 text-right">
|
||||
<button class="p-1.5 rounded-md hover:bg-slate-200 dark:hover:bg-slate-700 text-text-secondary transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Table Footer -->
|
||||
<div class="bg-slate-50 dark:bg-[#1e2832] px-5 py-3 border-t border-slate-200 dark:border-border-dark flex justify-between items-center text-xs text-text-secondary">
|
||||
<span>Showing 2 active pools</span>
|
||||
<a class="hover:text-primary font-medium" href="#">View Archived Pools</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Physical Disks Grid -->
|
||||
<section class="flex flex-col gap-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-bold text-slate-900 dark:text-white">Physical Disks</h2>
|
||||
<button class="text-primary text-sm font-bold hover:underline">View All Disks</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-6 gap-4">
|
||||
<!-- Disk 1 -->
|
||||
<div class="bg-white dark:bg-surface-dark rounded-lg p-4 border border-slate-200 dark:border-border-dark flex flex-col gap-3 hover:border-primary/50 transition-colors group cursor-pointer relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 p-2">
|
||||
<div class="w-2 h-2 rounded-full bg-emerald-500"></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded bg-slate-100 dark:bg-slate-800 flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-primary transition-colors">hard_drive</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-slate-900 dark:text-white">sda</span>
|
||||
<span class="text-xs text-text-secondary">Slot 1</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between text-xs text-text-secondary">
|
||||
<span>HGST-7200</span>
|
||||
<span>4 TB</span>
|
||||
</div>
|
||||
<div class="flex gap-0.5 h-1.5 w-full rounded-full overflow-hidden bg-slate-200 dark:bg-slate-700">
|
||||
<div class="bg-primary w-2/3"></div>
|
||||
<div class="bg-transparent w-1/3"></div>
|
||||
</div>
|
||||
<span class="text-[10px] text-text-secondary mt-1">Pool: tank0</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Disk 2 -->
|
||||
<div class="bg-white dark:bg-surface-dark rounded-lg p-4 border border-slate-200 dark:border-border-dark flex flex-col gap-3 hover:border-primary/50 transition-colors group cursor-pointer relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 p-2">
|
||||
<div class="w-2 h-2 rounded-full bg-emerald-500"></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded bg-slate-100 dark:bg-slate-800 flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-primary transition-colors">hard_drive</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-slate-900 dark:text-white">sdb</span>
|
||||
<span class="text-xs text-text-secondary">Slot 2</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between text-xs text-text-secondary">
|
||||
<span>HGST-7200</span>
|
||||
<span>4 TB</span>
|
||||
</div>
|
||||
<div class="flex gap-0.5 h-1.5 w-full rounded-full overflow-hidden bg-slate-200 dark:bg-slate-700">
|
||||
<div class="bg-primary w-2/3"></div>
|
||||
<div class="bg-transparent w-1/3"></div>
|
||||
</div>
|
||||
<span class="text-[10px] text-text-secondary mt-1">Pool: tank0</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Disk 3 -->
|
||||
<div class="bg-white dark:bg-surface-dark rounded-lg p-4 border border-slate-200 dark:border-border-dark flex flex-col gap-3 hover:border-primary/50 transition-colors group cursor-pointer relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 p-2">
|
||||
<div class="w-2 h-2 rounded-full bg-emerald-500"></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded bg-slate-100 dark:bg-slate-800 flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-primary transition-colors">hard_drive</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-slate-900 dark:text-white">sdc</span>
|
||||
<span class="text-xs text-text-secondary">Slot 3</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between text-xs text-text-secondary">
|
||||
<span>HGST-7200</span>
|
||||
<span>4 TB</span>
|
||||
</div>
|
||||
<div class="flex gap-0.5 h-1.5 w-full rounded-full overflow-hidden bg-slate-200 dark:bg-slate-700">
|
||||
<div class="bg-primary w-2/3"></div>
|
||||
<div class="bg-transparent w-1/3"></div>
|
||||
</div>
|
||||
<span class="text-[10px] text-text-secondary mt-1">Pool: tank0</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Disk 4 (Faulted) -->
|
||||
<div class="bg-red-50 dark:bg-red-900/10 rounded-lg p-4 border border-red-200 dark:border-red-900/30 flex flex-col gap-3 hover:border-red-500 transition-colors group cursor-pointer relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 p-2">
|
||||
<div class="w-2 h-2 rounded-full bg-red-500 animate-pulse"></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded bg-red-100 dark:bg-red-900/20 flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-red-500 group-hover:text-red-400 transition-colors">error</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-slate-900 dark:text-white">sdd</span>
|
||||
<span class="text-xs text-red-500 font-bold">FAULTED</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between text-xs text-text-secondary">
|
||||
<span>HGST-7200</span>
|
||||
<span>4 TB</span>
|
||||
</div>
|
||||
<div class="flex gap-0.5 h-1.5 w-full rounded-full overflow-hidden bg-slate-200 dark:bg-slate-700">
|
||||
<!-- Error state for bar -->
|
||||
<div class="bg-red-500 w-full opacity-50"></div>
|
||||
</div>
|
||||
<span class="text-[10px] text-red-400 mt-1">Pool: archive_legacy</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Disk 5 (Spare) -->
|
||||
<div class="bg-white dark:bg-surface-dark rounded-lg p-4 border border-slate-200 dark:border-border-dark flex flex-col gap-3 hover:border-primary/50 transition-colors group cursor-pointer relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 p-2">
|
||||
<div class="w-2 h-2 rounded-full bg-blue-500"></div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded bg-slate-100 dark:bg-slate-800 flex items-center justify-center">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-primary transition-colors">medical_services</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm font-bold text-slate-900 dark:text-white">sde</span>
|
||||
<span class="text-xs text-text-secondary">Slot 5</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between text-xs text-text-secondary">
|
||||
<span>Samsung SSD</span>
|
||||
<span>4 TB</span>
|
||||
</div>
|
||||
<div class="flex gap-0.5 h-1.5 w-full rounded-full overflow-hidden bg-slate-200 dark:bg-slate-700">
|
||||
<div class="bg-blue-500 w-0"></div>
|
||||
</div>
|
||||
<span class="text-[10px] text-blue-400 mt-1 font-bold">HOT SPARE</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Add Disk -->
|
||||
<div class="bg-slate-50 dark:bg-surface-dark/50 rounded-lg p-4 border border-dashed border-slate-300 dark:border-border-dark flex flex-col gap-3 hover:border-primary hover:bg-primary/5 transition-all group cursor-pointer items-center justify-center h-[134px]">
|
||||
<span class="material-symbols-outlined text-text-secondary group-hover:text-primary text-[32px]">add</span>
|
||||
<span class="text-sm font-medium text-text-secondary group-hover:text-primary">Add New Disk</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<!-- Slide-over Panel (Simulated) -->
|
||||
<div class="fixed inset-y-0 right-0 w-96 bg-white dark:bg-surface-darker border-l border-slate-200 dark:border-border-dark shadow-2xl z-30 transform translate-x-full lg:translate-x-0 transition-transform duration-300 flex flex-col">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between p-6 border-b border-slate-200 dark:border-border-dark bg-slate-50 dark:bg-surface-dark">
|
||||
<h3 class="text-lg font-bold text-slate-900 dark:text-white">tank0 Properties</h3>
|
||||
<button class="text-text-secondary hover:text-slate-900 dark:hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Content -->
|
||||
<div class="flex-1 overflow-y-auto p-6 flex flex-col gap-6">
|
||||
<!-- Quick Info -->
|
||||
<div class="p-4 rounded-lg bg-primary/10 border border-primary/20">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<span class="material-symbols-outlined text-primary">info</span>
|
||||
<span class="text-sm font-bold text-primary">Healthy</span>
|
||||
</div>
|
||||
<p class="text-xs text-slate-600 dark:text-slate-300 leading-relaxed">
|
||||
This pool is operating normally. Scrub completed successfully on Oct 24, 2023.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<!-- Setting -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-sm font-medium text-slate-900 dark:text-white">Compression Level</label>
|
||||
<select class="w-full bg-white dark:bg-surface-dark border border-slate-300 dark:border-border-dark rounded-lg px-3 py-2 text-sm text-slate-700 dark:text-white focus:ring-2 focus:ring-primary outline-none">
|
||||
<option value="off">Off</option>
|
||||
<option selected="" value="lz4">LZ4 (Recommended)</option>
|
||||
<option value="zstd">ZSTD</option>
|
||||
<option value="gzip">GZIP</option>
|
||||
</select>
|
||||
<p class="text-xs text-text-secondary">Balances performance and storage efficiency.</p>
|
||||
</div>
|
||||
<!-- Setting -->
|
||||
<div class="flex flex-col gap-2 border-t border-slate-200 dark:border-border-dark pt-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="text-sm font-medium text-slate-900 dark:text-white">Deduplication</label>
|
||||
<!-- Toggle Switch -->
|
||||
<button aria-checked="false" class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full relative transition-colors focus:outline-none focus:ring-2 focus:ring-primary">
|
||||
<span class="absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-0"></span>
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-xs text-text-secondary">Requires significant RAM. Use with caution.</p>
|
||||
</div>
|
||||
<!-- Setting -->
|
||||
<div class="flex flex-col gap-2 border-t border-slate-200 dark:border-border-dark pt-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="text-sm font-medium text-slate-900 dark:text-white">Auto-Expand</label>
|
||||
<button aria-checked="true" class="w-11 h-6 bg-primary rounded-full relative transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface-darker focus:ring-primary">
|
||||
<span class="absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform transform translate-x-5"></span>
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-xs text-text-secondary">Automatically grow pool when larger disks are added.</p>
|
||||
</div>
|
||||
<!-- Setting -->
|
||||
<div class="flex flex-col gap-2 border-t border-slate-200 dark:border-border-dark pt-4">
|
||||
<label class="text-sm font-medium text-slate-900 dark:text-white">Scrub Interval</label>
|
||||
<div class="flex items-center gap-2">
|
||||
<input class="w-20 bg-white dark:bg-surface-dark border border-slate-300 dark:border-border-dark rounded-lg px-3 py-2 text-sm text-slate-700 dark:text-white focus:ring-2 focus:ring-primary outline-none" type="number" value="30"/>
|
||||
<span class="text-sm text-text-secondary">days</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Footer Actions -->
|
||||
<div class="p-6 border-t border-slate-200 dark:border-border-dark bg-slate-50 dark:bg-surface-dark flex gap-3">
|
||||
<button class="flex-1 px-4 py-2 bg-primary text-white text-sm font-bold rounded-lg hover:bg-primary/90 transition-colors">Save Changes</button>
|
||||
<button class="px-4 py-2 bg-white dark:bg-surface-darker border border-slate-300 dark:border-border-dark text-slate-700 dark:text-white text-sm font-bold rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">Cancel</button>
|
||||
</div>
|
||||
<div class="p-6 pt-0 bg-slate-50 dark:bg-surface-dark">
|
||||
<button class="w-full px-4 py-2 border border-red-500/30 text-red-500 hover:bg-red-500/10 text-sm font-bold rounded-lg transition-colors flex items-center justify-center gap-2">
|
||||
<span class="material-symbols-outlined text-[18px]">delete</span>
|
||||
Export / Destroy Pool
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
BIN
src/web/storage-management.png
Normal file
|
After Width: | Height: | Size: 310 KiB |
459
src/web/system-management-code.html
Normal file
@@ -0,0 +1,459 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>System Settings - Backup Appliance</title>
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<!-- Tailwind Config -->
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#101922",
|
||||
"card-dark": "#192633",
|
||||
"border-dark": "#233648",
|
||||
"text-secondary": "#92adc9",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"]
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Custom Toggle Switch */
|
||||
.toggle-checkbox:checked {
|
||||
right: 0;
|
||||
border-color: #137fec;
|
||||
}
|
||||
.toggle-checkbox:checked + .toggle-label {
|
||||
background-color: #137fec;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Manrope', sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-slate-900 dark:text-white overflow-hidden">
|
||||
<div class="flex h-screen w-full">
|
||||
<!-- Side Navigation -->
|
||||
<aside class="hidden w-64 flex-col border-r border-border-dark bg-background-dark md:flex">
|
||||
<div class="flex h-16 items-center px-6 border-b border-border-dark">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary" style="font-size: 28px;">dns</span>
|
||||
<h1 class="text-lg font-bold tracking-tight">BackupNode</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-1 flex-col justify-between p-4 overflow-y-auto">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="px-2">
|
||||
<p class="text-xs font-bold uppercase tracking-wider text-text-secondary mb-2">Main</p>
|
||||
<div class="flex flex-col gap-1">
|
||||
<a class="flex items-center gap-3 rounded-lg px-3 py-2 text-text-secondary hover:bg-border-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined">dashboard</span>
|
||||
<span class="text-sm font-medium">Dashboard</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 rounded-lg px-3 py-2 text-text-secondary hover:bg-border-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined">hard_drive</span>
|
||||
<span class="text-sm font-medium">Storage Pools</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 rounded-lg px-3 py-2 text-text-secondary hover:bg-border-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined">cloud_upload</span>
|
||||
<span class="text-sm font-medium">Cloud Sync</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<p class="text-xs font-bold uppercase tracking-wider text-text-secondary mb-2">System</p>
|
||||
<div class="flex flex-col gap-1">
|
||||
<a class="flex items-center gap-3 rounded-lg bg-primary/20 px-3 py-2 text-primary transition-colors" href="#">
|
||||
<span class="material-symbols-outlined fill-1">settings</span>
|
||||
<span class="text-sm font-bold">Settings</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 rounded-lg px-3 py-2 text-text-secondary hover:bg-border-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined">security</span>
|
||||
<span class="text-sm font-medium">Access Control</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 rounded-lg px-3 py-2 text-text-secondary hover:bg-border-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined">description</span>
|
||||
<span class="text-sm font-medium">System Logs</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-auto border-t border-border-dark pt-4">
|
||||
<div class="flex items-center gap-3 px-2 py-2">
|
||||
<div class="relative">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500 absolute -right-0.5 -bottom-0.5 border border-background-dark"></div>
|
||||
<div class="h-8 w-8 rounded-full bg-border-dark flex items-center justify-center text-text-secondary">
|
||||
<span class="material-symbols-outlined text-sm">person</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<p class="text-sm font-bold text-white">Administrator</p>
|
||||
<p class="text-xs text-text-secondary">root</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- Main Content -->
|
||||
<main class="flex flex-1 flex-col bg-background-light dark:bg-background-dark overflow-hidden relative">
|
||||
<!-- Top Navigation -->
|
||||
<header class="flex h-16 items-center justify-between border-b border-border-dark bg-background-dark px-6 lg:px-10 shrink-0 z-10">
|
||||
<div class="flex items-center gap-4">
|
||||
<button class="text-text-secondary md:hidden hover:text-white">
|
||||
<span class="material-symbols-outlined">menu</span>
|
||||
</button>
|
||||
<!-- Breadcrumbs -->
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<a class="text-text-secondary hover:text-white transition-colors" href="#">System</a>
|
||||
<span class="text-text-secondary">/</span>
|
||||
<span class="text-white font-medium">Configuration</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="hidden md:flex items-center gap-2 px-3 py-1.5 rounded-full bg-green-500/10 border border-green-500/20">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500 animate-pulse"></div>
|
||||
<span class="text-xs font-medium text-green-500">System Healthy</span>
|
||||
</div>
|
||||
<div class="h-6 w-px bg-border-dark mx-2"></div>
|
||||
<button class="flex items-center justify-center gap-2 rounded-lg bg-border-dark px-4 py-2 text-sm font-bold text-white hover:bg-[#2f455a] transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px]">restart_alt</span>
|
||||
<span class="hidden sm:inline">Reboot</span>
|
||||
</button>
|
||||
<button class="flex items-center justify-center gap-2 rounded-lg bg-red-500/10 px-4 py-2 text-sm font-bold text-red-500 hover:bg-red-500/20 transition-colors border border-red-500/20">
|
||||
<span class="material-symbols-outlined text-[18px]">power_settings_new</span>
|
||||
<span class="hidden sm:inline">Shutdown</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Scrollable Content -->
|
||||
<div class="flex-1 overflow-y-auto p-4 md:p-8 lg:px-12 scroll-smooth">
|
||||
<div class="mx-auto max-w-7xl">
|
||||
<!-- Page Header -->
|
||||
<div class="mb-8 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold tracking-tight text-white mb-2">System Configuration</h1>
|
||||
<p class="text-text-secondary text-sm max-w-2xl">
|
||||
Manage network interfaces, time synchronization, service states, and remote management protocols.
|
||||
</p>
|
||||
</div>
|
||||
<button class="flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-bold text-white hover:bg-blue-600 transition-all shadow-lg shadow-blue-500/20">
|
||||
<span class="material-symbols-outlined text-[20px]">save</span>
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
<!-- Grid Layout -->
|
||||
<div class="grid grid-cols-1 gap-6 xl:grid-cols-2">
|
||||
<!-- Network Card -->
|
||||
<div class="flex flex-col rounded-xl border border-border-dark bg-card-dark shadow-sm">
|
||||
<div class="flex items-center justify-between border-b border-border-dark px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-primary">lan</span>
|
||||
<h2 class="text-lg font-bold text-white">Network Interfaces</h2>
|
||||
</div>
|
||||
<button class="text-xs font-bold text-primary hover:text-blue-400">CONFIGURE DNS</button>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<!-- Interface Item 1 -->
|
||||
<div class="group flex items-center justify-between rounded-lg p-3 hover:bg-border-dark/50 transition-colors">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-border-dark text-white">
|
||||
<span class="material-symbols-outlined">settings_ethernet</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<p class="font-bold text-white">eth0</p>
|
||||
<span class="rounded bg-primary/20 px-1.5 py-0.5 text-[10px] font-bold text-primary uppercase">Management</span>
|
||||
</div>
|
||||
<p class="font-mono text-xs text-text-secondary">192.168.1.50 <span class="opacity-50 mx-1">/</span> 24</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="hidden sm:flex flex-col items-end">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500"></div>
|
||||
<span class="text-xs font-medium text-white">Connected</span>
|
||||
</div>
|
||||
<span class="text-xs text-text-secondary">10 Gbps</span>
|
||||
</div>
|
||||
<button class="h-8 w-8 rounded-full hover:bg-border-dark flex items-center justify-center text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">more_vert</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Interface Item 2 -->
|
||||
<div class="group flex items-center justify-between rounded-lg p-3 hover:bg-border-dark/50 transition-colors">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-border-dark text-white">
|
||||
<span class="material-symbols-outlined">settings_ethernet</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<p class="font-bold text-white">eth1</p>
|
||||
<span class="rounded bg-purple-500/20 px-1.5 py-0.5 text-[10px] font-bold text-purple-400 uppercase">iSCSI</span>
|
||||
</div>
|
||||
<p class="font-mono text-xs text-text-secondary">10.0.50.10 <span class="opacity-50 mx-1">/</span> 24</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="hidden sm:flex flex-col items-end">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500"></div>
|
||||
<span class="text-xs font-medium text-white">Connected</span>
|
||||
</div>
|
||||
<span class="text-xs text-text-secondary">10 Gbps</span>
|
||||
</div>
|
||||
<button class="h-8 w-8 rounded-full hover:bg-border-dark flex items-center justify-center text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">more_vert</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Interface Item 3 -->
|
||||
<div class="group flex items-center justify-between rounded-lg p-3 hover:bg-border-dark/50 transition-colors opacity-70">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-border-dark text-text-secondary">
|
||||
<span class="material-symbols-outlined">settings_ethernet</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<p class="font-bold text-text-secondary">eth2</p>
|
||||
</div>
|
||||
<p class="font-mono text-xs text-text-secondary">No Carrier</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="hidden sm:flex flex-col items-end">
|
||||
<div class="flex items-center gap-1.5">
|
||||
<div class="h-2 w-2 rounded-full bg-red-500"></div>
|
||||
<span class="text-xs font-medium text-text-secondary">Down</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="h-8 w-8 rounded-full hover:bg-border-dark flex items-center justify-center text-text-secondary hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">more_vert</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Services Card -->
|
||||
<div class="flex flex-col rounded-xl border border-border-dark bg-card-dark shadow-sm">
|
||||
<div class="flex items-center justify-between border-b border-border-dark px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-primary">memory</span>
|
||||
<h2 class="text-lg font-bold text-white">Service Control</h2>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="h-2 w-2 rounded-full bg-green-500"></span>
|
||||
<span class="text-xs text-text-secondary">All Systems Normal</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 flex flex-col gap-1">
|
||||
<!-- Service Row -->
|
||||
<div class="flex items-center justify-between rounded-lg bg-[#111a22] p-3 border border-transparent hover:border-border-dark transition-colors">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded bg-border-dark/50 text-white">
|
||||
<span class="material-symbols-outlined text-[20px]">terminal</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold text-white">SSH Service</p>
|
||||
<p class="text-xs text-text-secondary">Remote command line access</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-green-500/20 text-green-500 border border-green-500/20">RUNNING</span>
|
||||
<div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
|
||||
<input checked="" class="toggle-checkbox absolute block w-5 h-5 rounded-full bg-white border-4 appearance-none cursor-pointer checked:right-0 checked:border-primary transition-all duration-300" id="ssh-toggle" name="toggle" type="checkbox"/>
|
||||
<label class="toggle-label block overflow-hidden h-5 rounded-full bg-border-dark cursor-pointer transition-colors duration-300" for="ssh-toggle"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Service Row -->
|
||||
<div class="flex items-center justify-between rounded-lg bg-[#111a22] p-3 border border-transparent hover:border-border-dark transition-colors">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded bg-border-dark/50 text-white">
|
||||
<span class="material-symbols-outlined text-[20px]">folder_shared</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold text-white">SMB / CIFS</p>
|
||||
<p class="text-xs text-text-secondary">Windows file sharing</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-green-500/20 text-green-500 border border-green-500/20">RUNNING</span>
|
||||
<div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
|
||||
<input checked="" class="toggle-checkbox absolute block w-5 h-5 rounded-full bg-white border-4 appearance-none cursor-pointer checked:right-0 checked:border-primary transition-all duration-300" id="smb-toggle" name="toggle" type="checkbox"/>
|
||||
<label class="toggle-label block overflow-hidden h-5 rounded-full bg-border-dark cursor-pointer transition-colors duration-300" for="smb-toggle"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Service Row -->
|
||||
<div class="flex items-center justify-between rounded-lg bg-[#111a22] p-3 border border-transparent hover:border-border-dark transition-colors">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded bg-border-dark/50 text-white">
|
||||
<span class="material-symbols-outlined text-[20px]">storage</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold text-white">iSCSI Target</p>
|
||||
<p class="text-xs text-text-secondary">Block storage sharing</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-yellow-500/20 text-yellow-500 border border-yellow-500/20">STOPPED</span>
|
||||
<div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
|
||||
<input class="toggle-checkbox absolute block w-5 h-5 rounded-full bg-white border-4 appearance-none cursor-pointer checked:right-0 checked:border-primary transition-all duration-300" id="iscsi-toggle" name="toggle" type="checkbox"/>
|
||||
<label class="toggle-label block overflow-hidden h-5 rounded-full bg-border-dark cursor-pointer transition-colors duration-300" for="iscsi-toggle"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Service Row -->
|
||||
<div class="flex items-center justify-between rounded-lg bg-[#111a22] p-3 border border-transparent hover:border-border-dark transition-colors">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 rounded bg-border-dark/50 text-white">
|
||||
<span class="material-symbols-outlined text-[20px]">share</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold text-white">NFS Service</p>
|
||||
<p class="text-xs text-text-secondary">Unix file sharing</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-bold bg-green-500/20 text-green-500 border border-green-500/20">RUNNING</span>
|
||||
<div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
|
||||
<input checked="" class="toggle-checkbox absolute block w-5 h-5 rounded-full bg-white border-4 appearance-none cursor-pointer checked:right-0 checked:border-primary transition-all duration-300" id="nfs-toggle" name="toggle" type="checkbox"/>
|
||||
<label class="toggle-label block overflow-hidden h-5 rounded-full bg-border-dark cursor-pointer transition-colors duration-300" for="nfs-toggle"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Date & Time Card -->
|
||||
<div class="flex flex-col rounded-xl border border-border-dark bg-card-dark shadow-sm">
|
||||
<div class="flex items-center justify-between border-b border-border-dark px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-primary">schedule</span>
|
||||
<h2 class="text-lg font-bold text-white">Date & Time</h2>
|
||||
</div>
|
||||
<span class="text-xs font-mono text-text-secondary bg-border-dark px-2 py-1 rounded">UTC</span>
|
||||
</div>
|
||||
<div class="p-6 flex flex-col gap-6">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="col-span-2">
|
||||
<label class="mb-2 block text-xs font-medium text-text-secondary uppercase">System Timezone</label>
|
||||
<div class="relative">
|
||||
<select class="block w-full rounded-lg border-border-dark bg-[#111a22] py-2.5 pl-3 pr-10 text-sm text-white focus:border-primary focus:ring-1 focus:ring-primary appearance-none">
|
||||
<option>Etc/UTC</option>
|
||||
<option>America/New_York</option>
|
||||
<option>Europe/London</option>
|
||||
<option>Asia/Tokyo</option>
|
||||
</select>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-white">
|
||||
<span class="material-symbols-outlined text-sm">expand_more</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label class="block text-xs font-medium text-text-secondary uppercase">NTP Servers</label>
|
||||
<button class="text-xs text-primary font-bold hover:text-white flex items-center gap-1">
|
||||
<span class="material-symbols-outlined text-[14px]">add</span> Add Server
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center justify-between rounded-lg bg-[#111a22] p-3 border border-border-dark">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500 animate-pulse"></div>
|
||||
<span class="text-sm font-mono text-white">pool.ntp.org</span>
|
||||
</div>
|
||||
<span class="text-xs text-text-secondary">Stratum 2 • 12ms</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between rounded-lg bg-[#111a22] p-3 border border-border-dark">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500"></div>
|
||||
<span class="text-sm font-mono text-white">time.google.com</span>
|
||||
</div>
|
||||
<span class="text-xs text-text-secondary">Stratum 1 • 45ms</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Management & SNMP Card -->
|
||||
<div class="flex flex-col rounded-xl border border-border-dark bg-card-dark shadow-sm">
|
||||
<div class="flex items-center justify-between border-b border-border-dark px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-primary">hub</span>
|
||||
<h2 class="text-lg font-bold text-white">Management</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6 flex flex-col gap-6">
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<h3 class="text-sm font-bold text-white">SNMP Monitoring</h3>
|
||||
<p class="text-xs text-text-secondary">Enable Simple Network Management Protocol</p>
|
||||
</div>
|
||||
<div class="relative inline-block w-10 align-middle select-none transition duration-200 ease-in">
|
||||
<input class="toggle-checkbox absolute block w-5 h-5 rounded-full bg-white border-4 appearance-none cursor-pointer checked:right-0 checked:border-primary transition-all duration-300" id="snmp-toggle" name="toggle" type="checkbox"/>
|
||||
<label class="toggle-label block overflow-hidden h-5 rounded-full bg-border-dark cursor-pointer transition-colors duration-300" for="snmp-toggle"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 gap-4 opacity-50 pointer-events-none" id="snmp-settings">
|
||||
<div>
|
||||
<label class="mb-1.5 block text-xs font-medium text-text-secondary uppercase">Community String</label>
|
||||
<input class="block w-full rounded-lg border-border-dark bg-[#111a22] p-2.5 text-sm text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary" placeholder="e.g. public" type="text" value="public"/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1.5 block text-xs font-medium text-text-secondary uppercase">Trap Receiver IP</label>
|
||||
<input class="block w-full rounded-lg border-border-dark bg-[#111a22] p-2.5 text-sm text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary" placeholder="e.g. 192.168.1.100" type="text"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-border-dark pt-4">
|
||||
<h3 class="text-sm font-bold text-white mb-3">Syslog Forwarding</h3>
|
||||
<div class="flex gap-2">
|
||||
<input class="flex-1 rounded-lg border-border-dark bg-[#111a22] p-2.5 text-sm text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary" placeholder="Syslog Server Address (UDP:514)" type="text"/>
|
||||
<button class="rounded-lg bg-border-dark px-4 py-2 text-sm font-bold text-white hover:bg-[#2f455a] transition-colors">Test</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Bottom Spacer -->
|
||||
<div class="h-10"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<script>
|
||||
// Simple script to toggle opacity of SNMP settings for visual feedback
|
||||
const snmpToggle = document.getElementById('snmp-toggle');
|
||||
const snmpSettings = document.getElementById('snmp-settings');
|
||||
|
||||
snmpToggle.addEventListener('change', function() {
|
||||
if(this.checked) {
|
||||
snmpSettings.classList.remove('opacity-50', 'pointer-events-none');
|
||||
} else {
|
||||
snmpSettings.classList.add('opacity-50', 'pointer-events-none');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
BIN
src/web/system-management.png
Normal file
|
After Width: | Height: | Size: 307 KiB |
453
src/web/system-monitoring-code.html
Normal file
@@ -0,0 +1,453 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Backup Appliance - Monitoring & Logs</title>
|
||||
<!-- Material Symbols -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Google Fonts: Manrope -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#111a22", /* Matching the example code background */
|
||||
"card-dark": "#1a2632", /* Slightly lighter than bg */
|
||||
"border-dark": "#324d67",
|
||||
"text-secondary": "#92adc9",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"],
|
||||
"mono": ["JetBrains Mono", "monospace"],
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Custom scrollbar for log viewer */
|
||||
.custom-scrollbar::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
.custom-scrollbar::-webkit-scrollbar-track {
|
||||
background: #111a22;
|
||||
}
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: #476685;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-slate-900 dark:text-white font-display overflow-hidden">
|
||||
<div class="flex h-screen w-full">
|
||||
<!-- SIDEBAR -->
|
||||
<aside class="w-64 flex flex-col border-r border-border-dark bg-background-dark flex-shrink-0 z-20">
|
||||
<div class="p-6 flex flex-col gap-1">
|
||||
<h1 class="text-white text-lg font-bold leading-normal tracking-tight">Backup Appliance</h1>
|
||||
<p class="text-text-secondary text-xs font-mono">v4.2.0-stable</p>
|
||||
</div>
|
||||
<nav class="flex-1 overflow-y-auto px-4 space-y-2">
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">dashboard</span>
|
||||
<span class="text-sm font-medium">Dashboard</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">hard_drive</span>
|
||||
<span class="text-sm font-medium">Storage</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">network_check</span>
|
||||
<span class="text-sm font-medium">Network</span>
|
||||
</a>
|
||||
<!-- Active State -->
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg bg-[#233648] text-primary border border-primary/20" href="#">
|
||||
<span class="material-symbols-outlined text-[24px] fill-current">monitoring</span>
|
||||
<span class="text-sm font-bold">Monitor & Logs</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2 rounded-lg text-text-secondary hover:bg-card-dark hover:text-white transition-colors" href="#">
|
||||
<span class="material-symbols-outlined text-[24px]">settings</span>
|
||||
<span class="text-sm font-medium">Settings</span>
|
||||
</a>
|
||||
</nav>
|
||||
<div class="p-4 border-t border-border-dark">
|
||||
<div class="flex items-center gap-3 p-2 rounded-lg bg-card-dark border border-border-dark">
|
||||
<div class="h-8 w-8 rounded-full bg-primary flex items-center justify-center text-white font-bold text-xs">AD</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-xs font-bold text-white">Admin User</span>
|
||||
<span class="text-[10px] text-text-secondary">admin@local</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- MAIN CONTENT -->
|
||||
<main class="flex-1 flex flex-col min-w-0 bg-background-dark overflow-hidden relative">
|
||||
<!-- HEADER -->
|
||||
<header class="flex-none px-6 py-5 border-b border-border-dark bg-background-dark/95 backdrop-blur z-10">
|
||||
<div class="flex flex-wrap justify-between items-end gap-3 max-w-[1600px] mx-auto">
|
||||
<div class="flex flex-col gap-1">
|
||||
<h2 class="text-white text-3xl font-black tracking-tight">System Monitor</h2>
|
||||
<p class="text-text-secondary text-sm">Real-time telemetry, ZFS health, and system event logs</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-2 px-3 py-2 bg-card-dark rounded-lg border border-border-dark">
|
||||
<span class="relative flex h-2 w-2">
|
||||
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
||||
<span class="relative inline-flex rounded-full h-2 w-2 bg-emerald-500"></span>
|
||||
</span>
|
||||
<span class="text-xs font-medium text-emerald-400">System Healthy</span>
|
||||
</div>
|
||||
<button class="flex items-center gap-2 h-10 px-4 bg-card-dark hover:bg-[#233648] border border-border-dark text-white text-sm font-bold rounded-lg transition-colors">
|
||||
<span class="material-symbols-outlined text-[18px]">refresh</span>
|
||||
<span>Refresh: 5s</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- SCROLLABLE CONTENT AREA -->
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar p-6">
|
||||
<div class="flex flex-col gap-6 max-w-[1600px] mx-auto pb-10">
|
||||
<!-- TOP STATS ROW -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<!-- CPU -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">CPU Load</p>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[20px]">memory</span>
|
||||
</div>
|
||||
<div class="flex items-end gap-3 mt-1">
|
||||
<p class="text-white text-3xl font-bold">12%</p>
|
||||
<span class="text-emerald-500 text-sm font-medium mb-1 flex items-center">
|
||||
<span class="material-symbols-outlined text-[16px]">trending_down</span> 2%
|
||||
</span>
|
||||
</div>
|
||||
<!-- Mini Sparkline visualization -->
|
||||
<div class="h-1.5 w-full bg-[#233648] rounded-full mt-3 overflow-hidden">
|
||||
<div class="h-full bg-primary w-[12%] rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RAM -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">RAM Usage</p>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[20px]">memory_alt</span>
|
||||
</div>
|
||||
<div class="flex items-end gap-3 mt-1">
|
||||
<p class="text-white text-3xl font-bold">8.4 <span class="text-lg text-text-secondary font-medium">GB</span></p>
|
||||
<span class="text-text-secondary text-xs mb-2">/ 32 GB</span>
|
||||
</div>
|
||||
<div class="h-1.5 w-full bg-[#233648] rounded-full mt-3 overflow-hidden">
|
||||
<div class="h-full bg-emerald-500 w-[26%] rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ZFS Health -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">ZFS Pool Status</p>
|
||||
<span class="material-symbols-outlined text-emerald-500 text-[20px]">check_circle</span>
|
||||
</div>
|
||||
<div class="flex items-end gap-3 mt-1">
|
||||
<p class="text-white text-3xl font-bold">Online</p>
|
||||
<span class="text-text-secondary text-sm font-medium mb-1">No Errors</span>
|
||||
</div>
|
||||
<div class="flex gap-1 mt-3">
|
||||
<div class="h-1.5 flex-1 bg-emerald-500 rounded-l-full"></div>
|
||||
<div class="h-1.5 flex-1 bg-emerald-500"></div>
|
||||
<div class="h-1.5 flex-1 bg-emerald-500"></div>
|
||||
<div class="h-1.5 flex-1 bg-emerald-500 rounded-r-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Uptime -->
|
||||
<div class="flex flex-col gap-2 rounded-xl p-5 border border-border-dark bg-card-dark">
|
||||
<div class="flex justify-between items-start">
|
||||
<p class="text-text-secondary text-sm font-medium">System Uptime</p>
|
||||
<span class="material-symbols-outlined text-text-secondary text-[20px]">schedule</span>
|
||||
</div>
|
||||
<div class="mt-1">
|
||||
<p class="text-white text-3xl font-bold">14d 2h 12m</p>
|
||||
</div>
|
||||
<p class="text-text-secondary text-xs mt-3">Last reboot: Manual Patching</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MIDDLE SECTION: CHARTS & DISKS -->
|
||||
<div class="grid grid-cols-1 xl:grid-cols-3 gap-6">
|
||||
<!-- CHARTS COLUMN (2/3) -->
|
||||
<div class="xl:col-span-2 flex flex-col gap-6">
|
||||
<!-- Network Chart -->
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl p-6 shadow-sm">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h3 class="text-white text-lg font-bold">Network Throughput</h3>
|
||||
<p class="text-text-secondary text-sm">Inbound vs Outbound (eth0)</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-white text-2xl font-bold leading-tight">1.2 Gbps</p>
|
||||
<p class="text-emerald-500 text-sm">Peak: 2.1 Gbps</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-[200px] w-full relative">
|
||||
<!-- Simulated SVG Chart -->
|
||||
<svg class="w-full h-full" preserveaspectratio="none" viewbox="0 0 1000 200">
|
||||
<defs>
|
||||
<lineargradient id="gradientPrimary" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0%" stop-color="#137fec" stop-opacity="0.2"></stop>
|
||||
<stop offset="100%" stop-color="#137fec" stop-opacity="0"></stop>
|
||||
</lineargradient>
|
||||
</defs>
|
||||
<!-- Outbound Line -->
|
||||
<path d="M0,150 Q100,140 200,100 T400,120 T600,80 T800,140 T1000,100" fill="none" stroke="#92adc9" stroke-dasharray="5,5" stroke-width="2"></path>
|
||||
<!-- Inbound Area -->
|
||||
<path d="M0,120 Q150,150 300,50 T600,80 T900,40 L1000,60 V200 H0 Z" fill="url(#gradientPrimary)"></path>
|
||||
<path d="M0,120 Q150,150 300,50 T600,80 T900,40 L1000,60" fill="none" stroke="#137fec" stroke-width="3"></path>
|
||||
</svg>
|
||||
<!-- X-Axis Labels -->
|
||||
<div class="flex justify-between text-text-secondary text-xs mt-2 font-mono">
|
||||
<span>10:00</span>
|
||||
<span>10:15</span>
|
||||
<span>10:30</span>
|
||||
<span>10:45</span>
|
||||
<span>11:00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ZFS ARC Chart -->
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl p-6 shadow-sm">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h3 class="text-white text-lg font-bold">ZFS ARC Hit Ratio</h3>
|
||||
<p class="text-text-secondary text-sm">Cache efficiency</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-white text-2xl font-bold leading-tight">94%</p>
|
||||
<p class="text-text-secondary text-sm">Target: >90%</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-[150px] w-full relative">
|
||||
<!-- Simulated SVG Chart -->
|
||||
<svg class="w-full h-full" preserveaspectratio="none" viewbox="0 0 1000 150">
|
||||
<path d="M0,40 L100,40 L105,80 L110,40 L300,35 L305,90 L310,35 L600,30 L605,100 L610,30 L1000,25" fill="none" stroke="#10b981" stroke-width="2"></path>
|
||||
</svg>
|
||||
<div class="w-full h-[1px] bg-border-dark absolute top-[20%]"></div>
|
||||
<div class="absolute top-[20%] right-0 text-xs text-text-secondary -mt-5">95%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- DISK HEATMAP COLUMN (1/3) -->
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl p-6 h-full shadow-sm flex flex-col">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="text-white text-lg font-bold">Disk Health</h3>
|
||||
<span class="bg-[#233648] text-white text-xs px-2 py-1 rounded border border-border-dark">Pool 1</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-4 gap-3 flex-1 content-start">
|
||||
<!-- Healthy Disks -->
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center group relative cursor-help">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da0</span>
|
||||
<div class="absolute bottom-full mb-2 hidden group-hover:block bg-black text-white text-xs p-2 rounded whitespace-nowrap z-10">Serial: Z802JKA</div>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da1</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da2</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da3</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da4</span>
|
||||
</div>
|
||||
<!-- Warning Disk -->
|
||||
<div class="aspect-square bg-[#332a18] border border-yellow-700/50 rounded flex flex-col items-center justify-center relative">
|
||||
<span class="absolute top-1 right-1 h-2 w-2 rounded-full bg-yellow-500 animate-pulse"></span>
|
||||
<span class="material-symbols-outlined text-yellow-500">warning</span>
|
||||
<span class="text-[10px] text-yellow-500 font-mono mt-1">da5</span>
|
||||
</div>
|
||||
<!-- Healthy Disks -->
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da6</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#1a2e22] border border-emerald-800 rounded flex flex-col items-center justify-center">
|
||||
<span class="material-symbols-outlined text-emerald-500">hard_drive</span>
|
||||
<span class="text-[10px] text-emerald-500 font-mono mt-1">da7</span>
|
||||
</div>
|
||||
<!-- Empty/Spare Slots -->
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
<div class="aspect-square bg-[#161f29] border border-border-dark border-dashed rounded flex flex-col items-center justify-center opacity-50">
|
||||
<span class="text-[10px] text-text-secondary font-mono">Empty</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 pt-4 border-t border-border-dark">
|
||||
<div class="flex justify-between text-sm text-text-secondary">
|
||||
<span>Total Capacity</span>
|
||||
<span class="text-white font-bold">64 TB</span>
|
||||
</div>
|
||||
<div class="w-full bg-[#233648] h-2 rounded-full mt-2 overflow-hidden">
|
||||
<div class="bg-primary h-full w-[65%]"></div>
|
||||
</div>
|
||||
<div class="flex justify-between text-xs text-text-secondary mt-1">
|
||||
<span>Used: 41.6 TB</span>
|
||||
<span>Free: 22.4 TB</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- BOTTOM SECTION: TABS & LOGS -->
|
||||
<div class="bg-card-dark border border-border-dark rounded-xl shadow-sm overflow-hidden flex flex-col h-[400px]">
|
||||
<!-- Tabs Header -->
|
||||
<div class="flex border-b border-border-dark bg-[#161f29]">
|
||||
<button class="px-6 py-4 text-sm font-bold text-primary border-b-2 border-primary bg-card-dark">
|
||||
Active Jobs <span class="ml-2 bg-primary/20 text-primary px-1.5 py-0.5 rounded text-xs">2</span>
|
||||
</button>
|
||||
<button class="px-6 py-4 text-sm font-medium text-text-secondary hover:text-white transition-colors">
|
||||
System Logs
|
||||
</button>
|
||||
<button class="px-6 py-4 text-sm font-medium text-text-secondary hover:text-white transition-colors">
|
||||
Alerts History
|
||||
</button>
|
||||
<div class="flex-1 flex justify-end items-center px-4">
|
||||
<div class="relative">
|
||||
<span class="material-symbols-outlined absolute left-2 top-1.5 text-text-secondary text-[18px]">search</span>
|
||||
<input class="bg-[#111a22] border border-border-dark rounded-md py-1 pl-8 pr-3 text-sm text-white focus:outline-none focus:border-primary w-48 transition-all" placeholder="Search logs..." type="text"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tab Content: Active Jobs + Logs Combined View for design -->
|
||||
<div class="flex-1 overflow-hidden flex flex-col">
|
||||
<!-- Jobs Section -->
|
||||
<div class="p-0">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead class="bg-[#1a2632] text-xs uppercase text-text-secondary font-medium sticky top-0 z-10">
|
||||
<tr>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Job Name</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Type</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark w-1/3">Progress</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Speed</th>
|
||||
<th class="px-6 py-3 border-b border-border-dark">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-sm divide-y divide-border-dark">
|
||||
<!-- Active Job 1 -->
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-4 font-medium text-white">Daily Backup: VM-Cluster-01</td>
|
||||
<td class="px-6 py-4 text-text-secondary">Replication</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-full bg-[#111a22] rounded-full h-2 overflow-hidden">
|
||||
<div class="bg-primary h-full rounded-full w-[45%] relative overflow-hidden">
|
||||
<div class="absolute inset-0 bg-white/20 animate-[pulse_2s_infinite]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-xs font-mono text-white">45%</span>
|
||||
</div>
|
||||
<p class="text-[10px] text-text-secondary mt-1">ETA: 1h 12m</p>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-text-secondary font-mono">145 MB/s</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-primary/20 text-primary">
|
||||
Running
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Active Job 2 -->
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-4 font-medium text-white">ZFS Scrub: Pool-01</td>
|
||||
<td class="px-6 py-4 text-text-secondary">Maintenance</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-full bg-[#111a22] rounded-full h-2 overflow-hidden">
|
||||
<div class="bg-primary h-full rounded-full w-[78%] relative overflow-hidden"></div>
|
||||
</div>
|
||||
<span class="text-xs font-mono text-white">78%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-text-secondary font-mono">1.2 GB/s</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-primary/20 text-primary">
|
||||
Running
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Logs Section Header (Visual Separator) -->
|
||||
<div class="px-6 py-2 bg-[#161f29] border-y border-border-dark flex items-center justify-between">
|
||||
<h4 class="text-xs uppercase text-text-secondary font-bold tracking-wider">Recent System Events</h4>
|
||||
<button class="text-xs text-primary hover:text-white transition-colors">View All Logs</button>
|
||||
</div>
|
||||
<!-- Logs Table -->
|
||||
<div class="flex-1 overflow-y-auto custom-scrollbar bg-[#111a22]">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<tbody class="text-sm font-mono divide-y divide-border-dark/50">
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:45:22</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-emerald-500">INFO</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">systemd</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">Started User Manager for UID 1000.</td>
|
||||
</tr>
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:45:15</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-yellow-500">WARN</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">smartd</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">Device: /dev/ada5, SMART Usage Attribute: 194 Temperature_Celsius changed from 38 to 41</td>
|
||||
</tr>
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:44:58</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-emerald-500">INFO</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">kernel</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">ix0: link state changed to UP</td>
|
||||
</tr>
|
||||
<tr class="group hover:bg-[#233648] transition-colors">
|
||||
<td class="px-6 py-2 text-text-secondary w-32 whitespace-nowrap">10:42:10</td>
|
||||
<td class="px-6 py-2 w-24">
|
||||
<span class="text-emerald-500">INFO</span>
|
||||
</td>
|
||||
<td class="px-6 py-2 w-32 text-white">zfs</td>
|
||||
<td class="px-6 py-2 text-text-secondary truncate max-w-lg">zfs_arc_reclaim_thread: reclaiming 157286400 bytes ...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body></html>
|
||||
BIN
src/web/system-monitoring.png
Normal file
|
After Width: | Height: | Size: 272 KiB |
400
src/web/user-access-management-code.html
Normal file
@@ -0,0 +1,400 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>User & Access Management - Backup Appliance</title>
|
||||
<!-- Google Fonts: Manrope -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<!-- Theme Configuration -->
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#101922",
|
||||
"surface-dark": "#1c2630",
|
||||
"surface-darker": "#111a22",
|
||||
"border-dark": "#324d67",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "sans-serif"]
|
||||
},
|
||||
borderRadius: { "DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px" },
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Custom scrollbar for dark mode cockpit feel */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #101922;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #137fec;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-slate-900 dark:text-white font-display overflow-hidden h-screen w-full flex">
|
||||
<!-- Sidebar -->
|
||||
<aside class="w-64 h-full bg-surface-darker flex flex-col border-r border-border-dark flex-shrink-0 z-20">
|
||||
<div class="p-6 flex flex-col gap-6">
|
||||
<!-- Appliance Identity -->
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-primary/20 p-2 rounded-lg">
|
||||
<span class="material-symbols-outlined text-primary text-3xl">dns</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h1 class="text-white text-base font-bold leading-tight">Backup Appliance</h1>
|
||||
<p class="text-slate-400 text-xs font-medium">Host: node-01.local</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Navigation -->
|
||||
<nav class="flex flex-col gap-2">
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">dashboard</span>
|
||||
<span class="text-sm font-medium">Dashboard</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">hard_drive</span>
|
||||
<span class="text-sm font-medium">Storage</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">lan</span>
|
||||
<span class="text-sm font-medium">Network</span>
|
||||
</a>
|
||||
<!-- Active State -->
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg bg-primary/10 text-primary border border-primary/20" href="#">
|
||||
<span class="material-symbols-outlined fill-1">manage_accounts</span>
|
||||
<span class="text-sm font-bold">User & Access</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">security</span>
|
||||
<span class="text-sm font-medium">Data Protection</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-slate-300 hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">settings</span>
|
||||
<span class="text-sm font-medium">System</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- User Profile (Bottom Sidebar) -->
|
||||
<div class="mt-auto p-4 border-t border-border-dark">
|
||||
<div class="flex items-center gap-3 px-2 py-2 rounded-lg hover:bg-surface-dark cursor-pointer transition-colors">
|
||||
<div class="h-8 w-8 rounded-full bg-cover bg-center ring-2 ring-border-dark" data-alt="Administrator profile picture" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuDzrQIWpC-TosfbyD0BB4efX7Qu00RduKrfteJ7r7YTjzmO5t98e3qOPYXvr-Zjxa_fzls8Vqy3Hl1Pfh01M45iBNGvfTswlOkJk9PDvJVHmngkOauGp61DKXrkfvVOymrFoPmFYGfx1o5Lxv1H078E95PFapYKZVO9Dh_0319rQLN4KFjOhjY4VDWOARbEKkbjGfT2reaOHVXhkc9A3XRRhd4opmYGmUrR68VVk0SOQ_2eFoZd69WnYjLTa44FoyzvpOE7Mps_JLg');"></div>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="text-sm font-semibold text-white truncate">Admin User</span>
|
||||
<span class="text-xs text-slate-400 truncate">System Administrator</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- Main Content Area -->
|
||||
<main class="flex-1 flex flex-col h-full overflow-hidden bg-background-dark">
|
||||
<!-- Scrollable content -->
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<div class="max-w-[1200px] mx-auto w-full p-8 flex flex-col gap-6">
|
||||
<!-- Page Header -->
|
||||
<header class="flex flex-wrap justify-between items-end gap-4 border-b border-border-dark pb-6">
|
||||
<div class="flex flex-col gap-2">
|
||||
<nav class="flex items-center gap-2 text-sm text-slate-400 mb-1">
|
||||
<span>System</span>
|
||||
<span class="material-symbols-outlined text-[16px]">chevron_right</span>
|
||||
<span class="text-white">Access Control</span>
|
||||
</nav>
|
||||
<h1 class="text-3xl font-black text-white leading-tight">User & Access Management</h1>
|
||||
<p class="text-slate-400 text-base max-w-2xl">Manage local accounts, define RBAC roles, and configure directory services (LDAP/AD) integration.</p>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<button class="flex items-center justify-center gap-2 px-4 py-2 bg-surface-dark border border-border-dark rounded-lg text-white hover:bg-border-dark transition-colors font-semibold">
|
||||
<span class="material-symbols-outlined text-[20px]">history</span>
|
||||
Audit Log
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Content Container -->
|
||||
<div class="flex flex-col gap-6">
|
||||
<!-- Tabs -->
|
||||
<div class="flex border-b border-border-dark gap-8">
|
||||
<button class="flex items-center gap-2 pb-3 border-b-[3px] border-primary text-white hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">group</span>
|
||||
<span class="text-sm font-bold">Local Users & Groups</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-2 pb-3 border-b-[3px] border-transparent text-slate-400 hover:text-white hover:border-slate-600 transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">badge</span>
|
||||
<span class="text-sm font-bold">Directory Services</span>
|
||||
</button>
|
||||
<button class="flex items-center gap-2 pb-3 border-b-[3px] border-transparent text-slate-400 hover:text-white hover:border-slate-600 transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">lock</span>
|
||||
<span class="text-sm font-bold">Authentication & SSO</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Toolbar Area -->
|
||||
<div class="flex flex-wrap gap-4 items-center justify-between">
|
||||
<!-- Search & Filter -->
|
||||
<div class="flex flex-1 max-w-xl gap-3">
|
||||
<div class="relative flex-1">
|
||||
<span class="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-slate-400">search</span>
|
||||
<input class="w-full bg-surface-dark border border-border-dark rounded-lg pl-10 pr-4 py-2.5 text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm" placeholder="Search users by name, role, or group..." type="text"/>
|
||||
</div>
|
||||
<button class="flex items-center gap-2 px-4 py-2.5 bg-surface-dark border border-border-dark rounded-lg text-slate-300 hover:text-white hover:border-slate-500 transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">filter_list</span>
|
||||
<span class="text-sm font-medium">Filter</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Primary Action -->
|
||||
<button class="flex items-center gap-2 bg-primary hover:bg-blue-600 text-white px-5 py-2.5 rounded-lg font-bold shadow-lg shadow-blue-500/20 transition-all">
|
||||
<span class="material-symbols-outlined text-[20px]">person_add</span>
|
||||
Create User
|
||||
</button>
|
||||
</div>
|
||||
<!-- Users Table -->
|
||||
<div class="rounded-xl border border-border-dark bg-surface-darker overflow-hidden shadow-sm">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="bg-surface-dark border-b border-border-dark text-left">
|
||||
<th class="px-6 py-4 text-xs font-bold text-slate-400 uppercase tracking-wider w-24">Status</th>
|
||||
<th class="px-6 py-4 text-xs font-bold text-slate-400 uppercase tracking-wider">Username</th>
|
||||
<th class="px-6 py-4 text-xs font-bold text-slate-400 uppercase tracking-wider">Full Name</th>
|
||||
<th class="px-6 py-4 text-xs font-bold text-slate-400 uppercase tracking-wider">Role</th>
|
||||
<th class="px-6 py-4 text-xs font-bold text-slate-400 uppercase tracking-wider">Groups</th>
|
||||
<th class="px-6 py-4 text-xs font-bold text-slate-400 uppercase tracking-wider">Last Login</th>
|
||||
<th class="px-6 py-4 text-xs font-bold text-slate-400 uppercase tracking-wider text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-border-dark">
|
||||
<!-- Row 1: Active Admin -->
|
||||
<tr class="group hover:bg-surface-dark transition-colors">
|
||||
<td class="px-6 py-4">
|
||||
<div class="inline-flex items-center gap-2 px-2.5 py-1 rounded-full bg-green-500/10 text-green-500 text-xs font-bold border border-green-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse"></span>
|
||||
Active
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-full bg-gradient-to-br from-blue-500 to-indigo-600 flex items-center justify-center text-white text-xs font-bold" data-alt="Avatar gradient">AD</div>
|
||||
<span class="text-white font-medium">admin</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-300 text-sm">System Administrator</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center gap-1.5 text-xs font-medium px-2.5 py-1 rounded-md bg-purple-500/10 text-purple-400 border border-purple-500/20">
|
||||
<span class="material-symbols-outlined text-[14px]">verified_user</span>
|
||||
Superuser
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">wheel, system</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">Just now</td>
|
||||
<td class="px-6 py-4 text-right">
|
||||
<button class="p-2 text-slate-400 hover:text-white hover:bg-border-dark rounded-lg transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 2: Operator -->
|
||||
<tr class="group hover:bg-surface-dark transition-colors">
|
||||
<td class="px-6 py-4">
|
||||
<div class="inline-flex items-center gap-2 px-2.5 py-1 rounded-full bg-green-500/10 text-green-500 text-xs font-bold border border-green-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-green-500"></span>
|
||||
Active
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-full bg-slate-700 flex items-center justify-center text-slate-300 text-xs font-bold" data-alt="Avatar placeholder">JD</div>
|
||||
<span class="text-white font-medium">jdoe</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-300 text-sm">John Doe</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center gap-1.5 text-xs font-medium px-2.5 py-1 rounded-md bg-blue-500/10 text-blue-400 border border-blue-500/20">
|
||||
<span class="material-symbols-outlined text-[14px]">engineering</span>
|
||||
Operator
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">operators, backup</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">2 days ago</td>
|
||||
<td class="px-6 py-4 text-right">
|
||||
<button class="p-2 text-slate-400 hover:text-white hover:bg-border-dark rounded-lg transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 3: Service Account (Locked) -->
|
||||
<tr class="group hover:bg-surface-dark transition-colors">
|
||||
<td class="px-6 py-4">
|
||||
<div class="inline-flex items-center gap-2 px-2.5 py-1 rounded-full bg-red-500/10 text-red-500 text-xs font-bold border border-red-500/20">
|
||||
<span class="material-symbols-outlined text-[14px]">lock</span>
|
||||
Locked
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-full bg-slate-700 flex items-center justify-center text-slate-300 text-xs font-bold" data-alt="Avatar placeholder">BS</div>
|
||||
<span class="text-white font-medium">backup_svc</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-300 text-sm">Backup Service Account</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center gap-1.5 text-xs font-medium px-2.5 py-1 rounded-md bg-slate-700 text-slate-300 border border-slate-600">
|
||||
<span class="material-symbols-outlined text-[14px]">smart_toy</span>
|
||||
Service
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">services</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">Never</td>
|
||||
<td class="px-6 py-4 text-right">
|
||||
<button class="p-2 text-slate-400 hover:text-white hover:bg-border-dark rounded-lg transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 4: Auditor -->
|
||||
<tr class="group hover:bg-surface-dark transition-colors">
|
||||
<td class="px-6 py-4">
|
||||
<div class="inline-flex items-center gap-2 px-2.5 py-1 rounded-full bg-green-500/10 text-green-500 text-xs font-bold border border-green-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-green-500"></span>
|
||||
Active
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-full bg-slate-700 flex items-center justify-center text-slate-300 text-xs font-bold" data-alt="Avatar placeholder">AS</div>
|
||||
<span class="text-white font-medium">asmith</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-300 text-sm">Alice Smith</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center gap-1.5 text-xs font-medium px-2.5 py-1 rounded-md bg-yellow-500/10 text-yellow-500 border border-yellow-500/20">
|
||||
<span class="material-symbols-outlined text-[14px]">visibility</span>
|
||||
Auditor
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">auditors</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">1 week ago</td>
|
||||
<td class="px-6 py-4 text-right">
|
||||
<button class="p-2 text-slate-400 hover:text-white hover:bg-border-dark rounded-lg transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 5: Storage Admin -->
|
||||
<tr class="group hover:bg-surface-dark transition-colors">
|
||||
<td class="px-6 py-4">
|
||||
<div class="inline-flex items-center gap-2 px-2.5 py-1 rounded-full bg-green-500/10 text-green-500 text-xs font-bold border border-green-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-green-500"></span>
|
||||
Active
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-full bg-slate-700 flex items-center justify-center text-slate-300 text-xs font-bold" data-alt="Avatar placeholder">RR</div>
|
||||
<span class="text-white font-medium">rroe</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-300 text-sm">Richard Roe</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="inline-flex items-center gap-1.5 text-xs font-medium px-2.5 py-1 rounded-md bg-teal-500/10 text-teal-500 border border-teal-500/20">
|
||||
<span class="material-symbols-outlined text-[14px]">storage</span>
|
||||
Storage Admin
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">storage_admins</td>
|
||||
<td class="px-6 py-4 text-slate-400 text-sm">5 hours ago</td>
|
||||
<td class="px-6 py-4 text-right">
|
||||
<button class="p-2 text-slate-400 hover:text-white hover:bg-border-dark rounded-lg transition-colors">
|
||||
<span class="material-symbols-outlined text-[20px]">more_vert</span>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Pagination -->
|
||||
<div class="px-6 py-4 border-t border-border-dark flex items-center justify-between bg-surface-dark">
|
||||
<span class="text-sm text-slate-400">Showing <span class="font-bold text-white">1-5</span> of <span class="font-bold text-white">24</span> users</span>
|
||||
<div class="flex gap-2">
|
||||
<button class="p-2 rounded-lg text-slate-400 hover:bg-border-dark hover:text-white disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<span class="material-symbols-outlined text-[20px]">chevron_left</span>
|
||||
</button>
|
||||
<button class="p-2 rounded-lg text-slate-400 hover:bg-border-dark hover:text-white">
|
||||
<span class="material-symbols-outlined text-[20px]">chevron_right</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Info Cards (Simulating Dashboard widgets) -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mt-2">
|
||||
<!-- Directory Status -->
|
||||
<div class="bg-surface-darker p-5 rounded-xl border border-border-dark flex flex-col gap-4">
|
||||
<div class="flex justify-between items-start">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 bg-slate-800 rounded-lg text-slate-300">
|
||||
<span class="material-symbols-outlined">domain</span>
|
||||
</div>
|
||||
<h3 class="text-white font-bold">Directory Service</h3>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-xs font-bold bg-slate-800 text-slate-400 border border-slate-700">Inactive</span>
|
||||
</div>
|
||||
<p class="text-sm text-slate-400">No LDAP or Active Directory server is currently connected. Local authentication is being used.</p>
|
||||
<div class="mt-auto pt-2">
|
||||
<a class="text-primary text-sm font-bold hover:underline flex items-center gap-1" href="#">
|
||||
Configure Directory
|
||||
<span class="material-symbols-outlined text-[16px]">arrow_forward</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MFA Status -->
|
||||
<div class="bg-surface-darker p-5 rounded-xl border border-border-dark flex flex-col gap-4">
|
||||
<div class="flex justify-between items-start">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 bg-orange-500/10 rounded-lg text-orange-500">
|
||||
<span class="material-symbols-outlined">shield</span>
|
||||
</div>
|
||||
<h3 class="text-white font-bold">Security Policy</h3>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-xs font-bold bg-green-500/10 text-green-500 border border-green-500/20">Good</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<span class="text-slate-400">Multi-Factor Auth</span>
|
||||
<span class="text-green-500 font-medium">Enforced</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<span class="text-slate-400">Password Rotation</span>
|
||||
<span class="text-white font-medium">90 Days</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-auto pt-2">
|
||||
<a class="text-primary text-sm font-bold hover:underline flex items-center gap-1" href="#">
|
||||
Manage Policies
|
||||
<span class="material-symbols-outlined text-[16px]">arrow_forward</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body></html>
|
||||
BIN
src/web/user-access-management.png
Normal file
|
After Width: | Height: | Size: 308 KiB |
516
src/web/vtl-management-code.html
Normal file
@@ -0,0 +1,516 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>Virtual Tape Library Management</title>
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
|
||||
<!-- Material Symbols -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<!-- Theme Configuration -->
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#137fec",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#101922",
|
||||
"surface-dark": "#1c2834",
|
||||
"border-dark": "#324d67",
|
||||
"text-secondary": "#92adc9",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Manrope", "Noto Sans", "sans-serif"]
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 24;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.material-symbols-filled {
|
||||
font-variation-settings:
|
||||
'FILL' 1,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 24;
|
||||
}
|
||||
|
||||
/* Custom scrollbar for dark theme */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #101922;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #4a6b8c;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark font-display text-slate-900 dark:text-white overflow-hidden">
|
||||
<div class="flex h-screen w-full">
|
||||
<!-- Sidebar Navigation -->
|
||||
<aside class="flex w-72 flex-col border-r border-border-dark bg-[#111a22] hidden lg:flex shrink-0 z-20">
|
||||
<div class="flex h-full flex-col justify-between p-4">
|
||||
<div class="flex flex-col gap-6">
|
||||
<!-- Appliance Header -->
|
||||
<div class="flex gap-3 items-center px-2">
|
||||
<div class="bg-center bg-no-repeat bg-cover rounded-full size-10 shadow-lg relative overflow-hidden bg-gradient-to-br from-blue-600 to-indigo-900" data-alt="Abstract blue gradient circle representing appliance logo">
|
||||
<div class="absolute inset-0 flex items-center justify-center text-white opacity-80">
|
||||
<span class="material-symbols-outlined text-xl">dns</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h1 class="text-white text-base font-bold leading-tight">Cockpit Appliance</h1>
|
||||
<p class="text-text-secondary text-xs font-medium">v4.2.0 • <span class="text-green-400">Online</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Navigation Links -->
|
||||
<nav class="flex flex-col gap-2">
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">hard_drive</span>
|
||||
<span class="text-sm font-medium">Storage</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">hub</span>
|
||||
<span class="text-sm font-medium">Networking</span>
|
||||
</a>
|
||||
<!-- Active State -->
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg bg-primary/20 text-white border-l-4 border-primary" href="#">
|
||||
<span class="material-symbols-outlined text-primary fill-current material-symbols-filled">database</span>
|
||||
<span class="text-sm font-bold">VTL</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">settings</span>
|
||||
<span class="text-sm font-medium">System</span>
|
||||
</a>
|
||||
<a class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-text-secondary hover:bg-surface-dark hover:text-white transition-colors group" href="#">
|
||||
<span class="material-symbols-outlined group-hover:text-primary transition-colors">description</span>
|
||||
<span class="text-sm font-medium">Logs</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- Footer User Profile -->
|
||||
<div class="flex items-center gap-3 px-3 py-3 border-t border-border-dark mt-auto">
|
||||
<div class="size-8 rounded-full bg-surface-dark flex items-center justify-center text-text-secondary">
|
||||
<span class="material-symbols-outlined text-sm">person</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<p class="text-white text-sm font-medium">Admin User</p>
|
||||
<p class="text-text-secondary text-xs">admin@local</p>
|
||||
</div>
|
||||
<button class="ml-auto text-text-secondary hover:text-white">
|
||||
<span class="material-symbols-outlined text-lg">logout</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<!-- Main Content Area -->
|
||||
<main class="flex-1 flex flex-col h-full overflow-hidden relative">
|
||||
<!-- Top Header & Breadcrumbs -->
|
||||
<header class="flex-none px-6 py-5 border-b border-border-dark bg-[#111a22]/95 backdrop-blur z-10">
|
||||
<div class="max-w-[1400px] mx-auto w-full flex flex-col gap-4">
|
||||
<!-- Breadcrumbs -->
|
||||
<div class="flex flex-wrap gap-2 items-center">
|
||||
<a class="text-text-secondary text-sm font-medium hover:text-primary transition-colors" href="#">Home</a>
|
||||
<span class="text-text-secondary text-xs">/</span>
|
||||
<a class="text-text-secondary text-sm font-medium hover:text-primary transition-colors" href="#">Storage</a>
|
||||
<span class="text-text-secondary text-xs">/</span>
|
||||
<span class="text-white text-sm font-medium">Virtual Tape Libraries</span>
|
||||
</div>
|
||||
<!-- Page Heading & Actions -->
|
||||
<div class="flex flex-wrap justify-between items-end gap-4">
|
||||
<div class="flex flex-col gap-1">
|
||||
<h2 class="text-white text-3xl font-bold tracking-tight">Virtual Tape Libraries</h2>
|
||||
<p class="text-text-secondary text-base max-w-2xl">Manage virtual tape devices, emulation profiles, and storage targets.</p>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<button class="px-4 py-2 bg-surface-dark hover:bg-[#2a3b4d] border border-border-dark rounded-lg text-white text-sm font-medium flex items-center gap-2 transition-all">
|
||||
<span class="material-symbols-outlined text-lg">refresh</span>
|
||||
Refresh
|
||||
</button>
|
||||
<button class="px-4 py-2 bg-primary hover:bg-blue-600 rounded-lg text-white text-sm font-bold shadow-lg shadow-blue-900/20 flex items-center gap-2 transition-all">
|
||||
<span class="material-symbols-outlined text-lg">add</span>
|
||||
Create VTL
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Scrollable Content -->
|
||||
<div class="flex-1 overflow-y-auto bg-background-dark">
|
||||
<div class="max-w-[1400px] mx-auto p-6 flex flex-col gap-6 pb-20">
|
||||
<!-- Stats Grid -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<!-- Stat Card 1 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark relative overflow-hidden group">
|
||||
<div class="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<span class="material-symbols-outlined text-6xl text-white">dns</span>
|
||||
</div>
|
||||
<p class="text-text-secondary text-sm font-medium">Total Libraries</p>
|
||||
<div class="flex items-end gap-2">
|
||||
<p class="text-white text-3xl font-bold tracking-tight">3</p>
|
||||
<span class="text-green-500 text-xs font-medium mb-1.5 flex items-center">
|
||||
<span class="material-symbols-outlined text-sm mr-0.5">check_circle</span> All Online
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stat Card 2 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark relative overflow-hidden group">
|
||||
<div class="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<span class="material-symbols-outlined text-6xl text-white">database</span>
|
||||
</div>
|
||||
<p class="text-text-secondary text-sm font-medium">Total Capacity</p>
|
||||
<div class="flex items-end gap-2">
|
||||
<p class="text-white text-3xl font-bold tracking-tight">120 <span class="text-lg text-text-secondary font-medium">TB</span></p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stat Card 3 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark relative overflow-hidden group">
|
||||
<div class="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<span class="material-symbols-outlined text-6xl text-white">album</span>
|
||||
</div>
|
||||
<p class="text-text-secondary text-sm font-medium">Tapes Online</p>
|
||||
<div class="flex items-end gap-2">
|
||||
<p class="text-white text-3xl font-bold tracking-tight">45</p>
|
||||
<span class="text-text-secondary text-xs font-medium mb-1.5">/ 200 Slots</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stat Card 4 -->
|
||||
<div class="flex flex-col gap-1 p-5 rounded-xl border border-border-dark bg-surface-dark relative overflow-hidden group">
|
||||
<div class="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<span class="material-symbols-outlined text-6xl text-white">swap_horiz</span>
|
||||
</div>
|
||||
<p class="text-text-secondary text-sm font-medium">Active Sessions</p>
|
||||
<div class="flex items-end gap-2">
|
||||
<p class="text-white text-3xl font-bold tracking-tight">2</p>
|
||||
<span class="text-blue-400 text-xs font-medium mb-1.5">Writing</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Usage Progress Section -->
|
||||
<div class="p-5 rounded-xl bg-surface-dark border border-border-dark flex flex-col gap-3">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-text-secondary">pie_chart</span>
|
||||
<h3 class="text-white text-sm font-semibold">VTL Partition Usage (ZFS Pool)</h3>
|
||||
</div>
|
||||
<p class="text-white text-sm font-medium">14.5 TB / 50 TB Used</p>
|
||||
</div>
|
||||
<div class="w-full bg-[#111a22] rounded-full h-3 overflow-hidden">
|
||||
<div class="bg-gradient-to-r from-blue-600 to-primary h-3 rounded-full" style="width: 29%"></div>
|
||||
</div>
|
||||
<div class="flex justify-between items-center text-xs text-text-secondary">
|
||||
<span>Compression Ratio: <span class="text-white font-mono">1.5x</span></span>
|
||||
<span class="flex items-center gap-1 text-green-400"><span class="w-2 h-2 rounded-full bg-green-500"></span> Pool Healthy</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Main Data Table Section -->
|
||||
<div class="flex flex-col rounded-xl border border-border-dark bg-surface-dark overflow-hidden">
|
||||
<!-- Toolbar -->
|
||||
<div class="p-4 border-b border-border-dark flex flex-col sm:flex-row gap-4 justify-between items-center bg-[#1c2834]">
|
||||
<div class="relative w-full sm:w-96">
|
||||
<span class="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary text-lg">search</span>
|
||||
<input class="w-full bg-[#111a22] border border-border-dark text-white text-sm rounded-lg pl-10 pr-4 py-2 focus:ring-1 focus:ring-primary focus:border-primary placeholder-gray-600 outline-none transition-all" placeholder="Search libraries by name or ID..." type="text"/>
|
||||
</div>
|
||||
<div class="flex gap-2 w-full sm:w-auto">
|
||||
<button class="px-3 py-2 bg-[#111a22] hover:bg-[#1a2632] border border-border-dark rounded-lg text-text-secondary text-sm font-medium flex items-center gap-2 transition-colors">
|
||||
<span class="material-symbols-outlined text-lg">filter_list</span>
|
||||
Filter
|
||||
</button>
|
||||
<button class="px-3 py-2 bg-[#111a22] hover:bg-[#1a2632] border border-border-dark rounded-lg text-text-secondary text-sm font-medium flex items-center gap-2 transition-colors">
|
||||
<span class="material-symbols-outlined text-lg">settings</span>
|
||||
Columns
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Table -->
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="bg-[#151e29] border-b border-border-dark">
|
||||
<th class="py-4 px-6 text-xs font-semibold uppercase tracking-wider text-text-secondary w-12">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-offset-background-dark focus:ring-primary h-4 w-4" type="checkbox"/>
|
||||
</th>
|
||||
<th class="py-4 px-6 text-xs font-semibold uppercase tracking-wider text-text-secondary">Library Name</th>
|
||||
<th class="py-4 px-6 text-xs font-semibold uppercase tracking-wider text-text-secondary">Status</th>
|
||||
<th class="py-4 px-6 text-xs font-semibold uppercase tracking-wider text-text-secondary">Emulation</th>
|
||||
<th class="py-4 px-6 text-xs font-semibold uppercase tracking-wider text-text-secondary">Tapes / Slots</th>
|
||||
<th class="py-4 px-6 text-xs font-semibold uppercase tracking-wider text-text-secondary">iSCSI Target</th>
|
||||
<th class="py-4 px-6 text-xs font-semibold uppercase tracking-wider text-text-secondary text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-border-dark">
|
||||
<!-- Row 1 -->
|
||||
<tr class="group hover:bg-[#233342] transition-colors">
|
||||
<td class="py-4 px-6">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-offset-background-dark focus:ring-primary h-4 w-4" type="checkbox"/>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="size-8 rounded bg-blue-900/30 flex items-center justify-center text-primary">
|
||||
<span class="material-symbols-outlined text-lg">shelves</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-white text-sm font-bold">VTL_Arch_01</p>
|
||||
<p class="text-text-secondary text-xs">ID: 001</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium bg-green-500/10 text-green-400 border border-green-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse"></span>
|
||||
Ready
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<p class="text-white text-sm font-medium">HP MSL2024</p>
|
||||
<p class="text-text-secondary text-xs">LTO-7 • 2 Drives</p>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-text-secondary text-lg">album</span>
|
||||
<span class="text-white text-sm">24 / 24</span>
|
||||
</div>
|
||||
<div class="w-24 bg-[#111a22] rounded-full h-1 mt-1.5">
|
||||
<div class="bg-primary h-1 rounded-full" style="width: 100%"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-2 group/copy cursor-pointer">
|
||||
<code class="text-xs text-text-secondary font-mono bg-[#111a22] px-2 py-1 rounded border border-border-dark group-hover/copy:text-white transition-colors">iqn.2023-10.com.vtl:arch01</code>
|
||||
<span class="material-symbols-outlined text-text-secondary text-sm opacity-0 group-hover/copy:opacity-100 transition-opacity">content_copy</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<button class="p-2 text-text-secondary hover:text-white hover:bg-[#324d67] rounded-lg transition-colors" title="Manage Tapes">
|
||||
<span class="material-symbols-outlined text-xl">cable</span>
|
||||
</button>
|
||||
<button class="p-2 text-text-secondary hover:text-primary hover:bg-primary/10 rounded-lg transition-colors" title="Edit Configuration">
|
||||
<span class="material-symbols-outlined text-xl">edit</span>
|
||||
</button>
|
||||
<button class="p-2 text-text-secondary hover:text-red-400 hover:bg-red-400/10 rounded-lg transition-colors" title="Delete Library">
|
||||
<span class="material-symbols-outlined text-xl">delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 2 -->
|
||||
<tr class="group hover:bg-[#233342] transition-colors">
|
||||
<td class="py-4 px-6">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-offset-background-dark focus:ring-primary h-4 w-4" type="checkbox"/>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="size-8 rounded bg-blue-900/30 flex items-center justify-center text-primary">
|
||||
<span class="material-symbols-outlined text-lg">shelves</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-white text-sm font-bold">VTL_Prod_Daily</p>
|
||||
<p class="text-text-secondary text-xs">ID: 002</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium bg-blue-500/10 text-blue-400 border border-blue-500/20">
|
||||
<span class="material-symbols-outlined text-[10px] animate-spin">refresh</span>
|
||||
Writing
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<p class="text-white text-sm font-medium">Quantum i3</p>
|
||||
<p class="text-text-secondary text-xs">LTO-8 • 4 Drives</p>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-text-secondary text-lg">album</span>
|
||||
<span class="text-white text-sm">12 / 50</span>
|
||||
</div>
|
||||
<div class="w-24 bg-[#111a22] rounded-full h-1 mt-1.5">
|
||||
<div class="bg-blue-500 h-1 rounded-full" style="width: 24%"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-2 group/copy cursor-pointer">
|
||||
<code class="text-xs text-text-secondary font-mono bg-[#111a22] px-2 py-1 rounded border border-border-dark group-hover/copy:text-white transition-colors">iqn.2023-10.com.vtl:prod02</code>
|
||||
<span class="material-symbols-outlined text-text-secondary text-sm opacity-0 group-hover/copy:opacity-100 transition-opacity">content_copy</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<button class="p-2 text-text-secondary hover:text-white hover:bg-[#324d67] rounded-lg transition-colors" title="Manage Tapes">
|
||||
<span class="material-symbols-outlined text-xl">cable</span>
|
||||
</button>
|
||||
<button class="p-2 text-text-secondary hover:text-primary hover:bg-primary/10 rounded-lg transition-colors" title="Edit Configuration">
|
||||
<span class="material-symbols-outlined text-xl">edit</span>
|
||||
</button>
|
||||
<button class="p-2 text-text-secondary hover:text-red-400 hover:bg-red-400/10 rounded-lg transition-colors" title="Delete Library">
|
||||
<span class="material-symbols-outlined text-xl">delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Row 3 -->
|
||||
<tr class="group hover:bg-[#233342] transition-colors">
|
||||
<td class="py-4 px-6">
|
||||
<input class="rounded border-border-dark bg-[#111a22] text-primary focus:ring-offset-background-dark focus:ring-primary h-4 w-4" type="checkbox"/>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="size-8 rounded bg-gray-700/30 flex items-center justify-center text-gray-400">
|
||||
<span class="material-symbols-outlined text-lg">shelves</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-white text-sm font-bold">VTL_Legacy_03</p>
|
||||
<p class="text-text-secondary text-xs">ID: 003</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium bg-gray-500/10 text-gray-400 border border-gray-500/20">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-gray-500"></span>
|
||||
Offline
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<p class="text-white text-sm font-medium">IBM TS3100</p>
|
||||
<p class="text-text-secondary text-xs">LTO-5 • 1 Drive</p>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-text-secondary text-lg">album</span>
|
||||
<span class="text-white text-sm">9 / 10</span>
|
||||
</div>
|
||||
<div class="w-24 bg-[#111a22] rounded-full h-1 mt-1.5">
|
||||
<div class="bg-gray-500 h-1 rounded-full" style="width: 90%"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6">
|
||||
<div class="flex items-center gap-2 group/copy cursor-pointer">
|
||||
<code class="text-xs text-text-secondary font-mono bg-[#111a22] px-2 py-1 rounded border border-border-dark group-hover/copy:text-white transition-colors">iqn.2023-10.com.vtl:leg03</code>
|
||||
<span class="material-symbols-outlined text-text-secondary text-sm opacity-0 group-hover/copy:opacity-100 transition-opacity">content_copy</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<div class="flex items-center justify-end gap-1">
|
||||
<button class="p-2 text-text-secondary hover:text-white hover:bg-[#324d67] rounded-lg transition-colors" title="Power On">
|
||||
<span class="material-symbols-outlined text-xl">power_settings_new</span>
|
||||
</button>
|
||||
<button class="p-2 text-text-secondary hover:text-primary hover:bg-primary/10 rounded-lg transition-colors" title="Edit Configuration">
|
||||
<span class="material-symbols-outlined text-xl">edit</span>
|
||||
</button>
|
||||
<button class="p-2 text-text-secondary hover:text-red-400 hover:bg-red-400/10 rounded-lg transition-colors" title="Delete Library">
|
||||
<span class="material-symbols-outlined text-xl">delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Pagination -->
|
||||
<div class="px-6 py-4 border-t border-border-dark flex items-center justify-between bg-[#1c2834]">
|
||||
<p class="text-text-secondary text-sm">Showing <span class="text-white font-medium">1-3</span> of <span class="text-white font-medium">3</span> libraries</p>
|
||||
<div class="flex gap-2">
|
||||
<button class="px-3 py-1.5 rounded-lg border border-border-dark bg-[#111a22] text-text-secondary text-sm hover:text-white disabled:opacity-50">Previous</button>
|
||||
<button class="px-3 py-1.5 rounded-lg border border-border-dark bg-[#111a22] text-text-secondary text-sm hover:text-white disabled:opacity-50">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- "Tape Detail" Drawer Simulation (Showing detailed context for selected item) -->
|
||||
<!-- Positioned absolute to simulate a slide-up panel or just a section on the page. Using a bottom panel style here. -->
|
||||
<div class="bg-surface-dark border-t border-border-dark p-6 absolute bottom-0 w-full transform translate-y-full transition-transform lg:relative lg:translate-y-0 lg:border-t lg:border-border-dark lg:h-auto z-30 shadow-2xl shadow-black">
|
||||
<div class="max-w-[1400px] mx-auto">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="material-symbols-outlined text-primary text-2xl">cable</span>
|
||||
<div>
|
||||
<h3 class="text-white text-lg font-bold">Tape Management: VTL_Arch_01</h3>
|
||||
<p class="text-text-secondary text-sm">Manage virtual cartridges, import/export slots, and barcodes.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-3">
|
||||
<button class="px-3 py-2 bg-[#111a22] border border-border-dark rounded-lg text-text-secondary hover:text-white text-sm font-medium transition-colors">
|
||||
Bulk Format
|
||||
</button>
|
||||
<button class="px-3 py-2 bg-primary hover:bg-blue-600 rounded-lg text-white text-sm font-bold transition-colors flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-lg">add</span>
|
||||
Add Tapes
|
||||
</button>
|
||||
<button class="lg:hidden p-2 text-text-secondary hover:text-white">
|
||||
<span class="material-symbols-outlined">close</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
|
||||
<!-- Tape Item (Loaded) -->
|
||||
<div class="p-3 bg-[#111a22] rounded border border-green-500/30 flex flex-col gap-2 relative group hover:border-green-500 transition-colors cursor-pointer">
|
||||
<div class="flex justify-between items-start">
|
||||
<span class="material-symbols-outlined text-green-500 text-xl">album</span>
|
||||
<span class="text-[10px] uppercase font-bold text-text-secondary bg-[#1c2834] px-1 rounded">Slot 1</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-white text-xs font-mono font-bold">ARC001L7</p>
|
||||
<p class="text-text-secondary text-[10px]">12.0 TB / 12.0 TB</p>
|
||||
</div>
|
||||
<div class="absolute inset-0 bg-black/60 hidden group-hover:flex items-center justify-center gap-2 backdrop-blur-[1px] rounded">
|
||||
<span class="material-symbols-outlined text-white hover:text-primary text-lg">eject</span>
|
||||
<span class="material-symbols-outlined text-white hover:text-red-400 text-lg">delete</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tape Item (Loaded) -->
|
||||
<div class="p-3 bg-[#111a22] rounded border border-border-dark flex flex-col gap-2 relative group hover:border-primary transition-colors cursor-pointer">
|
||||
<div class="flex justify-between items-start">
|
||||
<span class="material-symbols-outlined text-text-secondary text-xl">album</span>
|
||||
<span class="text-[10px] uppercase font-bold text-text-secondary bg-[#1c2834] px-1 rounded">Slot 2</span>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-white text-xs font-mono font-bold">ARC002L7</p>
|
||||
<p class="text-text-secondary text-[10px]">Empty / 12.0 TB</p>
|
||||
</div>
|
||||
<div class="absolute inset-0 bg-black/60 hidden group-hover:flex items-center justify-center gap-2 backdrop-blur-[1px] rounded">
|
||||
<span class="material-symbols-outlined text-white hover:text-primary text-lg">upload</span>
|
||||
<span class="material-symbols-outlined text-white hover:text-red-400 text-lg">delete</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tape Item (Empty Slot) -->
|
||||
<div class="p-3 bg-[#111a22] rounded border border-dashed border-border-dark flex flex-col gap-2 justify-center items-center h-20 opacity-60 hover:opacity-100 hover:bg-[#1c2834] transition-all cursor-pointer">
|
||||
<span class="material-symbols-outlined text-text-secondary">add_circle</span>
|
||||
<span class="text-[10px] text-text-secondary uppercase font-bold">Empty Slot 3</span>
|
||||
</div>
|
||||
<!-- Tape Item (Empty Slot) -->
|
||||
<div class="p-3 bg-[#111a22] rounded border border-dashed border-border-dark flex flex-col gap-2 justify-center items-center h-20 opacity-60 hover:opacity-100 hover:bg-[#1c2834] transition-all cursor-pointer">
|
||||
<span class="material-symbols-outlined text-text-secondary">add_circle</span>
|
||||
<span class="text-[10px] text-text-secondary uppercase font-bold">Empty Slot 4</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body></html>
|
||||
BIN
src/web/vtl-management.png
Normal file
|
After Width: | Height: | Size: 292 KiB |