188 lines
9.9 KiB
HTML
188 lines
9.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>DB Restore Tool</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<style>
|
|
.spinner { animation: spin 1s linear infinite; }
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-100 min-h-screen">
|
|
<div class="container mx-auto px-4 py-8 max-w-6xl">
|
|
<!-- Header -->
|
|
<header class="mb-8">
|
|
<h1 class="text-3xl font-bold text-gray-800">Database Restore Tool</h1>
|
|
<p class="text-gray-600">Browse and restore database backups from remote server</p>
|
|
</header>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<!-- Connection Panel -->
|
|
<div class="lg:col-span-1">
|
|
<div class="bg-white rounded-lg shadow p-6" id="connection-panel">
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center">
|
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 14v3m4-3v3m4-3v3M3 21h18M3 10h18M3 7l9-4 9 4M4 10h16v11H4V10z"/>
|
|
</svg>
|
|
Connection
|
|
</h2>
|
|
|
|
<div id="connection-status" class="mb-4 p-3 rounded hidden"></div>
|
|
|
|
<form id="connect-form">
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Server</label>
|
|
<input type="text" value="{{ scp_host }}" disabled
|
|
class="w-full px-3 py-2 border rounded bg-gray-50 text-gray-600">
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Username</label>
|
|
<input type="text" value="{{ scp_username }}" disabled
|
|
class="w-full px-3 py-2 border rounded bg-gray-50 text-gray-600">
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Authentication</label>
|
|
<select id="auth-type" class="w-full px-3 py-2 border rounded">
|
|
<option value="password">Password</option>
|
|
<option value="key">SSH Key</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Password Auth -->
|
|
<div id="password-auth">
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Password</label>
|
|
<input type="password" id="password" placeholder="Enter password"
|
|
class="w-full px-3 py-2 border rounded focus:ring-2 focus:ring-blue-500">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Key Auth -->
|
|
<div id="key-auth" class="hidden">
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">SSH Key</label>
|
|
<select id="key-file" class="w-full px-3 py-2 border rounded">
|
|
<option value="">Select a key...</option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Key Passphrase (optional)</label>
|
|
<input type="password" id="key-passphrase" placeholder="Enter passphrase if required"
|
|
class="w-full px-3 py-2 border rounded focus:ring-2 focus:ring-blue-500">
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" id="connect-btn"
|
|
class="w-full bg-blue-600 text-white py-2 px-4 rounded hover:bg-blue-700 transition">
|
|
Connect
|
|
</button>
|
|
|
|
<button type="button" id="disconnect-btn"
|
|
class="w-full bg-red-600 text-white py-2 px-4 rounded hover:bg-red-700 transition hidden mt-2">
|
|
Disconnect
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Restore Panel -->
|
|
<div class="bg-white rounded-lg shadow p-6 mt-6" id="restore-panel">
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center">
|
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4"/>
|
|
</svg>
|
|
Restore
|
|
</h2>
|
|
|
|
<div id="selected-file-info" class="mb-4 p-3 bg-gray-50 rounded">
|
|
<p class="text-gray-500 text-sm">No file selected</p>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Target Database</label>
|
|
<select id="target-db" class="w-full px-3 py-2 border rounded">
|
|
{% for db in databases %}
|
|
<option value="{{ db }}">{{ db }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
|
|
<div class="bg-yellow-50 border border-yellow-200 rounded p-3 mb-4">
|
|
<p class="text-yellow-800 text-sm">
|
|
<strong>Warning:</strong> This will DROP all tables in the selected database before restoring!
|
|
</p>
|
|
</div>
|
|
|
|
<button type="button" id="restore-btn" disabled
|
|
class="w-full bg-green-600 text-white py-2 px-4 rounded hover:bg-green-700 transition disabled:bg-gray-400 disabled:cursor-not-allowed">
|
|
Start Restore
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- File Browser Panel -->
|
|
<div class="lg:col-span-2">
|
|
<div class="bg-white rounded-lg shadow p-6">
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center">
|
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/>
|
|
</svg>
|
|
Remote Browser
|
|
</h2>
|
|
|
|
<!-- Breadcrumb -->
|
|
<div id="breadcrumb" class="mb-4 flex items-center text-sm text-gray-600 overflow-x-auto">
|
|
<span class="text-gray-400">Not connected</span>
|
|
</div>
|
|
|
|
<!-- File List -->
|
|
<div id="file-browser" class="border rounded min-h-[400px] max-h-[600px] overflow-y-auto">
|
|
<div class="p-8 text-center text-gray-400">
|
|
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 14v3m4-3v3m4-3v3M3 21h18M3 10h18M3 7l9-4 9 4M4 10h16v11H4V10z"/>
|
|
</svg>
|
|
<p>Connect to browse remote files</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Panel -->
|
|
<div id="progress-panel" class="bg-white rounded-lg shadow p-6 mt-6 hidden">
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center">
|
|
<svg class="w-5 h-5 mr-2 spinner" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
|
</svg>
|
|
Restore Progress
|
|
</h2>
|
|
|
|
<div class="mb-4">
|
|
<div class="flex justify-between text-sm mb-1">
|
|
<span id="progress-status">Initializing...</span>
|
|
<span id="progress-percent">0%</span>
|
|
</div>
|
|
<div class="w-full bg-gray-200 rounded-full h-4">
|
|
<div id="progress-bar" class="bg-blue-600 h-4 rounded-full transition-all duration-300" style="width: 0"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="progress-details" class="text-sm text-gray-600">
|
|
<p id="progress-message">Starting...</p>
|
|
<p id="progress-elapsed" class="mt-1"></p>
|
|
</div>
|
|
|
|
<button type="button" id="cancel-btn"
|
|
class="mt-4 w-full bg-red-600 text-white py-2 px-4 rounded hover:bg-red-700 transition hidden">
|
|
Cancel Restore
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="{{ url_for('static', filename='app.js') }}"></script>
|
|
</body>
|
|
</html>
|