click-textual
Maveno 1 year ago
parent a46a2b421e
commit 322321b1ed

@ -1,10 +1,24 @@
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.orm import relationship, sessionmaker, Mapped
from .show import Base from .show import Base
class Pattern(Base): class Pattern(Base):
__tablename__ = 'patterns' __tablename__ = 'patterns'
# v1.x
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
pattern = Column(String) pattern = Column(String)
# v2.0
# id: Mapped[int] = mapped_column(Integer, primary_key=True)
# pattern: Mapped[str] = mapped_column(String, nullable=False)
# v1.x
show_id = Column(Integer, ForeignKey('shows.id', ondelete="CASCADE"))
show = relationship('Show', back_populates='patterns')
# v2.0
# show_id: Mapped[int] = mapped_column(ForeignKey("shows.id", ondelete="CASCADE"))
# show: Mapped["Show"] = relationship(back_populates="patterns")

@ -1,13 +1,25 @@
# from typing import List
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.orm import relationship, declarative_base, sessionmaker
from sqlalchemy.orm import declarative_base
Base = declarative_base() Base = declarative_base()
class Show(Base): class Show(Base):
__tablename__ = 'shows' __tablename__ = 'shows'
# v1.x
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
name = Column(String) name = Column(String)
year = Column(Integer) year = Column(Integer)
# v2.0
# id: Mapped[int] = mapped_column(Integer, primary_key=True)
# name: Mapped[str] = mapped_column(String, nullable=False)
# year: Mapped[int] = mapped_column(Integer, nullable=False)
# v1.x
patterns = relationship('Pattern', back_populates='show', cascade="all, delete")
# v2.0
# patterns: Mapped[List["Pattern"]] = relationship(back_populates="show", cascade="all, delete")

@ -108,7 +108,7 @@ class ShowDeleteScreen(Screen):
def deleteShow(self, show_id): def deleteShow(self, show_id):
try: try:
s = self.Session() s = self.Session()
q = s.query(Show).filter(Show.id == show_id) q = s.query(Show).filter(Show.id == int(show_id))
if q.count(): if q.count():
q.delete() q.delete()
@ -120,4 +120,3 @@ class ShowDeleteScreen(Screen):
click.ClickException(f"ShowDetailsScreen.updateShow(): {repr(ex)}") click.ClickException(f"ShowDetailsScreen.updateShow(): {repr(ex)}")
finally: finally:
s.close() s.close()

@ -7,6 +7,7 @@ from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListIt
from textual.containers import Grid, Horizontal from textual.containers import Grid, Horizontal
from ffx.model.show import Show from ffx.model.show import Show
from ffx.model.pattern import Pattern
# Screen[dict[int, str, int]] # Screen[dict[int, str, int]]
class ShowDetailsScreen(Screen): class ShowDetailsScreen(Screen):
@ -28,6 +29,11 @@ class ShowDetailsScreen(Screen):
Button { Button {
border: none; border: none;
} }
DataTable {
column-span: 2;
min-height: 5;
}
#toplabel { #toplabel {
height: 1; height: 1;
column-span: 2; column-span: 2;
@ -55,37 +61,68 @@ class ShowDetailsScreen(Screen):
self.show_obj = show self.show_obj = show
def loadPatterns(self, show_id):
try:
s = self.Session()
q = s.query(Pattern).filter(Pattern.show_id == int(show_id))
return [{'id': int(p.id), 'pattern': p.pattern} for p in q.all()]
except Exception as ex:
click.ClickException(f"loadPatterns(): {repr(ex)}")
finally:
s.close()
def on_mount(self): def on_mount(self):
if self.show_obj: if self.show_obj:
self.query_one("#id_wdg", Static).update(str(self.show_obj['id'])) self.query_one("#id_wdg", Static).update(str(self.show_obj['id']))
self.query_one("#name_input", Input).value = self.show_obj['name'] self.query_one("#name_input", Input).value = str(self.show_obj['name'])
self.query_one("#year_input", Input).value = self.show_obj['year'] self.query_one("#year_input", Input).value = str(self.show_obj['year'])
for pattern in self.loadPatterns(int(self.show_obj['id'])):
row = (pattern['pattern'],)
self.patternTable.add_row(*map(str, row))
def compose(self): def compose(self):
# Create the DataTable widget
self.patternTable = DataTable()
# Define the columns with headers
self.column_key_id = self.patternTable.add_column("Pattern", width=60)
#self.column_key_name = self.patternTable.add_column("Name", width=50)
#self.column_key_year = self.patternTable.add_column("Year", width=10)
self.patternTable.cursor_type = 'row'
yield Header() yield Header()
with Grid(): with Grid():
yield Static("New Show" if self.show_obj else "Show", id="toplabel") yield Static("Show" if self.show_obj else "New Show", id="toplabel")
yield Static("ID") yield Static("ID")
if self.show_obj: if self.show_obj:
yield Static("", id="id_wdg") yield Static("", id="id_wdg")
else: else:
yield Input(type="text", id="id_wdg") yield Input(type="integer", id="id_wdg")
yield Static("Name") yield Static("Name")
yield Input(type="text", id="name_input") yield Input(type="text", id="name_input")
yield Static("Year") yield Static("Year")
yield Input(type="text", id="year_input") yield Input(type="integer", id="year_input")
yield Static("") yield Static("")
yield Static("") yield Static("")
yield self.patternTable
yield Static("") yield Static("")
yield Static("") yield Static("")
@ -102,8 +139,8 @@ class ShowDetailsScreen(Screen):
else: else:
showId = int(self.query_one("#id_wdg", Input).value) showId = int(self.query_one("#id_wdg", Input).value)
showName = self.query_one("#name_input", Input).value showName = str(self.query_one("#name_input", Input).value)
showYear = self.query_one("#year_input", Input).value showYear = int(self.query_one("#year_input", Input).value)
return showId, showName, showYear return showId, showName, showYear
@ -136,9 +173,9 @@ class ShowDetailsScreen(Screen):
q = s.query(Show).filter(Show.id == show_id) q = s.query(Show).filter(Show.id == show_id)
if not q.count(): if not q.count():
show = Show(id = show_id, show = Show(id = int(show_id),
name = show_name, name = str(show_name),
year = show_year) year = int(show_year))
s.add(show) s.add(show)
s.commit() s.commit()
return True return True
@ -147,11 +184,11 @@ class ShowDetailsScreen(Screen):
currentShow = q.first() currentShow = q.first()
changed = False changed = False
if currentShow.name != show_name: if currentShow.name != str(show_name):
currentShow.name = show_name currentShow.name = str(show_name)
changed = True changed = True
if currentShow.year != show_year: if currentShow.year != int(show_year):
currentShow.year = show_year currentShow.year = int(show_year)
changed = True changed = True
if changed: if changed:
s.commit() s.commit()

@ -1,60 +0,0 @@
import click
from textual.app import App, ComposeResult
from textual.screen import Screen
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button
from textual.containers import Grid, Horizontal
from ffx.model.show import Show
class ShowNewScreen(Screen):
CSS = """
Grid {
grid-size: 2;
grid-rows: 2 auto;
height: 100%;
width: 100%;
padding: 1;
}
#top {
height: 1;
}
#two {
column-span: 2;
row-span: 2;
tint: magenta 40%;
}
.box {
height: 100%;
border: solid green;
}
"""
BINDINGS = [
("q", "quit()", "Quit"),
("h", "switch_mode('help')", "Help")
]
def __init__(self):
super().__init__()
self.context = self.app.getContext()
self.Session = self.context['database_session'] # convenience
def compose(self):
yield Header()
with Grid():
yield Static("New Show")
yield Footer()
Loading…
Cancel
Save