74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
from rich.markup import escape
|
|
from textual import on
|
|
from textual.app import ComposeResult
|
|
from textual.binding import Binding
|
|
from textual.containers import Horizontal, VerticalScroll
|
|
from textual.widgets import DataTable, Static
|
|
|
|
import portfolio
|
|
from fields import get_path, to_form_text
|
|
from tui.content_pane import ContentPane
|
|
from tui.record_editor import RecordEditor
|
|
|
|
PREVIEW_LENGTH = 60
|
|
|
|
|
|
class ProfilePane(ContentPane):
|
|
BINDINGS = [
|
|
Binding("e", "edit", "Edit"),
|
|
Binding("r", "reload", "Reload"),
|
|
]
|
|
|
|
content_file = portfolio.PROFILE.file
|
|
|
|
def compose(self) -> ComposeResult:
|
|
with Horizontal(classes="split-layout"):
|
|
yield DataTable(cursor_type="row", zebra_stripes=True)
|
|
with VerticalScroll(classes="detail-scroll"):
|
|
yield Static("", id="profile-detail")
|
|
|
|
def on_mount(self):
|
|
table = self.table()
|
|
table.add_column("Field", key="field")
|
|
table.add_column("Value", key="value")
|
|
self.reload()
|
|
|
|
def reload(self, focus_key: str | None = None):
|
|
profile = portfolio.load_records(portfolio.PROFILE)
|
|
table = self.table()
|
|
table.clear()
|
|
for spec in portfolio.PROFILE.fields:
|
|
text = to_form_text(spec.kind, get_path(profile, spec.path)).replace("\n", " · ")
|
|
preview = text if len(text) <= PREVIEW_LENGTH else text[:PREVIEW_LENGTH] + "..."
|
|
table.add_row(spec.label, preview, key=spec.path)
|
|
self.restore_cursor(focus_key)
|
|
self.show_field(self.selected_key())
|
|
|
|
def show_field(self, path: str | None):
|
|
spec = next((item for item in portfolio.PROFILE.fields if item.path == path), None)
|
|
detail = self.query_one("#profile-detail", Static)
|
|
if not spec:
|
|
detail.update("")
|
|
return
|
|
value = to_form_text(spec.kind, get_path(portfolio.load_records(portfolio.PROFILE), spec.path))
|
|
hint = f"\n[dim]{spec.hint}[/dim]" if spec.hint else ""
|
|
detail.update(f"[b]{escape(spec.label)}[/b]{hint}\n\n{escape(value) or '[dim]empty[/dim]'}\n\n[dim]Press e or Enter to edit the profile.[/dim]")
|
|
|
|
@on(DataTable.RowHighlighted)
|
|
def highlight_changed(self, event: DataTable.RowHighlighted):
|
|
self.show_field(event.row_key.value if event.row_key else None)
|
|
|
|
@on(DataTable.RowSelected)
|
|
def row_selected(self):
|
|
self.action_edit()
|
|
|
|
def action_edit(self):
|
|
profile = portfolio.load_records(portfolio.PROFILE)
|
|
focus_key = self.selected_key()
|
|
|
|
def saved(result: dict | None):
|
|
if result is not None:
|
|
self.run_now(lambda: portfolio.save_record(portfolio.PROFILE, None, result), "Saved profile", focus_key)
|
|
|
|
self.app.push_screen(RecordEditor("Edit profile", portfolio.PROFILE.fields, profile), saved)
|