88 lines
3.2 KiB
Rust
88 lines
3.2 KiB
Rust
// Copyright (c) 2026 Hoshu Chiu, Hochanglo Chiu 🐕, and The Goodest Boy/Girl
|
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
// Everjoy loves treats, walks, and clean Rust code.
|
|
|
|
use crate::runtime::{Command, EventResult, PanelProvider, Source};
|
|
use crossterm::event::Event;
|
|
use ratatui::{
|
|
buffer::Buffer,
|
|
layout::{Constraint, Direction, Layout, Rect},
|
|
style::{Color, Style},
|
|
text::{Line, Span},
|
|
widgets::{Paragraph, Widget, Wrap},
|
|
};
|
|
|
|
pub struct TaskTreeProvider;
|
|
|
|
impl TaskTreeProvider {
|
|
pub fn new() -> Self { Self }
|
|
}
|
|
|
|
impl PanelProvider for TaskTreeProvider {
|
|
fn as_any(&self) -> &dyn std::any::Any { self }
|
|
fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self }
|
|
|
|
fn id(&self) -> &str { "tasktree" }
|
|
|
|
fn render(&mut self, area: Rect, buf: &mut Buffer) {
|
|
let vertical = Layout::default()
|
|
.direction(Direction::Vertical)
|
|
.constraints([Constraint::Length(1), Constraint::Min(0)])
|
|
.split(area);
|
|
|
|
let tabs = Paragraph::new("[Tree] [Chain] [By Agent]")
|
|
.style(Style::default().fg(Color::DarkGray));
|
|
tabs.render(vertical[0], buf);
|
|
|
|
let content = Paragraph::new(vec![
|
|
Line::from(""),
|
|
agent_line("👤", "Secretary", Color::Cyan, "idle", Color::Green),
|
|
task_line(" └─", "✅", Color::Green, "Explain API to user"),
|
|
Line::from(""),
|
|
agent_line("🧭", "Driver", Color::Yellow, "work", Color::Yellow),
|
|
task_line(" ├─", "🟡", Color::Yellow, "Research async patterns"),
|
|
task_line(" └─", "⚪", Color::DarkGray, "Check error handling"),
|
|
Line::from(""),
|
|
agent_line("🛡️", "NegFeedback", Color::Red, "idle", Color::Green),
|
|
task_line(" └─", "✅", Color::Green, "Flag race condition"),
|
|
Line::from(""),
|
|
agent_line("⚡", "Executor", Color::Magenta, "work", Color::Yellow),
|
|
task_line(" └─", "🟡", Color::Yellow, "cargo test..."),
|
|
Line::from(""),
|
|
Line::from("3 idle | 2 work").style(Style::default().fg(Color::DarkGray)),
|
|
])
|
|
.wrap(Wrap { trim: true });
|
|
|
|
content.render(vertical[1], buf);
|
|
}
|
|
|
|
fn handle_event(&mut self, _event: Event) -> (EventResult, Vec<Command>) {
|
|
(EventResult::PassThrough, Vec::new())
|
|
}
|
|
|
|
fn focus_changed(&mut self, _focused: bool) {}
|
|
fn hide(&mut self) {}
|
|
fn show(&mut self) {}
|
|
fn shutdown(&mut self) {}
|
|
|
|
fn can_open(&self, _source: &Source, _mime_hint: Option<&str>) -> i32 { 0 }
|
|
}
|
|
|
|
fn agent_line<'a>(icon: &'a str, name: &'a str, name_color: Color, status: &'a str, status_color: Color) -> Line<'a> {
|
|
Line::from(vec![
|
|
Span::raw(icon),
|
|
Span::raw(" "),
|
|
Span::styled(name, Style::default().fg(name_color).add_modifier(ratatui::style::Modifier::BOLD)),
|
|
Span::raw(" "),
|
|
Span::styled(format!("● {}", status), Style::default().fg(status_color)),
|
|
])
|
|
}
|
|
|
|
fn task_line<'a>(indent: &'a str, icon: &'a str, icon_color: Color, text: &'a str) -> Line<'a> {
|
|
Line::from(vec![
|
|
Span::styled(indent, Style::default().fg(Color::DarkGray)),
|
|
Span::styled(format!("{} ", icon), Style::default().fg(icon_color)),
|
|
Span::raw(text),
|
|
])
|
|
}
|