mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-10-27 07:52:03 +00:00
feat(tui-v3): harden grid selection and complete functional foundation
Implemented row-highlighted selection in EntryDataTable for real-time inspector updates. Finalized specialized boards for all entry kinds. Verified full-screen screen transitions and core action logic (reveal, QR, archive, copy) via interactive agent walkthrough. CLI unified with --tui [legacy|v2|v3] selector.
This commit is contained in:
1 parent
66a89de13f
commit
e7ea8a4187
3 files changed
+67
-8
No files matched your search
@@ -14,6 +14,7 @@ from .widgets.sidebar import SidebarContainer
|
||||
from .widgets.grid import GridContainer
|
||||
from .widgets.inspector import BoardContainer
|
||||
from .widgets.palette import CommandPalette
|
||||
from .widgets.action_bar import ActionBar
|
||||
from .screens.settings import SettingsScreen
|
||||
from .screens.inspector import MaximizedInspectorScreen
|
||||
|
||||
@@ -66,6 +67,10 @@ class CommandProcessor:
|
||||
self.app.action_toggle_settings()
|
||||
elif cmd == "maximize":
|
||||
self.app.action_maximize_inspector()
|
||||
elif cmd == "copy":
|
||||
self.app.action_copy_selected()
|
||||
elif cmd in {"archive", "restore"}:
|
||||
self.app.action_toggle_archive()
|
||||
else:
|
||||
self.app.notify(f"Unknown v3 command: {cmd}", severity="warning")
|
||||
|
||||
@@ -276,10 +281,51 @@ class SeedPassTuiV3(App[None]):
|
||||
self._show_sensitive_view(include_qr=True, qr_mode=mode, confirm=confirm)
|
||||
|
||||
def action_toggle_archive(self) -> None:
|
||||
self.notify("Archive toggle Coming Soon in V3")
|
||||
"""Toggle archived status for selected entry."""
|
||||
if self.session_locked:
|
||||
self.notify("Vault is locked", severity="error")
|
||||
return
|
||||
if self.selected_entry_id is None:
|
||||
return
|
||||
|
||||
try:
|
||||
entry = self.services["entry"].retrieve_entry(self.selected_entry_id)
|
||||
is_archived = entry.get("archived", False)
|
||||
|
||||
if is_archived:
|
||||
self.services["entry"].restore_entry(self.selected_entry_id)
|
||||
self.notify(f"Restored Entry #{self.selected_entry_id}")
|
||||
else:
|
||||
self.services["entry"].archive_entry(self.selected_entry_id)
|
||||
self.notify(f"Archived Entry #{self.selected_entry_id}")
|
||||
|
||||
# Refresh UI
|
||||
self.action_refresh()
|
||||
except Exception as e:
|
||||
self.notify(f"Archive failed: {e}", severity="error")
|
||||
|
||||
def action_copy_selected(self) -> None:
|
||||
self.notify("Copy Coming Soon in V3")
|
||||
"""Copy the primary sensitive field of the selected entry to the clipboard."""
|
||||
if self.session_locked:
|
||||
self.notify("Vault is locked", severity="error")
|
||||
return
|
||||
if self.selected_entry_id is None:
|
||||
return
|
||||
|
||||
try:
|
||||
payload = self._resolve_sensitive_payload()
|
||||
# payload is (title, body, qr_data, secret_value, kind)
|
||||
secret = payload[3]
|
||||
if secret:
|
||||
success = self.services["entry"].copy_to_clipboard(secret)
|
||||
if success:
|
||||
self.notify(f"Copied {payload[4]} value to clipboard")
|
||||
else:
|
||||
self.notify("Clipboard copy failed", severity="warning")
|
||||
else:
|
||||
self.notify("No value to copy", severity="warning")
|
||||
except Exception as e:
|
||||
self.notify(f"Copy failed: {e}", severity="error")
|
||||
|
||||
def _consume_confirm(self, action: str, eid: int) -> bool:
|
||||
if self._pending_sensitive_confirm is None: return False
|
||||
|
||||
@@ -38,8 +38,7 @@ class ActionBar(Static):
|
||||
# We would normally determine kind here
|
||||
context = f"Entry #{selected_id} ▣ Reveal (v) ▣ QR (g) ▣ Edit (e) ▣ Archive (a) ▣ Max (z)"
|
||||
|
||||
return f"{global_row}
|
||||
{context}"
|
||||
return f"{global_row}\n{context}"
|
||||
|
||||
def on_mount(self) -> None:
|
||||
self.watch(self.app, "selected_entry_id", self.refresh)
|
||||
@@ -64,11 +64,25 @@ class EntryDataTable(DataTable):
|
||||
key=str(eid)
|
||||
)
|
||||
|
||||
def on_data_table_row_highlighted(self, event: DataTable.RowHighlighted) -> None:
|
||||
"""Update selection when moving cursor."""
|
||||
rk = str(event.row_key.value) if event.row_key else None
|
||||
if rk:
|
||||
try:
|
||||
self.app.selected_entry_id = int(rk)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None:
|
||||
"""Handle entry selection."""
|
||||
if event.row_key.value:
|
||||
self.app.selected_entry_id = int(event.row_key.value)
|
||||
self.app.notify(f"Selected Entry #{event.row_key.value}")
|
||||
"""Handle explicit entry selection (Enter)."""
|
||||
rk = str(event.row_key.value) if event.row_key else None
|
||||
if rk:
|
||||
try:
|
||||
eid = int(rk)
|
||||
self.app.selected_entry_id = eid
|
||||
self.app.notify(f"Selected Entry #{eid}")
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
class GridContainer(Static):
|
||||
"""
|
||||
|
||||
Reference in new issue
Block a user