teilchensammler-cli/src/teilchensammler_cli/main.py
bronsen 6c6ca0e997 create settings module in preparation of aerich
currently, it's only used for tortoise_orm
2025-12-09 21:35:48 +01:00

113 lines
3.2 KiB
Python

"""
This is where the application is implemented.
"""
from typing import Literal, final, override
from textual.app import App, ComposeResult
from textual.containers import HorizontalGroup
from textual.screen import Screen
from textual.widget import Widget
from textual.widgets import (
Button,
DataTable,
Footer,
Header,
Input,
Static,
)
from tortoise import Tortoise
from teilchensammler_cli import settings
@final
class SearchBar(Static):
DEFAULT_CSS = """
#teilchen-input {
width: 4fr;
}
#button-search, #button-add {
width: 1fr;
}
"""
@override
def compose(self) -> ComposeResult:
with HorizontalGroup(id="search-bar-widget"):
yield Input(
placeholder="Enter Teilchen information: name, description, #tags",
tooltip=(
"This is a free-form field: Enter a name and "
"description any way you like. You should use #hashtags for any "
"meta information."
),
id="teilchen-input",
type="text",
)
yield Button("Add", variant="success", classes="search-bar-buttons", id="button-add")
yield Button(
"Search",
variant="default",
classes="search-bar-buttons",
id="button-search",
)
TeilchenDatum = tuple[int, str, str, str, str]
TeilchenHeader = tuple[
Literal["pk"],
Literal["Name"],
Literal["Description"],
Literal["Number"],
Literal["Tags"],
]
FAKE_DATA: list[TeilchenHeader | TeilchenDatum] = [
("pk", "Name", "Description", "Number", "Tags"),
(0, "Name0", "Description0", "9000", "#tag0 #tag00 #tag000"),
(1, "Name1", "Description1", "9001", "#tag1 #tag11 #tag111"),
(2, "Name2", "Description2", "9002", "#tag2 #tag22 #tag222"),
(3, "Name3", "Description3", "9003", "#tag3 #tag33 #tag333"),
(4, "Name4", "Description4", "9004", "#tag4 #tag44 #tag444"),
(5, "Name5", "Description5", "9005", "#tag5 #tag55 #tag555"),
]
@final
class SearchResults(Widget):
@override
def compose(self) -> ComposeResult:
yield DataTable(id="table-search-result", cursor_type="row", zebra_stripes=True)
async def on_mount(self) -> None:
table: DataTable[None] = self.query_one(DataTable[None])
_ = table.add_columns(*FAKE_DATA[0]) # pyright: ignore[reportArgumentType]
_ = table.add_rows(FAKE_DATA[1:]) # pyright: ignore[reportArgumentType]
class AddInventoryScreen(Screen[None]):
@override
def compose(self) -> ComposeResult:
yield Header()
yield SearchBar()
yield SearchResults()
yield Footer()
@final
class SammlerApp(App[None]):
async def on_mount(self) -> None:
await Tortoise.init(config=settings.TORTOISE_ORM_CONFIG)
await Tortoise.generate_schemas(safe=True)
_ = self.push_screen(AddInventoryScreen())
async def on_unmount(self) -> None:
# https://tortoise.github.io/setup.html#the-importance-of-cleaning-up
await Tortoise.close_connections()
def main() -> None:
app = SammlerApp()
app.run()