Add project files
This commit is contained in:
parent
efd3406ae4
commit
73f651e985
5 changed files with 137 additions and 1 deletions
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
BSD 3-Clause License
|
BSD 3-Clause License
|
||||||
|
|
||||||
Copyright (c) 2025, Julian Müller
|
Copyright (c) 2025, Julian Müller (ChaoticByte)
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
30
dashboard/thing.py
Normal file
30
dashboard/thing.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright (c) 2025, Julian Müller (ChaoticByte)
|
||||||
|
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
# base classes and types and stuff
|
||||||
|
|
||||||
|
class SystemState(Enum):
|
||||||
|
OK = 0
|
||||||
|
FAILED = 1
|
||||||
|
UNKNOWN = 2
|
||||||
|
|
||||||
|
class System:
|
||||||
|
|
||||||
|
def __init__(self, name: str, description: str):
|
||||||
|
self.name = name
|
||||||
|
self.description = description
|
||||||
|
self.state = SystemState.UNKNOWN
|
||||||
|
self.state_verbose = ""
|
||||||
|
|
||||||
|
def get_actions(self) -> dict:
|
||||||
|
# to be overridden
|
||||||
|
# return {'ActionName': callable, ...}
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def update_state(self):
|
||||||
|
# to be overridden
|
||||||
|
self.state = SystemState.UNKNOWN
|
||||||
|
self.state_verbose = ""
|
48
dashboard/ui.py
Normal file
48
dashboard/ui.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# Copyright (c) 2025, Julian Müller (ChaoticByte)
|
||||||
|
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
from .thing import System, SystemState
|
||||||
|
|
||||||
|
from nicegui import ui
|
||||||
|
|
||||||
|
|
||||||
|
def init_ui(systems: List[System]):
|
||||||
|
|
||||||
|
@ui.refreshable
|
||||||
|
def systems_list():
|
||||||
|
with ui.column(align_items="center").style("width: 40vw; max-width: 40rem; min-width: 25rem;"):
|
||||||
|
for t in systems:
|
||||||
|
card = ui.card().classes("w-full")
|
||||||
|
if t.state == SystemState.OK:
|
||||||
|
card = card.style("border-left: 4px solid limegreen")
|
||||||
|
elif t.state == SystemState.FAILED:
|
||||||
|
card = card.style("border-left: 4px solid red")
|
||||||
|
else:
|
||||||
|
card = card.style("border-left: 4px solid dodgerblue")
|
||||||
|
|
||||||
|
with card:
|
||||||
|
ui.label(t.name).classes("text-xl font-medium")
|
||||||
|
if t.description != "":
|
||||||
|
ui.label(t.description).classes("opacity-75")
|
||||||
|
if t.state_verbose != "":
|
||||||
|
ui.label(t.state_verbose).classes("opacity-50")
|
||||||
|
actions = t.get_actions()
|
||||||
|
if len(actions) > 0:
|
||||||
|
if t.description != "" or t.state_verbose != "":
|
||||||
|
ui.separator()
|
||||||
|
with ui.card_actions():
|
||||||
|
for n, c in actions.items():
|
||||||
|
ui.button(text=n, on_click=c)
|
||||||
|
|
||||||
|
with ui.column(align_items="center").classes("w-full"):
|
||||||
|
systems_list()
|
||||||
|
|
||||||
|
def update_states():
|
||||||
|
for t in systems:
|
||||||
|
t.update_state()
|
||||||
|
|
||||||
|
ui.timer(15, callback=update_states)
|
||||||
|
ui.timer(2, systems_list.refresh)
|
||||||
|
|
||||||
|
dark = ui.dark_mode(None) # auto
|
57
example.py
Normal file
57
example.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# Copyright (c) 2025, Julian Müller (ChaoticByte)
|
||||||
|
|
||||||
|
|
||||||
|
from nicegui import ui
|
||||||
|
|
||||||
|
from dashboard.thing import System, SystemState
|
||||||
|
from dashboard.ui import init_ui
|
||||||
|
|
||||||
|
|
||||||
|
# define systems
|
||||||
|
|
||||||
|
|
||||||
|
class ExampleSystem(System):
|
||||||
|
|
||||||
|
pressed = False
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
super().__init__(*args)
|
||||||
|
self.started = False
|
||||||
|
|
||||||
|
def update_state(self):
|
||||||
|
if self.started:
|
||||||
|
self.state = SystemState.OK
|
||||||
|
self.state_verbose = f"{self.name} is currently started."
|
||||||
|
else:
|
||||||
|
self.state = SystemState.FAILED
|
||||||
|
self.state_verbose = f"{self.name} is currently stopped."
|
||||||
|
|
||||||
|
def get_actions(self) -> dict:
|
||||||
|
if self.started:
|
||||||
|
return {"Stop": self.stop}
|
||||||
|
else:
|
||||||
|
return {"Start": self.start}
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.state = SystemState.UNKNOWN
|
||||||
|
self.state_verbose = f"{self.name} is currently starting."
|
||||||
|
self.started = True
|
||||||
|
ui.notify("Starting " + self.name)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.state = SystemState.UNKNOWN
|
||||||
|
self.state_verbose = f"{self.name} is currently stopping."
|
||||||
|
self.started = False
|
||||||
|
ui.notify("Stopping " + self.name)
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
systems = [
|
||||||
|
ExampleSystem("Example System 1", "Description text ..."),
|
||||||
|
ExampleSystem("Example System 2", "Another description text ...")
|
||||||
|
]
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
init_ui(systems)
|
||||||
|
ui.run(show=False)
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nicegui~=2.11.1
|
Loading…
Add table
Add a link
Reference in a new issue