mwe full cycle form input
parent
24e85d7005
commit
37786f56b5
@ -0,0 +1,67 @@
|
||||
import os
|
||||
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Header, Footer, Placeholder, Label
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from ffx.model.show import Base, Show
|
||||
from ffx.model.pattern import Pattern
|
||||
|
||||
from .shows_screen import ShowsScreen
|
||||
from .warning_screen import WarningScreen
|
||||
from .dashboard_screen import DashboardScreen
|
||||
from .settings_screen import SettingsScreen
|
||||
from .help_screen import HelpScreen
|
||||
|
||||
class FfxApp(App):
|
||||
|
||||
TITLE = "FFX"
|
||||
|
||||
BINDINGS = [
|
||||
("q", "quit()", "Quit"),
|
||||
# ("d", "switch_mode('dashboard')", "Dashboard"),
|
||||
# ("s", "switch_mode('settings')", "Settings"),
|
||||
("h", "switch_mode('help')", "Help"),
|
||||
]
|
||||
|
||||
# MODES = {
|
||||
# "shows": ShowsScreen,
|
||||
# "warning": WarningScreen,
|
||||
# "dashboard": DashboardScreen,
|
||||
# "settings": SettingsScreen,
|
||||
# "help": HelpScreen,
|
||||
# }
|
||||
|
||||
|
||||
def __init__(self, context = {}):
|
||||
super().__init__()
|
||||
|
||||
# Data 'input' variable
|
||||
self.context = context
|
||||
|
||||
# Initialize DB
|
||||
homeDir = os.path.expanduser("~")
|
||||
ffxVarDir = os.path.join(homeDir, '.local', 'var', 'ffx')
|
||||
if not os.path.exists(ffxVarDir):
|
||||
os.makedirs(ffxVarDir)
|
||||
|
||||
self.context['database_url'] = f"sqlite:///{os.path.join(ffxVarDir, 'ffx.db')}"
|
||||
self.context['database_engine'] = create_engine(self.context['database_url'])
|
||||
self.context['database_session'] = sessionmaker(bind=self.context['database_engine'])
|
||||
|
||||
Base.metadata.create_all(self.context['database_engine'])
|
||||
|
||||
|
||||
def on_mount(self) -> None:
|
||||
|
||||
|
||||
# Show Shows Screen
|
||||
#self.switch_mode("shows")
|
||||
self.push_screen(ShowsScreen())
|
||||
|
||||
|
||||
def getContext(self):
|
||||
"""Data 'output' method"""
|
||||
return self.context
|
@ -1,2 +0,0 @@
|
||||
class FilePattern():
|
||||
pass
|
@ -0,0 +1,10 @@
|
||||
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
|
||||
from sqlalchemy.orm import relationship, sessionmaker
|
||||
|
||||
from .show import Base
|
||||
|
||||
class Pattern(Base):
|
||||
|
||||
__tablename__ = 'patterns'
|
||||
id = Column(Integer, primary_key=True)
|
||||
pattern = Column(String)
|
@ -0,0 +1,13 @@
|
||||
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
|
||||
from sqlalchemy.orm import relationship, sessionmaker
|
||||
|
||||
from sqlalchemy.orm import declarative_base
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class Show(Base):
|
||||
|
||||
__tablename__ = 'shows'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String)
|
||||
year = Column(Integer)
|
@ -1,39 +0,0 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Header, Footer, Placeholder, Label
|
||||
|
||||
from .shows_screen import ShowsScreen
|
||||
from .warning_screen import WarningScreen
|
||||
from .dashboard_screen import DashboardScreen
|
||||
from .settings_screen import SettingsScreen
|
||||
from .help_screen import HelpScreen
|
||||
|
||||
class ModesApp(App):
|
||||
|
||||
TITLE = "FFX"
|
||||
|
||||
BINDINGS = [
|
||||
("q", "quit()", "Quit"),
|
||||
# ("d", "switch_mode('dashboard')", "Dashboard"),
|
||||
# ("s", "switch_mode('settings')", "Settings"),
|
||||
# ("h", "switch_mode('help')", "Help"),
|
||||
]
|
||||
|
||||
MODES = {
|
||||
"shows": ShowsScreen,
|
||||
"warning": WarningScreen,
|
||||
"dashboard": DashboardScreen,
|
||||
"settings": SettingsScreen,
|
||||
"help": HelpScreen,
|
||||
}
|
||||
|
||||
|
||||
def __init__(self, context = {}):
|
||||
super().__init__()
|
||||
self.context = context
|
||||
|
||||
def on_mount(self) -> None:
|
||||
self.switch_mode("shows")
|
||||
|
||||
def getContext(self):
|
||||
return self.context
|
@ -1,2 +0,0 @@
|
||||
class Show():
|
||||
pass
|
@ -0,0 +1,166 @@
|
||||
import click
|
||||
|
||||
from textual import events
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input
|
||||
from textual.containers import Grid, Horizontal
|
||||
|
||||
from ffx.model.show import Show
|
||||
|
||||
# class IdInput(Input):
|
||||
# def on_key(self, event: events.Key) -> None:
|
||||
# if event == "enter":
|
||||
# quit()
|
||||
|
||||
class ShowDetailsScreen(Screen):
|
||||
|
||||
CSS = """
|
||||
|
||||
Grid {
|
||||
grid-size: 2;
|
||||
grid-rows: 2 auto;
|
||||
grid-columns: 30 auto;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 1;
|
||||
}
|
||||
|
||||
Input {
|
||||
border: none;
|
||||
}
|
||||
Button {
|
||||
border: none;
|
||||
}
|
||||
#toplabel {
|
||||
height: 1;
|
||||
column-span: 2;
|
||||
}
|
||||
|
||||
|
||||
#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 action_quit(self):
|
||||
# quit()
|
||||
|
||||
def __init__(self, show_id = None):
|
||||
super().__init__()
|
||||
|
||||
self.context = self.app.getContext()
|
||||
|
||||
self.Session = self.context['database_session'] # convenience
|
||||
|
||||
self.show_id = show_id
|
||||
|
||||
def action_submit(self):
|
||||
quit()
|
||||
|
||||
def compose(self):
|
||||
|
||||
yield Header()
|
||||
|
||||
with Grid():
|
||||
|
||||
yield Static("New Show" if self.show_id is None else "Show", id="toplabel")
|
||||
yield Static("ID")
|
||||
yield Input(type="text", id="id_input")
|
||||
yield Static("Name")
|
||||
yield Input(type="text", id="name_input")
|
||||
yield Static("Year")
|
||||
yield Input(type="text", id="year_input")
|
||||
|
||||
yield Static("")
|
||||
yield Static("")
|
||||
|
||||
yield Static("")
|
||||
yield Static("")
|
||||
|
||||
yield Button("Save", id="save_button")
|
||||
yield Button("Cancel", id="cancel_button")
|
||||
|
||||
yield Static("", id="output_static")
|
||||
|
||||
|
||||
yield Footer()
|
||||
|
||||
def getValues(self):
|
||||
showId = int(self.query_one("#id_input", Input).value)
|
||||
showName = self.query_one("#name_input", Input).value
|
||||
showYear = self.query_one("#year_input", Input).value
|
||||
return showId, showName, showYear
|
||||
|
||||
|
||||
def on_input_submitted(self, event: Input.Submitted) -> None:
|
||||
|
||||
showId, showName, showYear = self.getValues()
|
||||
|
||||
#self.query_one("#output_static", Static).update(f"{showId} - {showName} ({showYear})")
|
||||
|
||||
# if event.input.id == "id_input":
|
||||
# # Retrieve the entered text
|
||||
# name = event.value
|
||||
# # Display the result in the output label
|
||||
# self.query_one("#output_static", Static).update(f"Hello, {name}!")
|
||||
# self.set_focus(self.query_one("#name_input", Input))
|
||||
#
|
||||
# if event.input.id == "name_input":
|
||||
# # Retrieve the entered text
|
||||
# name = event.value
|
||||
# # Display the result in the output label
|
||||
# self.query_one("#output_static", Static).update(f"Yo, {name}!")
|
||||
# self.set_focus(self.query_one("#year_input", Input))
|
||||
#
|
||||
# if event.input.id == "year_input":
|
||||
# # Retrieve the entered text
|
||||
# name = event.value
|
||||
# # Display the result in the output label
|
||||
# self.query_one("#output_static", Static).update(f"Ya, {name}!")
|
||||
# self.set_focus(None)
|
||||
|
||||
# Event handler for button press
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
# Check if the button pressed is the one we are interested in
|
||||
if event.button.id == "save_button":
|
||||
|
||||
showId, showName, showYear = self.getValues()
|
||||
self.query_one("#output_static", Static).update(f"{showId} - {showName} ({showYear})")
|
||||
|
||||
self.addShow(showId, showName, showYear)
|
||||
#TODO: Validation
|
||||
|
||||
# self.app.pop_screen()
|
||||
self.dismiss(showId)
|
||||
|
||||
if event.button.id == "cancel_button":
|
||||
self.app.pop_screen()
|
||||
|
||||
def addShow(self, show_id, show_name, show_year):
|
||||
|
||||
try:
|
||||
s = self.Session()
|
||||
show = Show(id = show_id,
|
||||
name = show_name,
|
||||
year = show_year)
|
||||
|
||||
s.add(show)
|
||||
s.commit()
|
||||
except Exception as ex:
|
||||
click.ClickException(f"ShowDetailsScreen.addShow(): {repr(ex)}")
|
||||
finally:
|
||||
s.close()
|
||||
|
@ -0,0 +1,60 @@
|
||||
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…
Reference in New Issue