public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured
@ 2025-12-03  9:59 Dominik Csapak
  2025-12-03  9:59 ` [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard/views: add subscription notice in status row Dominik Csapak
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Dominik Csapak @ 2025-12-03  9:59 UTC (permalink / raw)
  To: pdm-devel

by checking the 'total_nodes' value of the subscription for 0

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 ui/src/lib.rs | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/ui/src/lib.rs b/ui/src/lib.rs
index 20dcec8b..76d60a37 100644
--- a/ui/src/lib.rs
+++ b/ui/src/lib.rs
@@ -2,6 +2,7 @@ use js_sys::{Array, JsString, Object};
 use pdm_api_types::remote_updates::RemoteUpdateSummary;
 use pdm_api_types::remotes::RemoteType;
 use pdm_api_types::resource::{PveLxcResource, PveQemuResource};
+use pdm_api_types::subscription::PdmSubscriptionInfo;
 use pdm_client::types::Resource;
 use proxmox_deb_version::Version;
 use serde::{Deserialize, Serialize};
@@ -241,7 +242,15 @@ pub(crate) fn locale_compare(first: String, second: &str, numeric: bool) -> std:
 /// Returns true if the global subscription checks succeeded
 pub async fn check_subscription() -> bool {
     let data: Result<Value, _> = http_get("/nodes/localhost/subscription", None).await;
-    proxmox_yew_comp::subscription_is_active(Some(&data))
+    let mut is_active = proxmox_yew_comp::subscription_is_active(Some(&data));
+    if !is_active {
+        if let Ok(Ok(info)) = data.map(serde_json::from_value::<PdmSubscriptionInfo>) {
+            if info.statistics.total_nodes == 0 {
+                is_active = true;
+            }
+        }
+    }
+    is_active
 }
 
 /// Extract the version of a specific package from `RemoteUpdateSummary` for a specific node
-- 
2.47.3



_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard/views: add subscription notice in status row
  2025-12-03  9:59 [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured Dominik Csapak
@ 2025-12-03  9:59 ` Dominik Csapak
  2025-12-03  9:59 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: views: make Subscription panel not required anymore Dominik Csapak
  2025-12-03 12:08 ` [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured Thomas Lamprecht
  2 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2025-12-03  9:59 UTC (permalink / raw)
  To: pdm-devel

This adds a short subscription notice to the status row.
It will be loaded together with the normal refresh.

It currently only shows the following states:
* No remotes configured (warning)
* No valid subscriptions (error)
* Valid subscriptions (good)

It reuses the pdm backend subscription check for this.
If there is a message or an error from the api call, show that as
tooltip.

A click on the notice routes to the subscriptions panel of PDM, where
more info about the statistics is outlined.

Downside of this approach is that we might load the subscription info
twice on a fresh login, once for the login popup check, and once for the
dashboard/view if one is open after login.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 ui/Cargo.toml                  |  1 +
 ui/src/dashboard/status_row.rs | 86 ++++++++++++++++++++++++++++++++--
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/ui/Cargo.toml b/ui/Cargo.toml
index 12c1ff45..d5124340 100644
--- a/ui/Cargo.toml
+++ b/ui/Cargo.toml
@@ -39,6 +39,7 @@ proxmox-client = "1"
 proxmox-human-byte = "1"
 proxmox-login = "1"
 proxmox-schema = "5"
+proxmox-subscription = { version = "1.0.1", features = ["api-types"], default-features = false }
 proxmox-rrd-api-types = "1"
 proxmox-node-status = "1"
 pbs-api-types = { version = "1.0.3", features = [ "enum-fallback" ] }
diff --git a/ui/src/dashboard/status_row.rs b/ui/src/dashboard/status_row.rs
index e1af6697..582a9b87 100644
--- a/ui/src/dashboard/status_row.rs
+++ b/ui/src/dashboard/status_row.rs
@@ -1,19 +1,27 @@
+use anyhow::Error;
 use gloo_timers::callback::Interval;
 use yew::html::IntoPropValue;
 use yew::{Component, Properties};
+use yew_router::prelude::RouterScopeExt;
+use yew_router::AnyRoute;
 
-use pwt::css;
 use pwt::prelude::*;
 use pwt::state::SharedState;
+use pwt::{css, AsyncPool};
 use pwt::{
     css::AlignItems,
     widget::{ActionIcon, Container, Row, Tooltip},
 };
 use pwt_macros::{builder, widget};
 
+use proxmox_subscription::SubscriptionStatus;
+use proxmox_yew_comp::subscription_icon;
 use proxmox_yew_comp::utils::render_epoch;
 
+use pdm_api_types::subscription::PdmSubscriptionInfo;
+
 use crate::dashboard::view::EditingMessage;
+use crate::LoadResult;
 
 #[widget(comp=PdmDashboardStatusRow)]
 #[derive(Properties, PartialEq, Clone)]
@@ -51,6 +59,7 @@ impl DashboardStatusRow {
 pub enum Msg {
     /// The bool denotes if the reload comes from the click or the timer.
     Reload(bool),
+    SubscriptionInfoLoaded(Result<PdmSubscriptionInfo, Error>),
     Edit(EditingMessage),
 }
 
@@ -59,6 +68,9 @@ pub struct PdmDashboardStatusRow {
     _interval: Interval,
     loading: bool,
     edit: bool,
+
+    async_pool: AsyncPool,
+    subscription_info: LoadResult<PdmSubscriptionInfo, Error>,
 }
 
 impl PdmDashboardStatusRow {
@@ -73,6 +85,13 @@ impl PdmDashboardStatusRow {
 
         _interval
     }
+
+    fn load_subscription(&self, ctx: &yew::Context<Self>) {
+        self.async_pool.send_future(ctx.link().clone(), async move {
+            let res = proxmox_yew_comp::http_get("/nodes/localhost/subscription", None).await;
+            Msg::SubscriptionInfoLoaded(res)
+        });
+    }
 }
 
 impl Component for PdmDashboardStatusRow {
@@ -80,11 +99,15 @@ impl Component for PdmDashboardStatusRow {
     type Properties = DashboardStatusRow;
 
     fn create(ctx: &yew::Context<Self>) -> Self {
-        Self {
+        let this = Self {
             _interval: Self::create_interval(ctx),
             loading: false,
             edit: false,
-        }
+            async_pool: AsyncPool::new(),
+            subscription_info: LoadResult::new(),
+        };
+        this.load_subscription(ctx);
+        this
     }
 
     fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
@@ -92,6 +115,7 @@ impl Component for PdmDashboardStatusRow {
         match msg {
             Msg::Reload(clicked) => {
                 props.on_reload.emit(clicked);
+                self.load_subscription(ctx);
                 self.loading = true;
                 true
             }
@@ -102,6 +126,10 @@ impl Component for PdmDashboardStatusRow {
                 }
                 true
             }
+            Msg::SubscriptionInfoLoaded(res) => {
+                self.subscription_info.update(res);
+                true
+            }
         }
     }
 
@@ -116,7 +144,8 @@ impl Component for PdmDashboardStatusRow {
 
     fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
         let props = ctx.props();
-        let is_loading = props.last_refresh.is_none() || self.loading;
+        let is_loading =
+            props.last_refresh.is_none() || self.loading || !self.subscription_info.has_data();
         let on_settings_click = props.on_settings_click.clone();
         Row::new()
             .gap(1)
@@ -141,6 +170,18 @@ impl Component for PdmDashboardStatusRow {
                 }
                 None => tr!("Now refreshing"),
             }))
+            .with_optional_child(create_subscription_notice(&self.subscription_info).map(
+                |element| {
+                    element.class("pwt-pointer").onclick({
+                        let link = ctx.link().clone();
+                        move |_| {
+                            if let Some(nav) = link.navigator() {
+                                nav.push(&AnyRoute::new("/subscription"));
+                            }
+                        }
+                    })
+                },
+            ))
             .with_flex_spacer()
             .with_optional_child(props.editing_state.clone().and_then(|_| {
                 (!self.edit).then_some({
@@ -190,3 +231,40 @@ impl Component for PdmDashboardStatusRow {
             .into()
     }
 }
+
+fn create_subscription_notice(
+    subscriptions: &LoadResult<PdmSubscriptionInfo, Error>,
+) -> Option<Tooltip> {
+    if !subscriptions.has_data() {
+        return None;
+    }
+    let mut text = tr!("No valid subscriptions");
+    let mut icon = subscription_icon(&SubscriptionStatus::NotFound.to_string());
+    let mut tooltip = None;
+
+    if let Some(subscriptions) = &subscriptions.data {
+        if subscriptions.statistics.total_nodes == 0 {
+            text = tr!("No remotes configured");
+            icon = subscription_icon("unknown");
+        } else if let SubscriptionStatus::Active = subscriptions.info.status {
+            text = tr!("Valid subscriptions");
+            icon = subscription_icon(&subscriptions.info.status.to_string());
+        } else if let Some(msg) = &subscriptions.info.message {
+            tooltip = Some(msg.clone());
+        }
+    } else if let Some(err) = &subscriptions.error {
+        tooltip = Some(err.to_string())
+    }
+
+    Some(
+        Tooltip::new(
+            Row::new()
+                .padding_x(2)
+                .gap(2)
+                .class(css::AlignItems::Center)
+                .with_child(icon.large())
+                .with_child(Container::new().with_child(text)),
+        )
+        .tip(tooltip),
+    )
+}
-- 
2.47.3



_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [pdm-devel] [PATCH datacenter-manager 3/3] ui: views: make Subscription panel not required anymore
  2025-12-03  9:59 [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured Dominik Csapak
  2025-12-03  9:59 ` [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard/views: add subscription notice in status row Dominik Csapak
@ 2025-12-03  9:59 ` Dominik Csapak
  2025-12-03 12:08 ` [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured Thomas Lamprecht
  2 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2025-12-03  9:59 UTC (permalink / raw)
  To: pdm-devel

Since we now show the subscription state of pdm always in the status row,
the subscription panel in views are useful, but not required anymore.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 ui/src/dashboard/view.rs | 38 +-------------------------------------
 1 file changed, 1 insertion(+), 37 deletions(-)

diff --git a/ui/src/dashboard/view.rs b/ui/src/dashboard/view.rs
index 0606f1a9..f45f4622 100644
--- a/ui/src/dashboard/view.rs
+++ b/ui/src/dashboard/view.rs
@@ -12,7 +12,7 @@ use pwt::css;
 use pwt::prelude::*;
 use pwt::props::StorageLocation;
 use pwt::state::{PersistentState, SharedState};
-use pwt::widget::{error_message, form::FormContext, Column, Container, Progress, Row};
+use pwt::widget::{error_message, form::FormContext, Column, Container, Progress};
 use pwt::AsyncPool;
 
 use crate::dashboard::refresh_config_edit::{
@@ -288,23 +288,6 @@ fn required_api_calls(layout: &ViewLayout) -> (bool, bool, bool) {
     (status, top_entities, task_statistics)
 }
 
-fn has_sub_panel(layout: Option<&ViewTemplate>) -> bool {
-    match layout.map(|template| &template.layout) {
-        Some(ViewLayout::Rows { rows }) => {
-            for row in rows {
-                for item in row {
-                    if item.r#type == WidgetType::Subscription {
-                        return true;
-                    }
-                }
-            }
-        }
-        None => {}
-    }
-
-    false
-}
-
 impl Component for ViewComp {
     type Message = Msg;
     type Properties = View;
@@ -479,25 +462,6 @@ impl Component for ViewComp {
                 ),
         );
 
-        if !has_sub_panel(self.template.data.as_ref()) {
-            let subs = self.render_args.subscriptions.clone();
-            let link = ctx.link().clone();
-            view.add_child(
-                Row::new()
-                    .padding_x(4)
-                    .padding_bottom(4)
-                    .padding_top(0)
-                    .class("pwt-content-spacer-colors")
-                    .with_child(
-                        create_subscription_panel(
-                            subs.clone(),
-                            link.clone()
-                                .callback(move |_| Msg::ShowSubscriptionsDialog(true)),
-                        )
-                        .flex(1.0),
-                    ),
-            );
-        }
         match self.template.data.as_ref().map(|template| &template.layout) {
             Some(ViewLayout::Rows { rows }) => {
                 view.add_child(
-- 
2.47.3



_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured
  2025-12-03  9:59 [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured Dominik Csapak
  2025-12-03  9:59 ` [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard/views: add subscription notice in status row Dominik Csapak
  2025-12-03  9:59 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: views: make Subscription panel not required anymore Dominik Csapak
@ 2025-12-03 12:08 ` Thomas Lamprecht
  2 siblings, 0 replies; 4+ messages in thread
From: Thomas Lamprecht @ 2025-12-03 12:08 UTC (permalink / raw)
  To: pdm-devel, Dominik Csapak

On Wed, 03 Dec 2025 10:59:37 +0100, Dominik Csapak wrote:
> by checking the 'total_nodes' value of the subscription for 0
> 
> 

Applied, thanks!

[1/3] ui: mark subscription check as active if no remotes are configured
      commit: 7f48316c76dae95f7e475f22a0c33320a29ab594
[2/3] ui: dashboard/views: add subscription notice in status row
      commit: 7d8836b31f5a01dc6028bde4627c0083733863f3
[3/3] ui: views: make Subscription panel not required anymore
      commit: 65a4edaa299bce5b1430c3c587638373defb10a3


_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-12-03 12:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-03  9:59 [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured Dominik Csapak
2025-12-03  9:59 ` [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard/views: add subscription notice in status row Dominik Csapak
2025-12-03  9:59 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: views: make Subscription panel not required anymore Dominik Csapak
2025-12-03 12:08 ` [pdm-devel] [PATCH datacenter-manager 1/3] ui: mark subscription check as active if no remotes are configured Thomas Lamprecht

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal