File app-comprehensive.html of Package PersistenceOS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PersistenceOS - Comprehensive Test (All Phases)</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Load ALL modules from all phases -->
<script src="js/auth-v2.js?v=phase2"></script>
<script src="js/core-utils-v2.js?v=phase1"></script>
<script src="js/dashboard-v2.js?v=phase3"></script>
<script src="js/vms-v2.js?v=phase4"></script>
<script src="js/storage-v2.js?v=phase4"></script>
<script src="js/network-v2.js?v=phase4"></script>
<script src="js/snapshots-v2.js?v=phase4"></script>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f7fa; color: #333; }
.app-container { display: flex; height: 100vh; }
.sidebar { width: 250px; background: linear-gradient(135deg, #0066cc 0%, #004499 100%); color: white; }
.sidebar-header { padding: 1.5rem; border-bottom: 1px solid rgba(255,255,255,0.1); }
.logo-container h1 { font-size: 20px; font-weight: 300; }
.logo-icon { margin-top: 0.5rem; font-size: 24px; }
.sidebar-nav { flex: 1; padding: 1rem 0; }
.nav-list { list-style: none; }
.nav-item { margin-bottom: 0.5rem; }
.nav-link {
display: flex;
align-items: center;
padding: 0.75rem 1.5rem;
color: rgba(255,255,255,0.8);
text-decoration: none;
border-radius: 6px;
margin: 0 1rem;
transition: all 0.2s;
}
.nav-link:hover, .nav-link.active {
background: rgba(255,255,255,0.1);
color: white;
}
.nav-link i { margin-right: 0.75rem; width: 16px; }
.main-content { flex: 1; display: flex; flex-direction: column; }
.header { padding: 1.5rem 2rem; background: white; border-bottom: 1px solid #e9ecef; }
.header h2 { color: #0066cc; font-weight: 500; }
.content { flex: 1; padding: 2rem; overflow-y: auto; }
/* Phase indicator */
.phase-indicator {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1rem 2rem;
margin-bottom: 2rem;
border-radius: 12px;
text-align: center;
}
.phase-indicator h3 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
/* Dashboard cards */
.dashboard-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.dashboard-card {
background: white;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
border-left: 4px solid #0066cc;
}
.card-header {
display: flex;
align-items: center;
margin-bottom: 1rem;
}
.card-icon {
font-size: 2rem;
margin-right: 1rem;
color: #0066cc;
}
.card-title {
font-size: 1.1rem;
font-weight: 600;
color: #333;
}
.card-value {
font-size: 2rem;
font-weight: 700;
color: #0066cc;
margin-bottom: 0.5rem;
}
.card-subtitle {
color: #666;
font-size: 0.9rem;
}
/* Data tables */
.data-table {
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
margin-bottom: 2rem;
}
.table-header {
background: #f8f9fa;
padding: 1rem 1.5rem;
border-bottom: 1px solid #e9ecef;
}
.table-title {
font-size: 1.2rem;
font-weight: 600;
color: #333;
}
.table-content {
padding: 1.5rem;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
text-align: left;
padding: 0.75rem;
border-bottom: 1px solid #e9ecef;
}
th {
background: #f8f9fa;
font-weight: 600;
color: #333;
}
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
}
.status-running { background: #d4edda; color: #155724; }
.status-stopped { background: #f8d7da; color: #721c24; }
.status-healthy { background: #d1ecf1; color: #0c5460; }
.btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 6px;
font-size: 0.9rem;
cursor: pointer;
margin-right: 0.5rem;
transition: all 0.2s;
}
.btn-primary { background: #0066cc; color: white; }
.btn-success { background: #28a745; color: white; }
.btn-danger { background: #dc3545; color: white; }
.btn-warning { background: #ffc107; color: #212529; }
.btn:hover { transform: translateY(-1px); opacity: 0.9; }
/* Module status */
.module-status {
background: white;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
margin-bottom: 2rem;
}
.module-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
.module-item {
display: flex;
align-items: center;
padding: 0.75rem;
background: #f8f9fa;
border-radius: 8px;
}
.module-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 0.75rem;
}
.module-loaded { background: #28a745; }
.module-error { background: #dc3545; }
.hidden { display: none; }
</style>
</head>
<body>
<div id="app" class="app-container">
<!-- Sidebar -->
<div class="sidebar">
<div class="sidebar-header">
<div class="logo-container">
<h1>PersistenceOS</h1>
<div class="logo-icon">๐ง</div>
</div>
</div>
<nav class="sidebar-nav">
<ul class="nav-list">
<li class="nav-item">
<a href="#" class="nav-link active" @click="setActiveSection('overview')">
<i class="fas fa-tachometer-alt"></i>
Overview
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" @click="setActiveSection('virtualization')">
<i class="fas fa-server"></i>
Virtual Machines
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" @click="setActiveSection('storage')">
<i class="fas fa-hdd"></i>
Storage
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" @click="setActiveSection('network')">
<i class="fas fa-network-wired"></i>
Network
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" @click="setActiveSection('snapshots')">
<i class="fas fa-camera"></i>
Snapshots
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link" @click="setActiveSection('modules')">
<i class="fas fa-puzzle-piece"></i>
Module Status
</a>
</li>
</ul>
</nav>
</div>
<!-- Main Content -->
<div class="main-content">
<div class="header">
<h2>{{ getSectionTitle() }}</h2>
</div>
<div class="content">
<!-- Phase Indicator -->
<div class="phase-indicator">
<h3>๐งช Comprehensive Test - All Phases Integrated</h3>
<p>Testing all 7 modules working together in a single flowing interface</p>
</div>
<!-- Overview Section -->
<div v-show="activeSection === 'overview'">
<div class="dashboard-grid">
<div class="dashboard-card" v-for="stat in dashboardStats" :key="stat.title">
<div class="card-header">
<div class="card-icon">
<i :class="stat.icon"></i>
</div>
<div>
<div class="card-title">{{ stat.title }}</div>
</div>
</div>
<div class="card-value">{{ stat.value }}</div>
<div class="card-subtitle">{{ stat.subtitle }}</div>
</div>
</div>
</div>
<!-- Virtual Machines Section -->
<div v-show="activeSection === 'virtualization'" class="data-table">
<div class="table-header">
<div class="table-title">Virtual Machines</div>
</div>
<div class="table-content">
<table>
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>CPU</th>
<th>Memory</th>
<th>IP Address</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="vm in virtualMachines" :key="vm.name">
<td>{{ vm.name }}</td>
<td><span :class="'status-badge status-' + vm.status.toLowerCase()">{{ vm.status }}</span></td>
<td>{{ vm.cpu }}</td>
<td>{{ vm.memory }}</td>
<td>{{ vm.ip }}</td>
<td>
<button class="btn btn-success" @click="startVM(vm.name)">Start</button>
<button class="btn btn-warning" @click="stopVM(vm.name)">Stop</button>
<button class="btn btn-danger" @click="deleteVM(vm.name)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Storage Section -->
<div v-show="activeSection === 'storage'" class="data-table">
<div class="table-header">
<div class="table-title">Storage Pools</div>
</div>
<div class="table-content">
<table>
<thead>
<tr>
<th>Pool Name</th>
<th>Type</th>
<th>Size</th>
<th>Used</th>
<th>Available</th>
<th>Health</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="pool in storagePools" :key="pool.name">
<td>{{ pool.name }}</td>
<td>{{ pool.type }}</td>
<td>{{ pool.size }}</td>
<td>{{ pool.used }}</td>
<td>{{ pool.available }}</td>
<td><span :class="'status-badge status-' + pool.health.toLowerCase()">{{ pool.health }}</span></td>
<td>
<button class="btn btn-primary" @click="managePool(pool.name)">Manage</button>
<button class="btn btn-warning" @click="scrubPool(pool.name)">Scrub</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Network Section -->
<div v-show="activeSection === 'network'" class="data-table">
<div class="table-header">
<div class="table-title">Network Interfaces</div>
</div>
<div class="table-content">
<table>
<thead>
<tr>
<th>Interface</th>
<th>Status</th>
<th>IP Address</th>
<th>RX Rate</th>
<th>TX Rate</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="iface in networkInterfaces" :key="iface.name">
<td>{{ iface.name }}</td>
<td><span :class="'status-badge status-' + iface.status.toLowerCase()">{{ iface.status }}</span></td>
<td>{{ iface.ip }}</td>
<td>{{ iface.rxRate }}</td>
<td>{{ iface.txRate }}</td>
<td>
<button class="btn btn-primary" @click="configureInterface(iface.name)">Configure</button>
<button class="btn btn-warning" @click="restartInterface(iface.name)">Restart</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Snapshots Section -->
<div v-show="activeSection === 'snapshots'" class="data-table">
<div class="table-header">
<div class="table-title">System Snapshots</div>
</div>
<div class="table-content">
<table>
<thead>
<tr>
<th>Snapshot</th>
<th>Type</th>
<th>Created</th>
<th>Size</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="snapshot in systemSnapshots" :key="snapshot.name">
<td>{{ snapshot.name }}</td>
<td>{{ snapshot.type }}</td>
<td>{{ snapshot.created }}</td>
<td>{{ snapshot.size }}</td>
<td>{{ snapshot.description }}</td>
<td>
<button class="btn btn-success" @click="restoreSnapshot(snapshot.name)">Restore</button>
<button class="btn btn-danger" @click="deleteSnapshot(snapshot.name)">Delete</button>
</td>
</tr>
</tbody>
</table>
<div style="margin-top: 1rem;">
<button class="btn btn-primary" @click="createSnapshot()">Create New Snapshot</button>
<button class="btn btn-warning" @click="scheduleSnapshots()">Schedule Snapshots</button>
</div>
</div>
</div>
<!-- Module Status Section -->
<div v-show="activeSection === 'modules'" class="module-status">
<h3 style="margin-bottom: 1.5rem;">Module Loading Status</h3>
<div class="module-list">
<div class="module-item" v-for="module in moduleStatus" :key="module.name">
<div :class="'module-indicator ' + (module.loaded ? 'module-loaded' : 'module-error')"></div>
<div>
<div style="font-weight: 600;">{{ module.name }}</div>
<div style="font-size: 0.8rem; color: #666;">{{ module.status }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
activeSection: 'overview',
dashboardStats: [
{ title: 'Virtual Machines', value: '5', subtitle: '3 running, 2 stopped', icon: 'fas fa-server' },
{ title: 'Storage Pools', value: '2', subtitle: '1.2TB total capacity', icon: 'fas fa-hdd' },
{ title: 'Network Interfaces', value: '3', subtitle: 'All interfaces active', icon: 'fas fa-network-wired' },
{ title: 'System Snapshots', value: '8', subtitle: 'Last: 2 hours ago', icon: 'fas fa-camera' },
{ title: 'System Health', value: '98%', subtitle: 'All systems operational', icon: 'fas fa-heart' }
],
virtualMachines: [
{ name: 'ubuntu-server-01', status: 'Running', cpu: '2 vCPU', memory: '4GB', ip: '192.168.1.100' },
{ name: 'windows-10-dev', status: 'Running', cpu: '4 vCPU', memory: '8GB', ip: '192.168.1.101' },
{ name: 'centos-web', status: 'Running', cpu: '2 vCPU', memory: '2GB', ip: '192.168.1.102' },
{ name: 'debian-db', status: 'Stopped', cpu: '2 vCPU', memory: '6GB', ip: '-' },
{ name: 'test-vm', status: 'Stopped', cpu: '1 vCPU', memory: '1GB', ip: '-' }
],
storagePools: [
{ name: 'system', type: 'BTRFS', size: '500GB', used: '180GB', available: '320GB', health: 'Healthy' },
{ name: 'vm-storage', type: 'XFS', size: '1TB', used: '650GB', available: '350GB', health: 'Healthy' }
],
networkInterfaces: [
{ name: 'eth0', status: 'Running', ip: '192.168.1.10', rxRate: '125 MB/s', txRate: '89 MB/s' },
{ name: 'virbr0', status: 'Running', ip: '192.168.122.1', rxRate: '45 MB/s', txRate: '32 MB/s' },
{ name: 'lo', status: 'Running', ip: '127.0.0.1', rxRate: '0 MB/s', txRate: '0 MB/s' }
],
systemSnapshots: [
{ name: 'snapshot-20250117-1400', type: 'System', created: '2025-01-17 14:00', size: '2.1GB', description: 'Pre-update snapshot' },
{ name: 'snapshot-20250117-1200', type: 'System', created: '2025-01-17 12:00', size: '2.0GB', description: 'Scheduled snapshot' },
{ name: 'snapshot-20250117-1000', type: 'System', created: '2025-01-17 10:00', size: '1.9GB', description: 'Scheduled snapshot' },
{ name: 'snapshot-20250117-0800', type: 'System', created: '2025-01-17 08:00', size: '1.9GB', description: 'Scheduled snapshot' },
{ name: 'vm-backup-20250117', type: 'VM', created: '2025-01-17 06:00', size: '15.2GB', description: 'VM backup snapshot' }
],
moduleStatus: [
{ name: 'Authentication Module v2', loaded: true, status: 'Loaded successfully' },
{ name: 'Core Utilities Module v2', loaded: true, status: 'Loaded successfully' },
{ name: 'Dashboard Module v2', loaded: true, status: 'Loaded successfully' },
{ name: 'VMs Module v2', loaded: true, status: 'Loaded successfully' },
{ name: 'Storage Module v2', loaded: true, status: 'Loaded successfully' },
{ name: 'Network Module v2', loaded: true, status: 'Loaded successfully' },
{ name: 'Snapshots Module v2', loaded: true, status: 'Loaded successfully' }
]
}
},
methods: {
setActiveSection(section) {
this.activeSection = section;
// Update nav links
document.querySelectorAll('.nav-link').forEach(link => {
link.classList.remove('active');
});
event.target.classList.add('active');
},
getSectionTitle() {
const titles = {
'overview': 'System Overview',
'virtualization': 'Virtual Machine Management',
'storage': 'Storage Management',
'network': 'Network Configuration',
'snapshots': 'Snapshot Management',
'modules': 'Module Status'
};
return titles[this.activeSection] || 'PersistenceOS Dashboard';
},
// VM Actions
startVM(vmName) {
this.showNotification(`Starting VM: ${vmName}`, 'success');
},
stopVM(vmName) {
this.showNotification(`Stopping VM: ${vmName}`, 'warning');
},
deleteVM(vmName) {
this.showNotification(`Deleting VM: ${vmName}`, 'error');
},
// Storage Actions
managePool(poolName) {
this.showNotification(`Managing storage pool: ${poolName}`, 'info');
},
scrubPool(poolName) {
this.showNotification(`Starting scrub on pool: ${poolName}`, 'warning');
},
// Network Actions
configureInterface(ifaceName) {
this.showNotification(`Configuring interface: ${ifaceName}`, 'info');
},
restartInterface(ifaceName) {
this.showNotification(`Restarting interface: ${ifaceName}`, 'warning');
},
// Snapshot Actions
createSnapshot() {
this.showNotification('Creating new system snapshot...', 'success');
},
scheduleSnapshots() {
this.showNotification('Opening snapshot scheduler...', 'info');
},
restoreSnapshot(snapshotName) {
this.showNotification(`Restoring snapshot: ${snapshotName}`, 'warning');
},
deleteSnapshot(snapshotName) {
this.showNotification(`Deleting snapshot: ${snapshotName}`, 'error');
},
showNotification(message, type = 'info') {
if (window.PersistenceCore && window.PersistenceCore.showNotification) {
window.PersistenceCore.showNotification(message, type);
} else {
alert(message);
}
}
},
mounted() {
console.log('๐งช Comprehensive Test Application initialized');
console.log('๐ Auth Module:', typeof window.PersistenceAuth);
console.log('๐ ๏ธ Core Utils:', typeof window.PersistenceCore);
console.log('๐ Dashboard Module:', typeof window.PersistenceDashboard);
console.log('๐ฅ๏ธ VMs Module:', typeof window.PersistenceVMs);
console.log('๐พ Storage Module:', typeof window.PersistenceStorage);
console.log('๐ Network Module:', typeof window.PersistenceNetwork);
console.log('๐ธ Snapshots Module:', typeof window.PersistenceSnapshots);
// Update module status based on actual loading
this.moduleStatus.forEach(module => {
const moduleName = module.name.toLowerCase();
if (moduleName.includes('auth') && typeof window.PersistenceAuth === 'undefined') {
module.loaded = false;
module.status = 'Failed to load';
}
if (moduleName.includes('core') && typeof window.PersistenceCore === 'undefined') {
module.loaded = false;
module.status = 'Failed to load';
}
if (moduleName.includes('dashboard') && typeof window.PersistenceDashboard === 'undefined') {
module.loaded = false;
module.status = 'Failed to load';
}
if (moduleName.includes('vms') && typeof window.PersistenceVMs === 'undefined') {
module.loaded = false;
module.status = 'Failed to load';
}
if (moduleName.includes('storage') && typeof window.PersistenceStorage === 'undefined') {
module.loaded = false;
module.status = 'Failed to load';
}
if (moduleName.includes('network') && typeof window.PersistenceNetwork === 'undefined') {
module.loaded = false;
module.status = 'Failed to load';
}
if (moduleName.includes('snapshots') && typeof window.PersistenceSnapshots === 'undefined') {
module.loaded = false;
module.status = 'Failed to load';
}
});
console.log('โ
Comprehensive Test App mounted successfully - All modules integrated');
}
}).mount('#app');
</script>
</body>
</html>