Files
llm-monitor/app/web/templates/index.html
T
2026-04-25 16:13:41 +02:00

158 lines
8.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LLM Monitor - Ollama Dashboard</title>
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="manifest" href="/manifest.webmanifest">
<meta name="theme-color" content="#111827">
<meta name="application-name" content="LLM Monitor">
<meta name="description" content="Monitor available and running Ollama models.">
<!-- Tailwind CSS (compiled for production) -->
<link rel="stylesheet" href="/static/css/output.css">
<style>
@keyframes spin {
to { transform: rotate(360deg); }
}
.animate-spin {
animation: spin 1s linear infinite;
}
.modal-body {
max-height: 80vh;
overflow-y: auto;
padding-right: 10px;
scrollbar-width: thin;
scrollbar-color: #8b5cf6 #1f2937;
}
.modal-body::-webkit-scrollbar {
width: 8px;
}
.modal-body::-webkit-scrollbar-track {
background: #1f2937;
border-radius: 4px;
}
.modal-body::-webkit-scrollbar-thumb {
background: #8b5cf6;
border-radius: 4px;
}
</style>
</head>
<body class="bg-gray-900 text-white">
<div class="min-h-screen flex flex-col">
<!-- Header -->
<header class="bg-gray-800 border-b border-gray-700 sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 py-6">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-gradient-to-br from-purple-500 to-pink-500 rounded-lg flex items-center justify-center font-bold text-lg">
🦙
</div>
<h1 class="text-2xl font-bold">LLM Monitor</h1>
</div>
<div class="flex items-center gap-4">
<a id="servers-link" href="/servers" class="text-sm bg-gray-700 hover:bg-gray-600 px-3 py-2 rounded-lg transition">Servers</a>
<a id="running-link" href="/models-running" class="text-sm bg-gray-700 hover:bg-gray-600 px-3 py-2 rounded-lg transition">Running Models</a>
<span id="active-server-label" class="hidden text-xs text-gray-300 bg-gray-700 px-3 py-2 rounded-lg"></span>
<div id="health-status" class="flex items-center gap-2">
<div id="status-indicator" class="w-3 h-3 bg-gray-500 rounded-full"></div>
<span id="status-text" class="text-sm text-gray-400">Checking...</span>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1">
<div class="max-w-7xl mx-auto px-4 py-8">
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-gray-800 rounded-lg p-6 border border-gray-700">
<div class="text-gray-400 text-sm font-medium">Loaded Models</div>
<div id="models-count" class="text-4xl font-bold mt-2">-</div>
</div>
<div class="bg-gray-800 rounded-lg p-6 border border-gray-700">
<div class="text-gray-400 text-sm font-medium">Total Size</div>
<div id="total-size" class="text-4xl font-bold mt-2">-</div>
</div>
<div class="bg-gray-800 rounded-lg p-6 border border-gray-700">
<div class="text-gray-400 text-sm font-medium">Ollama Status</div>
<div id="ollama-status" class="text-4xl font-bold mt-2">-</div>
</div>
</div>
<!-- Models Section -->
<div class="bg-gray-800 rounded-lg border border-gray-700 p-6">
<div class="flex items-center justify-between mb-6">
<div>
<h2 class="text-xl font-bold">Available Models</h2>
<p class="text-xs text-gray-400 mt-1">Hover or click a card to open the details modal.</p>
<p id="cache-mode-indicator" class="hidden text-xs text-amber-300 mt-2">Model details are loaded on demand to keep device storage usage low.</p>
</div>
<button id="refresh-btn" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-lg text-sm font-medium transition">
Refresh
</button>
</div>
<!-- Models List -->
<div id="models-container" class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
<div class="text-center py-8">
<div class="animate-spin inline-block w-8 h-8 border-4 border-gray-600 border-t-purple-500 rounded-full"></div>
<p class="text-gray-400 mt-4">Loading models...</p>
</div>
</div>
</div>
<!-- API Documentation Section -->
<div class="mt-8 bg-blue-900 bg-opacity-20 border border-blue-700 rounded-lg p-6">
<h3 class="text-lg font-bold mb-4">API Documentation</h3>
<p class="text-gray-300 mb-4">The API is documented and testable from:</p>
<div class="flex gap-3 flex-wrap">
<a href="/docs" target="_blank" class="inline-block bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg text-sm font-medium transition">
Swagger UI
</a>
<a href="/redoc" target="_blank" class="inline-block bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg text-sm font-medium transition">
ReDoc
</a>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="bg-gray-800 border-t border-gray-700 mt-12">
<div class="max-w-7xl mx-auto px-4 py-6 text-center text-gray-400 text-sm">
<p>LLM Monitor v1.0.0 • Built by <a href="https://lucasacchi.net" target="_blank" class="text-purple-400 hover:text-purple-300">LucaSacchi.Net</a></p>
</div>
</footer>
</div>
<!-- Model Show Details Modal -->
<div id="model-details-modal" class="hidden fixed inset-0 z-50 items-center justify-center" aria-hidden="true">
<div id="model-details-backdrop" class="absolute inset-0 bg-black/70"></div>
<div id="model-details-dialog" class="relative w-full min-h-screen items-center justify-center p-4">
<div id="model-details-section" class="w-full max-w-4xl bg-gray-800 rounded-lg border border-gray-700 p-6 shadow-xl">
<div class="flex items-center justify-between mb-4">
<div>
<h3 class="text-lg font-bold">Model Details</h3>
<span id="model-details-name" class="text-sm text-purple-300 font-medium"></span>
</div>
<button id="model-details-close" type="button" class="text-gray-300 hover:text-white text-2xl leading-none px-2" aria-label="Close modal">×</button>
</div>
<div class="modal-body">
<pre id="model-details-content" class="bg-gray-900 text-gray-200 text-xs p-4 rounded-lg whitespace-pre-wrap"></pre>
</div>
</div>
</div>
</div>
<!-- LLM Monitor Application -->
<!-- Web Worker for background data sync -->
<!-- localStorage for client-side persistence -->
<script src="/static/js/server-config.js"></script>
<script src="/static/js/app.js"></script>
<script src="/static/js/pwa-register.js"></script>
</body>
</html>