Skip to content

Commit

Permalink
feat: execute node actions one at a time upon multiple selected
Browse files Browse the repository at this point in the history
  • Loading branch information
bochaco committed Dec 9, 2024
1 parent d3ae1b9 commit ac99a01
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 45 deletions.
9 changes: 4 additions & 5 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use tokio::{
};

#[cfg(feature = "hydrate")]
use gloo_timers::future::TimeoutFuture;
use gloo_timers::future::sleep;
use leptos::prelude::*;
use leptos_meta::{provide_meta_context, MetaTags, Script, Stylesheet, Title};
use leptos_router::{
Expand Down Expand Up @@ -89,9 +89,8 @@ impl Default for AppSettings {

// Maximum number of metrics data points to be kept per node on DB cache.
pub const METRICS_MAX_SIZE_PER_CONTAINER: usize = 5_000;

#[cfg(feature = "hydrate")]
const NODES_LIST_POLLING_FREQ_MILLIS: u32 = 5_500;
// How often we poll the backedn to retrieve an up to date list of node instances.
pub const NODES_LIST_POLLING_FREQ_MILLIS: u64 = 5_500;

#[cfg(feature = "ssr")]
#[derive(Clone, FromRef, Debug)]
Expand Down Expand Up @@ -305,7 +304,7 @@ fn spawn_nodes_list_polling() {
}
}

TimeoutFuture::new(NODES_LIST_POLLING_FREQ_MILLIS).await;
sleep(Duration::from_millis(NODES_LIST_POLLING_FREQ_MILLIS)).await;
}
});
}
11 changes: 7 additions & 4 deletions src/icons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn IconShowLogs() -> impl IntoView {
}

#[component]
pub fn IconCloseModal() -> impl IntoView {
pub fn IconCancel() -> impl IntoView {
view! {
<svg
class="w-3 h-3"
Expand Down Expand Up @@ -80,17 +80,20 @@ pub fn IconRecycle() -> impl IntoView {
pub fn IconRemove() -> impl IntoView {
view! {
<svg
class="w-6 h-6"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
d="M5 7h14m-9 3v8m4-8v8M10 3h4a1 1 0 0 1 1 1v3H9V4a1 1 0 0 1 1-1ZM6 7h12v13a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V7Z"
/>
</svg>
}
Expand Down
95 changes: 66 additions & 29 deletions src/node_actions.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use super::{
app::{get_addr_from_metamask, ClientGlobalState},
app::{get_addr_from_metamask, ClientGlobalState, NODES_LIST_POLLING_FREQ_MILLIS},
helpers::{add_node_instances, remove_node_instance, show_alert_msg},
icons::{
IconAddNode, IconCloseModal, IconManageNodes, IconOpenActionsMenu, IconPasteAddr,
IconRecycle, IconRemove, IconStartNode, IconStopNode, IconUpgradeNode,
IconAddNode, IconCancel, IconManageNodes, IconOpenActionsMenu, IconPasteAddr, IconRecycle,
IconRemove, IconStartNode, IconStopNode, IconUpgradeNode,
},
node_instance::{NodeInstanceInfo, NodeStatus},
server_api::{
Expand All @@ -12,8 +12,9 @@ use super::{
};

use alloy::primitives::Address;
use gloo_timers::future::sleep;
use leptos::{logging, prelude::*, task::spawn_local};
use std::num::ParseIntError;
use std::{num::ParseIntError, time::Duration};

// TODO: find next available port numbers by looking at already used ones
const DEFAULT_NODE_PORT: u16 = 12000;
Expand Down Expand Up @@ -62,7 +63,7 @@ impl NodeAction {
res
}
Self::Upgrade => {
if !previous_status.is_active() {
if !info.read_untracked().upgradeable() {
return;
}
info.update(|node| node.status = NodeStatus::Upgrading);
Expand Down Expand Up @@ -105,21 +106,24 @@ impl NodeAction {
pub fn NodesActionsView() -> impl IntoView {
let context = expect_context::<ClientGlobalState>();
let is_selecting_nodes = move || context.selecting_nodes.read().0;
let is_selection_executing = move || context.selecting_nodes.read().1;
let show_actions_menu = RwSignal::new(false);
let actions_class = move || {
if !is_selecting_nodes() {
"hidden"
} else if context.selecting_nodes.read().2.is_empty() {
} else if is_selection_executing() || context.selecting_nodes.read().2.is_empty() {
"btn-manage-nodes-action btn-disabled"
} else {
"btn-manage-nodes-action"
}
};

let apply_on_selected = Action::new(move |action: &NodeAction| {
let apply_on_selected = move |action: NodeAction| {
show_actions_menu.set(false);
let action = action.clone();
context.selecting_nodes.update(|(_, g, _)| *g = false);
context
.selecting_nodes
.update(|(_, executing, _)| *executing = true);
let selected = context.selecting_nodes.get_untracked().2;
let nodes = context
.nodes
Expand All @@ -129,18 +133,26 @@ pub fn NodesActionsView() -> impl IntoView {
.cloned()
.collect::<Vec<_>>();

async move {
spawn_local(async move {
let was_cancelled = move || !context.selecting_nodes.read_untracked().0;
for info in nodes {
if was_cancelled() {
break;
}

action.apply(&info).await;
context.selecting_nodes.update(|(_, _, s)| {
s.remove(&info.read_untracked().container_id);
})
while !was_cancelled() && info.read().status.is_transitioning() {
sleep(Duration::from_millis(NODES_LIST_POLLING_FREQ_MILLIS)).await;
}
}
context.selecting_nodes.update(|(f, _, _)| {

context.selecting_nodes.update(|(f, executing, s)| {
*f = false;
*executing = false;
s.clear();
});
}
});
});
};

// signal to switch the panel to add nodes
let modal_visibility = RwSignal::new(false);
Expand All @@ -158,23 +170,46 @@ pub fn NodesActionsView() -> impl IntoView {
<button
type="button"
on:click=move |_| {
let is_selecting = context.selecting_nodes.read_untracked().0;
context
.selecting_nodes
.update(|(f, g, _)| {
*f = !is_selecting;
*g = true;
});
.update(|(f, g, s)| {
s.clear();
*f = false;
*g = false;
})
}
data-tooltip-target="tooltip-manage"
data-tooltip-target="tooltip-cancel"
data-tooltip-placement="left"
class=move || {
if is_selecting_nodes() {
"btn-manage-nodes-action ring-4 ring-gray-300 outline-none dark:ring-gray-400"
} else {
"btn-manage-nodes-action"
"hidden"
}
}
>
<IconCancel />
<span class="sr-only">Cancel</span>
</button>
<div
id="tooltip-cancel"
role="tooltip"
class="absolute z-10 invisible inline-block w-auto px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"
>
Cancel
<div class="tooltip-arrow" data-popper-arrow></div>
</div>

<button
type="button"
on:click=move |_| {
context.selecting_nodes.update(|(f, _, _)| *f = true);
}
data-tooltip-target="tooltip-manage"
data-tooltip-placement="left"
class=move || {
if is_selecting_nodes() { "hidden" } else { "btn-manage-nodes-action" }
}
>
<IconManageNodes />
<span class="sr-only">Manage</span>
Expand All @@ -191,7 +226,7 @@ pub fn NodesActionsView() -> impl IntoView {
<button
type="button"
on:click=move |_| {
apply_on_selected.dispatch(NodeAction::Start);
apply_on_selected(NodeAction::Start);
}
data-tooltip-target="tooltip-start"
data-tooltip-placement="left"
Expand All @@ -212,7 +247,7 @@ pub fn NodesActionsView() -> impl IntoView {
<button
type="button"
on:click=move |_| {
apply_on_selected.dispatch(NodeAction::Stop);
apply_on_selected(NodeAction::Stop);
}
data-tooltip-target="tooltip-stop"
data-tooltip-placement="left"
Expand All @@ -233,7 +268,7 @@ pub fn NodesActionsView() -> impl IntoView {
<button
type="button"
on:click=move |_| {
apply_on_selected.dispatch(NodeAction::Upgrade);
apply_on_selected(NodeAction::Upgrade);
}
data-tooltip-target="tooltip-upgrade"
data-tooltip-placement="left"
Expand All @@ -254,7 +289,7 @@ pub fn NodesActionsView() -> impl IntoView {
<button
type="button"
on:click=move |_| {
apply_on_selected.dispatch(NodeAction::Recycle);
apply_on_selected(NodeAction::Recycle);
}
data-tooltip-target="tooltip-recycle"
data-tooltip-placement="left"
Expand All @@ -275,7 +310,7 @@ pub fn NodesActionsView() -> impl IntoView {
<button
type="button"
on:click=move |_| {
apply_on_selected.dispatch(NodeAction::Remove);
apply_on_selected(NodeAction::Remove);
}
data-tooltip-target="tooltip-remove"
data-tooltip-placement="left"
Expand All @@ -301,7 +336,9 @@ pub fn NodesActionsView() -> impl IntoView {
}
data-tooltip-target="tooltip-add-nodes"
data-tooltip-placement="left"
class="btn-manage-nodes-action"
class=move || {
if is_selecting_nodes() { "hidden" } else { "btn-manage-nodes-action" }
}
>
<IconAddNode />
<span class="sr-only">Add nodes</span>
Expand Down Expand Up @@ -352,7 +389,7 @@ pub fn NodesActionsView() -> impl IntoView {
class="end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
on:click=move |_| modal_visibility.set(false)
>
<IconCloseModal />
<IconCancel />
<span class="sr-only">Cancel</span>
</button>
</div>
Expand Down
10 changes: 5 additions & 5 deletions src/nodes_list_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{
chart_view::{node_metrics_update, ChartSeriesData, NodeChartView},
helpers::{node_logs_stream, show_alert_msg},
icons::{
IconCloseModal, IconRecycle, IconRemove, IconShowChart, IconShowLogs, IconStartNode,
IconCancel, IconRecycle, IconRemove, IconShowChart, IconShowLogs, IconStartNode,
IconStopNode, IconUpgradeNode,
},
node_actions::NodeAction,
Expand Down Expand Up @@ -70,7 +70,7 @@ pub fn NodesListView() -> impl IntoView {
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
on:click=move |_| context.logs_stream_on_for.set(None)
>
<IconCloseModal />
<IconCancel />
</label>
</div>
</div>
Expand All @@ -93,7 +93,7 @@ pub fn NodesListView() -> impl IntoView {
context.metrics_update_on_for.set(None);
}
>
<IconCloseModal />
<IconCancel />
</label>
</div>
</div>
Expand Down Expand Up @@ -147,7 +147,7 @@ fn BatchInProgressView(batch_info: RwSignal<Option<BatchInProgress>>) -> impl In
}
})
>
<IconRemove />
<IconCancel />
</button>
</div>
</div>
Expand Down Expand Up @@ -238,7 +238,7 @@ fn NodeInstanceView(
.read()
.2
.contains(&info.read_untracked().container_id)
disabled=move || !context.selecting_nodes.read().1
disabled=move || context.selecting_nodes.read().1
on:change=move |ev| {
if event_target_checked(&ev) {
context
Expand Down
4 changes: 2 additions & 2 deletions src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{
app::AppSettings,
helpers::show_alert_msg,
icons::IconCloseModal,
icons::IconCancel,
server_api::{get_settings, update_settings},
};

Expand Down Expand Up @@ -42,7 +42,7 @@ pub fn SettingsView(settings_panel: RwSignal<bool>) -> impl IntoView {
class="end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
on:click=move |_| settings_panel.set(false)
>
<IconCloseModal />
<IconCancel />
<span class="sr-only">Cancel</span>
</button>
</div>
Expand Down

0 comments on commit ac99a01

Please sign in to comment.