feat(tui): Phase 2 Issue List + MR List screens
Implement state, action, and view layers for both list screens: - Issue List: keyset pagination, snapshot fence, filter DSL, label aggregation - MR List: mirrors Issue pattern with draft/reviewer/target branch filters - Migration 027: covering indexes for TUI list screen queries - Updated Msg types to use typed Page structs instead of raw Vec<Row> - 303 tests passing, clippy clean Beads: bd-3ei1, bd-2kr0, bd-3pm2
This commit is contained in:
73
crates/lore-tui/src/app/mod.rs
Normal file
73
crates/lore-tui/src/app/mod.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
#![allow(dead_code)] // Phase 1: methods consumed as screens are implemented
|
||||
|
||||
//! Full FrankenTUI Model implementation for the lore TUI.
|
||||
//!
|
||||
//! LoreApp is the central coordinator: it owns all state, dispatches
|
||||
//! messages through a 5-stage key pipeline, records crash context
|
||||
//! breadcrumbs, manages async tasks via the supervisor, and routes
|
||||
//! view() to per-screen render functions.
|
||||
|
||||
mod tests;
|
||||
mod update;
|
||||
|
||||
use crate::clock::{Clock, SystemClock};
|
||||
use crate::commands::{CommandRegistry, build_registry};
|
||||
use crate::crash_context::CrashContext;
|
||||
use crate::db::DbManager;
|
||||
use crate::message::InputMode;
|
||||
use crate::navigation::NavigationStack;
|
||||
use crate::state::AppState;
|
||||
use crate::task_supervisor::TaskSupervisor;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// LoreApp
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Root model for the lore TUI.
|
||||
///
|
||||
/// Owns all state and implements the FrankenTUI Model trait. The
|
||||
/// update() method is the single entry point for all state transitions.
|
||||
pub struct LoreApp {
|
||||
pub state: AppState,
|
||||
pub navigation: NavigationStack,
|
||||
pub supervisor: TaskSupervisor,
|
||||
pub crash_context: CrashContext,
|
||||
pub command_registry: CommandRegistry,
|
||||
pub input_mode: InputMode,
|
||||
pub clock: Box<dyn Clock>,
|
||||
pub db: Option<DbManager>,
|
||||
}
|
||||
|
||||
impl LoreApp {
|
||||
/// Create a new LoreApp with default state.
|
||||
///
|
||||
/// Uses a real system clock and no DB connection (set separately).
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
state: AppState::default(),
|
||||
navigation: NavigationStack::new(),
|
||||
supervisor: TaskSupervisor::new(),
|
||||
crash_context: CrashContext::new(),
|
||||
command_registry: build_registry(),
|
||||
input_mode: InputMode::Normal,
|
||||
clock: Box::new(SystemClock),
|
||||
db: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a LoreApp for testing with a custom clock.
|
||||
#[cfg(test)]
|
||||
fn with_clock(clock: Box<dyn Clock>) -> Self {
|
||||
Self {
|
||||
clock,
|
||||
..Self::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LoreApp {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user