mxr_tui/ui/
error_modal.rs1use crate::app::ErrorModalState;
2use ratatui::prelude::*;
3use ratatui::widgets::*;
4
5pub fn draw(
6 frame: &mut Frame,
7 area: Rect,
8 error: Option<&ErrorModalState>,
9 theme: &crate::theme::Theme,
10) {
11 let Some(error) = error else {
12 return;
13 };
14
15 let popup = centered_rect(62, 26, area);
16 frame.render_widget(Clear, popup);
17
18 let block = Block::bordered()
19 .title(format!(" {} ", error.title))
20 .border_type(BorderType::Rounded)
21 .border_style(Style::default().fg(theme.error))
22 .style(Style::default().bg(theme.modal_bg));
23 let inner = block.inner(popup);
24 frame.render_widget(block, popup);
25
26 let lines = vec![
27 Line::from(error.detail.clone()),
28 Line::from(""),
29 Line::from("[Enter] dismiss [Esc] dismiss"),
30 ];
31 frame.render_widget(Paragraph::new(lines).wrap(Wrap { trim: false }), inner);
32}
33
34fn centered_rect(percent_x: u16, percent_y: u16, area: Rect) -> Rect {
35 let vertical = Layout::default()
36 .direction(Direction::Vertical)
37 .constraints([
38 Constraint::Percentage((100 - percent_y) / 2),
39 Constraint::Percentage(percent_y),
40 Constraint::Percentage((100 - percent_y) / 2),
41 ])
42 .split(area);
43
44 Layout::default()
45 .direction(Direction::Horizontal)
46 .constraints([
47 Constraint::Percentage((100 - percent_x) / 2),
48 Constraint::Percentage(percent_x),
49 Constraint::Percentage((100 - percent_x) / 2),
50 ])
51 .split(vertical[1])[1]
52}
53
54#[cfg(test)]
55mod tests {
56 use super::draw;
57 use crate::app::ErrorModalState;
58
59 #[test]
60 fn error_modal_state_is_constructible() {
61 let error = ErrorModalState {
62 title: "Mutation Failed".into(),
63 detail: "Optimistic changes could not be applied.".into(),
64 };
65 let _ = draw;
66 assert!(error.detail.contains("Optimistic"));
67 }
68}