[pdm-devel] [PATCH datacenter-manager 3/4] ui: pbs: move node overview to tab and add update tab
Lukas Wagner
l.wagner at proxmox.com
Thu Nov 20 11:36:19 CET 2025
PVE remote had an 'Updates' tab for a while now. This commit adds the
same thing for PBS remotes.
Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
---
ui/src/pbs/mod.rs | 4 +-
ui/src/pbs/node/mod.rs | 114 ++++++++++++++++++++++++++++++++++++
ui/src/pbs/node/overview.rs | 11 +---
3 files changed, 118 insertions(+), 11 deletions(-)
diff --git a/ui/src/pbs/mod.rs b/ui/src/pbs/mod.rs
index 1fdb417f..75ed9926 100644
--- a/ui/src/pbs/mod.rs
+++ b/ui/src/pbs/mod.rs
@@ -24,11 +24,11 @@ pub use datastore::DatastorePanel;
mod namespace_selector;
mod node;
-use node::overview::PbsNodeOverviewPanel;
mod snapshot_list;
pub use snapshot_list::SnapshotList;
+use crate::pbs::node::PbsNodePanel;
use crate::pbs::tree::PbsTree;
use crate::{get_deep_url, pdm_client};
@@ -108,7 +108,7 @@ impl LoadableComponent for PbsRemoteComp {
let props = ctx.props();
let content: Html = match &self.view {
- tree::PbsTreeNode::Root => PbsNodeOverviewPanel::new(props.remote.clone()).into(),
+ tree::PbsTreeNode::Root => PbsNodePanel::new(props.remote.clone()).into(),
tree::PbsTreeNode::Datastore(data_store_config) => {
DatastorePanel::new(props.remote.clone(), data_store_config.clone()).into()
}
diff --git a/ui/src/pbs/node/mod.rs b/ui/src/pbs/node/mod.rs
index 8468a02a..5cd210f8 100644
--- a/ui/src/pbs/node/mod.rs
+++ b/ui/src/pbs/node/mod.rs
@@ -1 +1,115 @@
+use std::rc::Rc;
+
+use proxmox_yew_comp::AptPackageManager;
+use yew::{
+ virtual_dom::{VComp, VNode},
+ Context,
+};
+
+use pwt::{
+ css::{AlignItems, ColorScheme},
+ prelude::*,
+ props::{ContainerBuilder, WidgetBuilder},
+ widget::{Fa, Row, TabBarItem, TabPanel},
+};
+
pub(crate) mod overview;
+
+use overview::PbsNodeOverviewPanel;
+
+use crate::get_deep_url_low_level;
+
+#[derive(Clone, Debug, Eq, PartialEq, Properties)]
+pub struct PbsNodePanel {
+ /// The remote to show
+ pub remote: String,
+}
+
+impl PbsNodePanel {
+ pub fn new(remote: String) -> Self {
+ yew::props!(Self { remote })
+ }
+}
+
+impl From<PbsNodePanel> for VNode {
+ fn from(val: PbsNodePanel) -> Self {
+ VComp::new::<PbsNodePanelComp>(Rc::new(val), None).into()
+ }
+}
+
+struct PbsNodePanelComp;
+
+impl yew::Component for PbsNodePanelComp {
+ type Message = ();
+ type Properties = PbsNodePanel;
+
+ fn create(_ctx: &yew::Context<Self>) -> Self {
+ Self
+ }
+
+ fn changed(&mut self, ctx: &Context<Self>, old_props: &Self::Properties) -> bool {
+ let props = ctx.props();
+
+ props.remote != old_props.remote
+ }
+
+ fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
+ let props = ctx.props();
+
+ let title: Html = Row::new()
+ .gap(2)
+ .class(AlignItems::Baseline)
+ .with_child(Fa::new("building"))
+ .with_child(tr!("Node"))
+ .into();
+
+ TabPanel::new()
+ .class(pwt::css::FlexFit)
+ .title(title)
+ .class(ColorScheme::Neutral)
+ .with_item_builder(
+ TabBarItem::new()
+ .key("status_view")
+ .label(tr!("Overview"))
+ .icon_class("fa fa-tachometer"),
+ {
+ let remote = props.remote.clone();
+ move |_| PbsNodeOverviewPanel::new(remote.clone()).into()
+ },
+ )
+ .with_item_builder(
+ TabBarItem::new()
+ .key("update_view")
+ .label(tr!("Updates"))
+ .icon_class("fa fa-refresh"),
+ {
+ let remote = props.remote.clone();
+ let link = ctx.link().clone();
+ move |_| {
+ let base_url = format!("/pbs/remotes/{remote}/nodes/localhost/apt");
+ let task_base_url = format!("/pbs/remotes/{remote}/tasks");
+
+ AptPackageManager::new()
+ .base_url(base_url)
+ .task_base_url(task_base_url)
+ .enable_upgrade(true)
+ .on_upgrade({
+ let remote = remote.clone();
+ let link = link.clone();
+
+ move |_| {
+ let hash = "#pbsServerAdministration:updates";
+ if let Some(url) =
+ get_deep_url_low_level(&link, &remote, None, hash)
+ {
+ let _ = gloo_utils::window().open_with_url(&url.href());
+ }
+ }
+ })
+ .into()
+ }
+ },
+ )
+ .into()
+ }
+}
diff --git a/ui/src/pbs/node/overview.rs b/ui/src/pbs/node/overview.rs
index d15eda04..da5a4085 100644
--- a/ui/src/pbs/node/overview.rs
+++ b/ui/src/pbs/node/overview.rs
@@ -7,10 +7,10 @@ use yew::{
use proxmox_yew_comp::{node_info, RRDGraph, RRDTimeframe, RRDTimeframeSelector, Series};
use pwt::{
- css::{AlignItems, ColorScheme, FlexFit, JustifyContent},
+ css::{ColorScheme, FlexFit, JustifyContent},
prelude::*,
props::{ContainerBuilder, WidgetBuilder},
- widget::{error_message, Column, Container, Fa, Panel, Progress, Row},
+ widget::{error_message, Column, Container, Panel, Progress, Row},
AsyncPool,
};
@@ -197,14 +197,7 @@ impl yew::Component for PbsNodeOverviewPanelComp {
fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
let status_comp = node_info(self.status.data.as_ref().map(|s| s.into()));
- let title: Html = Row::new()
- .gap(2)
- .class(AlignItems::Baseline)
- .with_child(Fa::new("tachometer"))
- .with_child(tr! {"Overview"})
- .into();
Panel::new()
- .title(title)
.class(FlexFit)
.class(ColorScheme::Neutral)
.with_child(
--
2.47.3
More information about the pdm-devel
mailing list