use std::borrow::Cow;
use rust_i18n::t;
use super::ResourceTab;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ActionKind {
Start,
Shutdown,
Reboot,
Clone,
Backup,
Delete
}
impl ActionKind {
#[must_use]
pub const fn label(self) -> &'static str {
match self {
Self::Start => "Start",
Self::Shutdown => "Shutdown",
Self::Reboot => "Reboot",
Self::Clone => "Clone",
Self::Backup => "Backup",
Self::Delete => "Delete"
}
}
#[must_use]
pub fn display_label(self) -> Cow<'static, str> {
match self {
Self::Start => t!("app.action_start"),
Self::Shutdown => t!("app.action_shutdown"),
Self::Reboot => t!("app.action_reboot"),
Self::Clone => t!("app.action_clone"),
Self::Backup => t!("app.action_backup"),
Self::Delete => t!("app.action_delete")
}
}
#[must_use]
pub const fn is_destructive(self) -> bool {
matches!(self, Self::Delete)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PendingAction {
pub tab: ResourceTab,
pub kind: ActionKind,
pub resource_id: String,
pub resource_name: String
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ActionMenu {
pub tab: ResourceTab,
pub resource_id: String,
pub resource_name: String,
pub actions: Vec<ActionKind>,
pub selected: usize
}
impl super::App {
pub fn open_action_menu(&mut self) {
let actions = self.active_tab.actions();
if actions.is_empty() {
self.status_message = Some(t!("app.no_actions").to_string());
return;
}
if let Some((id, name)) = self.selected_resource() {
self.action_menu = Some(ActionMenu {
tab: self.active_tab,
resource_id: id,
resource_name: name,
actions: actions.to_vec(),
selected: 0
});
}
}
pub fn close_action_menu(&mut self) {
self.action_menu = None;
}
#[must_use]
pub const fn action_menu_open(&self) -> bool {
self.action_menu.is_some()
}
#[must_use]
pub const fn action_menu(&self) -> Option<&ActionMenu> {
self.action_menu.as_ref()
}
pub const fn menu_next(&mut self) {
if let Some(menu) = self.action_menu.as_mut()
&& !menu.actions.is_empty()
{
menu.selected = (menu.selected + 1) % menu.actions.len();
}
}
pub const fn menu_previous(&mut self) {
if let Some(menu) = self.action_menu.as_mut() {
let len = menu.actions.len();
if len > 0 {
menu.selected = (menu.selected + len - 1) % len;
}
}
}
pub fn menu_select(&mut self) {
let Some(menu) = self.action_menu.take() else {
return;
};
let Some(&action) = menu.actions.get(menu.selected) else {
return;
};
let pending = PendingAction {
tab: menu.tab,
kind: action,
resource_id: menu.resource_id,
resource_name: menu.resource_name
};
if action.is_destructive() {
self.confirm = Some(pending);
} else {
self.dispatch = Some(pending);
}
}
pub fn confirm_action(&mut self) {
self.dispatch = self.confirm.take();
}
pub fn cancel_action(&mut self) {
self.confirm = None;
}
#[must_use]
pub const fn pending_action(&self) -> Option<&PendingAction> {
self.confirm.as_ref()
}
#[must_use]
pub const fn awaiting_confirm(&self) -> bool {
self.confirm.is_some()
}
#[must_use]
pub const fn take_dispatch(&mut self) -> Option<PendingAction> {
self.dispatch.take()
}
}