use ratatui::Frame;
use ratatui::text::{Line, Span};
use super::design;
use super::theme;
use crate::app::{App, Screen};
pub fn render_restart(frame: &mut Frame, app: &mut App) {
let Screen::ConfirmContainerRestart {
alias,
container_name,
project,
uptime,
..
} = &app.screen
else {
return;
};
render_dialog(
frame,
app,
" Restart container? ",
container_name,
alias,
project.as_deref(),
uptime.as_deref(),
crate::messages::CONTAINER_RESTART_BODY,
("restart", "keep"),
);
}
pub fn render_stack(frame: &mut Frame, app: &mut App) {
let Screen::ConfirmStackRestart {
alias,
project,
members,
} = &app.screen
else {
return;
};
let identity = Line::from(vec![
Span::raw(" "),
Span::styled(project.clone(), theme::bold()),
Span::raw(" "),
Span::styled(format!("on {}", alias), theme::muted()),
Span::raw(" "),
Span::styled(format!("· {} running", members.len()), theme::muted()),
]);
render_bulk_dialog(
frame,
app,
" Restart stack? ",
identity,
members,
crate::messages::CONTAINER_STACK_RESTART_BODY,
("restart", "keep"),
);
}
pub fn render_host_restart_all(frame: &mut Frame, app: &mut App) {
let Screen::ConfirmHostRestartAll { alias, members } = &app.screen else {
return;
};
let identity = Line::from(vec![
Span::raw(" "),
Span::styled(alias.clone(), theme::bold()),
Span::raw(" "),
Span::styled(format!("· {} running", members.len()), theme::muted()),
]);
render_bulk_dialog(
frame,
app,
" Restart all containers on host? ",
identity,
members,
crate::messages::CONTAINER_HOST_RESTART_ALL_BODY,
("restart", "keep"),
);
}
pub fn render_host_stop_all(frame: &mut Frame, app: &mut App) {
let Screen::ConfirmHostStopAll { alias, members } = &app.screen else {
return;
};
let identity = Line::from(vec![
Span::raw(" "),
Span::styled(alias.clone(), theme::bold()),
Span::raw(" "),
Span::styled(format!("· {} running", members.len()), theme::muted()),
]);
render_bulk_dialog(
frame,
app,
" Stop all containers on host? ",
identity,
members,
crate::messages::CONTAINER_HOST_STOP_ALL_BODY,
("stop", "keep"),
);
}
fn render_bulk_dialog(
frame: &mut Frame,
app: &App,
title: &str,
identity: Line<'static>,
members: &[crate::app::StackMember],
body: &str,
verbs: (&str, &str),
) {
let mut content: Vec<Line<'static>> = vec![identity, Line::from("")];
for m in members {
let uptime = m.uptime.clone().unwrap_or_else(|| "-".to_string());
content.push(Line::from(vec![
Span::raw(" "),
Span::raw(design::ICON_ONLINE),
Span::raw(" "),
Span::styled(m.container_name.clone(), theme::bold()),
Span::raw(" "),
Span::styled(uptime, theme::muted()),
]));
}
content.push(Line::from(""));
content.push(Line::from(vec![
Span::raw(" "),
Span::styled(body.to_string(), theme::muted()),
]));
let footer_spans = design::confirm_footer_destructive(verbs.0, verbs.1)
.to_line()
.spans;
design::render_confirm_popup(
frame,
64,
design::PopupKind::Destructive,
title,
content,
footer_spans,
app,
);
}
pub fn render_stop(frame: &mut Frame, app: &mut App) {
let Screen::ConfirmContainerStop {
alias,
container_name,
project,
uptime,
..
} = &app.screen
else {
return;
};
render_dialog(
frame,
app,
" Stop container? ",
container_name,
alias,
project.as_deref(),
uptime.as_deref(),
crate::messages::CONTAINER_STOP_BODY,
("stop", "keep"),
);
}
#[allow(clippy::too_many_arguments)]
fn render_dialog(
frame: &mut Frame,
app: &App,
title: &str,
name: &str,
alias: &str,
project: Option<&str>,
uptime: Option<&str>,
body: &str,
verbs: (&str, &str),
) {
let identity_line = Line::from(vec![
Span::raw(" "),
Span::styled(name.to_string(), theme::bold()),
Span::raw(" "),
Span::styled(format!("on {}", alias), theme::muted()),
]);
let mut meta_parts: Vec<String> = Vec::new();
if let Some(p) = project {
meta_parts.push(p.to_string());
}
if let Some(u) = uptime {
meta_parts.push(format!("Up {}", u));
}
let meta_line = if meta_parts.is_empty() {
Line::from("")
} else {
Line::from(vec![
Span::raw(" "),
Span::styled(meta_parts.join(" · "), theme::muted()),
])
};
let body_line = Line::from(vec![
Span::raw(" "),
Span::styled(body.to_string(), theme::muted()),
]);
let content: Vec<Line<'static>> = vec![identity_line, meta_line, Line::from(""), body_line];
let footer_spans = design::confirm_footer_destructive(verbs.0, verbs.1)
.to_line()
.spans;
design::render_confirm_popup(
frame,
60,
design::PopupKind::Destructive,
title,
content,
footer_spans,
app,
);
}