teilchensammler-cli/src/teilchensammler_cli/main.py

113 lines
3.1 KiB
Python
Raw Normal View History

"""
This is where the application is implemented.
"""
2025-12-04 19:25:18 +01:00
from typing import Literal, final, override
from textual.app import App, ComposeResult
2025-12-04 19:25:18 +01:00
from textual.containers import HorizontalGroup
from textual.screen import Screen
from textual.widget import Widget
from textual.widgets import (
Button,
2025-12-04 19:25:18 +01:00
DataTable,
Footer,
Header,
Input,
Static,
)
from tortoise import Tortoise, fields
from tortoise.models import Model
@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",
)
2025-12-04 19:25:18 +01:00
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)
2025-12-04 23:11:41 +01:00
async def on_mount(self) -> None:
2025-12-04 19:25:18 +01:00
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()
2025-12-04 19:25:18 +01:00
yield SearchResults()
yield Footer()
@final
class SammlerApp(App[None]):
2025-12-04 23:11:41 +01:00
async def on_mount(self) -> None:
await Tortoise.init(
db_url="sqlite://db.sqlite3", modules={"models": ["teilchensammler_cli"]}
)
await Tortoise.generate_schemas()
_ = self.push_screen(AddInventoryScreen())
def main() -> None:
app = SammlerApp()
app.run()