This commit is contained in:
2025-09-17 08:26:56 +02:00
parent 3ba44e47c1
commit 7af7ba28a0
23 changed files with 2420 additions and 0 deletions

193
src/main.py Normal file
View File

@@ -0,0 +1,193 @@
import os
from dotenv import load_dotenv
from nicegui import ui, app
from components import Header, Sidebar
from pages import DashboardPage, OllamaManagerPage
from utils import data_manager
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logging.getLogger('watchfiles').setLevel(logging.WARNING)
load_dotenv()
app.add_static_files('/static', 'src/static')
# Start global data collection
@app.on_startup
async def startup():
data_manager.start()
@app.on_shutdown
async def shutdown():
data_manager.stop()
def create_layout(current_route='/'):
# Force dark mode
ui.dark_mode(True)
ui.query('.nicegui-content').classes('p-0 m-0')
# Add custom CSS
ui.add_head_html('<link rel="stylesheet" type="text/css" href="/static/style.css">')
Header()
Sidebar(current_route)
@ui.page('/')
async def index_page():
create_layout('/')
DashboardPage()
@ui.page('/system')
async def system_page():
create_layout('/system')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('System Overview').classes('text-2xl font-bold text-white mb-4')
with ui.card().classes('metric-card p-6'):
ui.label('Detailed system information will be displayed here...').classes('text-grey-5')
@ui.page('/ollama')
async def ollama_page():
create_layout('/ollama')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('Ollama Manager').classes('text-2xl font-bold text-white mb-4')
# Status cards
with ui.row().classes('w-full gap-4 mb-6'):
with ui.card().classes('metric-card flex-grow p-4'):
with ui.row().classes('items-center gap-2'):
ui.icon('check_circle', color='green')
ui.label('Status: Online').classes('font-medium text-white')
with ui.card().classes('metric-card flex-grow p-4'):
ui.label('Version: 0.11.11').classes('font-medium text-white')
# Models list
with ui.card().classes('metric-card p-6'):
ui.label('Installed Models').classes('text-lg font-bold text-white mb-4')
models = [
('llama3.2:3b', '2.0 GB', 'Q4_0'),
('mistral:7b', '4.1 GB', 'Q4_0'),
('codellama:13b', '7.4 GB', 'Q4_K_M'),
('phi3:mini', '2.3 GB', 'Q4_0'),
]
for name, size, quant in models:
with ui.card().classes('metric-card p-4 mb-2'):
with ui.row().classes('w-full items-center'):
with ui.column().classes('gap-1'):
ui.label(name).classes('font-bold text-white')
with ui.row().classes('gap-2'):
ui.chip(size, icon='storage').props('outline dense color=cyan')
ui.chip(quant, icon='memory').props('outline dense color=orange')
ui.space()
with ui.row().classes('gap-2'):
ui.button(icon='play_arrow').props('round flat color=green').tooltip('Run')
ui.button(icon='info').props('round flat color=blue').tooltip('Info')
ui.button(icon='delete').props('round flat color=red').tooltip('Delete')
@ui.page('/processes')
async def processes_page():
create_layout('/processes')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('Process Manager').classes('text-2xl font-bold text-white')
with ui.card().classes('metric-card p-6'):
ui.label('Process management coming soon...').classes('text-grey-5')
@ui.page('/network')
async def network_page():
create_layout('/network')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('Network Monitor').classes('text-2xl font-bold text-white')
with ui.card().classes('metric-card p-6'):
ui.label('Network monitoring coming soon...').classes('text-grey-5')
@ui.page('/packages')
async def packages_page():
create_layout('/packages')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('Package Manager').classes('text-2xl font-bold text-white')
with ui.card().classes('metric-card p-6'):
ui.label('Package management coming soon...').classes('text-grey-5')
@ui.page('/logs')
async def logs_page():
create_layout('/logs')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('Log Viewer').classes('text-2xl font-bold text-white')
with ui.card().classes('metric-card p-6'):
ui.label('Log viewing coming soon...').classes('text-grey-5')
@ui.page('/info')
async def info_page():
create_layout('/info')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('System Information').classes('text-2xl font-bold text-white')
with ui.card().classes('metric-card p-6'):
ui.label('Detailed system information coming soon...').classes('text-grey-5')
@ui.page('/settings')
async def settings_page():
create_layout('/settings')
with ui.element('div').classes('main-content w-full'):
with ui.column().classes('w-full max-w-4xl mx-auto p-6 gap-6'):
ui.label('Settings').classes('text-2xl font-bold text-white')
with ui.card().classes('metric-card p-6'):
ui.label('Refresh Intervals').classes('text-lg font-bold text-white mb-4')
with ui.column().classes('gap-4'):
with ui.row().classes('items-center justify-between'):
ui.label('System Stats').classes('text-white')
ui.select(['1s', '2s', '5s', '10s'], value='2s').props('outlined dense color=cyan')
with ui.row().classes('items-center justify-between'):
ui.label('GPU Temperature').classes('text-white')
ui.select(['1s', '2s', '5s', '10s'], value='5s').props('outlined dense color=cyan')
with ui.card().classes('metric-card p-6 mt-4'):
ui.label('About').classes('text-lg font-bold text-white mb-4')
with ui.column().classes('gap-2'):
with ui.row().classes('items-center gap-2'):
ui.icon('computer', color='cyan')
ui.label('ArchGPU Frontend v0.1.0').classes('text-white')
with ui.row().classes('items-center gap-2'):
ui.icon('smart_toy', color='orange')
ui.label('Ollama v0.11.11').classes('text-white')
if __name__ in {"__main__", "__mp_main__"}:
ui.run(
title=os.getenv('APP_TITLE', 'ArchGPU Frontend'),
storage_secret=os.getenv('APP_STORAGE_SECRET'),
port=int(os.getenv('APP_PORT', '8080')),
show=os.getenv("APP_SHOW", 'false').lower() == "true",
dark=True
)