init
This commit is contained in:
193
src/main.py
Normal file
193
src/main.py
Normal 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
|
||||
)
|
||||
Reference in New Issue
Block a user