Coverage for nexusLIMS/tui/apps/instruments/app.py: 100%
29 statements
« prev ^ index » next coverage.py v7.11.3, created at 2026-03-24 05:23 +0000
« prev ^ index » next coverage.py v7.11.3, created at 2026-03-24 05:23 +0000
1"""
2Instrument Management TUI Application.
4Provides an interactive terminal UI for CRUD operations on the NexusLIMS
5instruments database.
6"""
8from pathlib import Path
10from sqlmodel import Session, create_engine
12from nexusLIMS import config
13from nexusLIMS.tui.apps.instruments.screens import InstrumentListScreen
14from nexusLIMS.tui.common.base_app import BaseNexusApp
17class InstrumentManagerApp(BaseNexusApp):
18 """
19 TUI application for managing NexusLIMS instruments.
21 Provides:
22 - List view of all instruments
23 - Add new instruments
24 - Edit existing instruments
25 - Delete instruments (with confirmation)
26 - Theme switching
27 - Help screen
29 Parameters
30 ----------
31 db_path : pathlib.Path | None
32 Path to the database file. If provided, overrides NX_DB_PATH from config.
33 If None, uses the value from config.settings.NX_DB_PATH.
34 """
36 def __init__(self, db_path: Path | None = None, **kwargs):
37 """Initialize the instrument manager app."""
38 self._db_path = db_path
39 super().__init__(**kwargs)
41 @property
42 def db_path(self) -> Path:
43 """Get the database path (override or from config)."""
44 return (
45 self._db_path if self._db_path is not None else config.settings.NX_DB_PATH
46 )
48 def on_mount(self) -> None:
49 """Set up the app and show instrument list."""
50 # If custom db_path provided, create custom session
51 if self._db_path is not None:
52 try:
53 engine = create_engine(
54 f"sqlite:///{self._db_path}",
55 connect_args={"check_same_thread": False},
56 )
57 self.db_session = Session(engine)
58 except Exception as e:
59 self.show_error(f"Database connection failed: {e}")
60 return
62 # Call parent on_mount (which creates default db_session if not set)
63 super().on_mount()
65 # Set title with database path
66 self.title = f"NexusLIMS Instrument Manager - {self.db_path}"
68 # Push the list screen as the main screen
69 self.push_screen(InstrumentListScreen())
71 def get_app_name(self) -> str:
72 """Get application name for help screen."""
73 return "NexusLIMS Instrument Manager"
75 def get_keybindings(self) -> list[tuple[str, str]]:
76 """Get app-specific keybindings for help screen."""
77 base_bindings = super().get_keybindings()
79 app_bindings = [
80 ("a", "Add new instrument"),
81 ("e / Enter", "Edit selected instrument"),
82 ("d", "Delete selected instrument"),
83 ("r", "Refresh instrument list"),
84 ("s", "Cycle sort column (press repeatedly to change column/direction)"),
85 ("/", "Focus filter/search bar"),
86 ("↑↓", "Navigate instrument list"),
87 ("Click column header", "Sort by that column (click again to reverse)"),
88 ("Double click instrument row", "Edit that instrument's data"),
89 ]
91 return app_bindings + base_bindings