public inbox for yew-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui
@ 2026-05-08 15:05 Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-comp 01/20] firewall rules panel: correct the url for the pve cluster firewall rules Shannon Sterz
                   ` (20 more replies)
  0 siblings, 21 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

this series cleans up the pve-yew-mobile-gui a little bit. it does so by first
fixing a bug in proxmox-yew-comp. then pve-yew-mobile-gui is made clippy clean
again. the last six patches add, unify and clean up functionality in the gui.
the main changes are as follows:

* properly populate the rules tab of the existing firewall tabs and comment out
  empty sub-tabs.
* add a firewall tab for container guests and nodes
* two small ui clean ups in how subscription levels and cpu utilization is
  rendered


yew-comp:

Shannon Sterz (1):
  firewall rules panel: correct the url for the pve cluster firewall
    rules

 src/configuration/pve/firewall/firewall_rules_panel.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


yew-mobile-gui:

Shannon Sterz (19):
  cargo.toml: globally ignore certain clippy lints
  main: avoid unnecessary clones
  tree-wide: collapse if statements
  tree-wide: implement the `From` trait instead of the `Into` trait
  tree-wide: implement `Default` for types with an `new()` constructor
  tree-wide: remove unnecessary lazy evaluations
  tree-wide: remove needless borrows
  configuration page: remove redundant static lifetimes
  resources/configuration page: remove useless `.into()` calls
  tree-wide: fix several clippy lints
  dashboard: use proper plural translation string instead of "CPU(s)"
  configuration: clarify that "Firewall" shows the cluster's firewall
  cluster/qemu firewall: use rules panel and comment out unused tabs
  lxc page: align layout for lxc guest with qemu guests
  lxc: add support for a rudimentary firewall tab for lxc guests
  node status: align layout for node status with guest pages
  node: add a rudimentary firewall tab for cluster nodes
  api types: remove unused file
  resources page: map subscription level analogous to dashboard

 Cargo.toml                                    |   5 +
 src/api_types.rs                              | 131 -------------
 src/main.rs                                   |  25 ++-
 src/pages/mod.rs                              |  13 ++
 src/pages/page_cluster_firewall/mod.rs        |  35 ++--
 src/pages/page_configuartion.rs               |  22 ++-
 src/pages/page_dashboard.rs                   |  43 ++---
 src/pages/page_login.rs                       |  12 +-
 src/pages/page_lxc_status/dashboard_panel.rs  |  70 ++++---
 src/pages/page_lxc_status/firewall_panel.rs   | 172 ++++++++++++++++++
 src/pages/page_lxc_status/mod.rs              |  47 ++++-
 src/pages/page_lxc_tasks.rs                   |   6 +-
 src/pages/page_node_status/dashboard_panel.rs |   6 +-
 src/pages/page_node_status/firewall_panel.rs  | 163 +++++++++++++++++
 src/pages/page_node_status/mod.rs             |  37 +++-
 src/pages/page_node_status/services_panel.rs  |   2 +-
 src/pages/page_node_tasks.rs                  |   6 +-
 src/pages/page_qemu_status/dashboard_panel.rs |  77 ++++----
 src/pages/page_qemu_status/firewall_panel.rs  |  33 ++--
 src/pages/page_qemu_status/mod.rs             |   6 +-
 src/pages/page_qemu_tasks.rs                  |   6 +-
 src/pages/page_resources.rs                   |  50 ++---
 src/pages/page_settings.rs                    |  12 +-
 src/pages/page_storage_status.rs              |   6 +-
 src/pages/page_task_status.rs                 |   6 +-
 src/widgets/guest_backup_panel.rs             |   4 +-
 src/widgets/task_list_button.rs               |  29 +--
 src/widgets/tasks_panel.rs                    |   2 +-
 src/widgets/top_nav_bar.rs                    |  12 +-
 29 files changed, 671 insertions(+), 367 deletions(-)
 delete mode 100644 src/api_types.rs
 create mode 100644 src/pages/page_lxc_status/firewall_panel.rs
 create mode 100644 src/pages/page_node_status/firewall_panel.rs


Summary over all repositories:
  30 files changed, 672 insertions(+), 368 deletions(-)

-- 
Generated by murpp 0.10.0




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

* [PATCH yew-comp 01/20] firewall rules panel: correct the url for the pve cluster firewall rules
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 02/20] cargo.toml: globally ignore certain clippy lints Shannon Sterz
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

this was previously unused, but is needed for the mobile firewall ui

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/configuration/pve/firewall/firewall_rules_panel.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/configuration/pve/firewall/firewall_rules_panel.rs b/src/configuration/pve/firewall/firewall_rules_panel.rs
index 3f9a9d0..2b2c282 100644
--- a/src/configuration/pve/firewall/firewall_rules_panel.rs
+++ b/src/configuration/pve/firewall/firewall_rules_panel.rs
@@ -73,7 +73,7 @@ impl FirewallRulesPanel {
                         percent_encode_component(remote)
                     )
                 } else {
-                    "/pve/firewall/rules".into()
+                    "/cluster/firewall/rules".into()
                 }
             }
             FirewallContext::Node { node } => {
-- 
2.47.3





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

* [PATCH yew-mobile-gui 02/20] cargo.toml: globally ignore certain clippy lints
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-comp 01/20] firewall rules panel: correct the url for the pve cluster firewall rules Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 03/20] main: avoid unnecessary clones Shannon Sterz
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

these three lints are rarely useful in this context and we already
ignore them for proxmox-yew-comp too, so ignore them here.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 Cargo.toml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Cargo.toml b/Cargo.toml
index 85dd597..ffe742b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,3 +47,8 @@ proxmox-client = { version = "1.0", features = ["perl-api-path-builder"] }
 #proxmox-yew-comp = { path = "../proxmox-yew-comp" }
 #pwt = { path = "../proxmox-yew-widget-toolkit" }
 #pwt-macros = { path = "../proxmox-yew-widget-toolkit/pwt-macros" }
+
+[lints.clippy]
+too_many_arguments = "allow"
+enum_variant_names = "allow"
+large_enum_variant = "allow"
-- 
2.47.3





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

* [PATCH yew-mobile-gui 03/20] main: avoid unnecessary clones
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-comp 01/20] firewall rules panel: correct the url for the pve cluster firewall rules Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 02/20] cargo.toml: globally ignore certain clippy lints Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 04/20] tree-wide: collapse if statements Shannon Sterz
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

fixes the clippy lint "clone_on_copy" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/main.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 4941f33..77991fd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -132,7 +132,7 @@ fn switch_route(route: Route) -> Vec<Html> {
         ),
         Route::QemuTasks { vmid, nodename } => (
             switch_route(Route::Qemu {
-                vmid: vmid.clone(),
+                vmid,
                 nodename: nodename.clone(),
             }),
             PageQemuTasks::new(nodename, vmid).into(),
@@ -144,7 +144,7 @@ fn switch_route(route: Route) -> Vec<Html> {
             endtime,
         } => (
             switch_route(Route::QemuTasks {
-                vmid: vmid.clone(),
+                vmid,
                 nodename: nodename.clone(),
             }),
             PageTaskStatus::new(
@@ -165,7 +165,7 @@ fn switch_route(route: Route) -> Vec<Html> {
         ),
         Route::LxcTasks { vmid, nodename } => (
             switch_route(Route::Lxc {
-                vmid: vmid.clone(),
+                vmid,
                 nodename: nodename.clone(),
             }),
             PageLxcTasks::new(nodename, vmid).into(),
@@ -177,7 +177,7 @@ fn switch_route(route: Route) -> Vec<Html> {
             endtime,
         } => (
             switch_route(Route::LxcTasks {
-                vmid: vmid.clone(),
+                vmid,
                 nodename: nodename.clone(),
             }),
             PageTaskStatus::new(
-- 
2.47.3





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

* [PATCH yew-mobile-gui 04/20] tree-wide: collapse if statements
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (2 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 03/20] main: avoid unnecessary clones Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 05/20] tree-wide: implement the `From` trait instead of the `Into` trait Shannon Sterz
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

fixes the clippy lint "clippy::collapsible_if" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/main.rs                                   | 11 ++--
 src/pages/page_dashboard.rs                   | 14 ++--
 src/pages/page_lxc_status/dashboard_panel.rs  | 62 +++++++++---------
 src/pages/page_qemu_status/dashboard_panel.rs | 64 +++++++++----------
 src/pages/page_resources.rs                   | 16 ++---
 5 files changed, 80 insertions(+), 87 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 77991fd..2a91379 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -313,12 +313,11 @@ impl Component for PveMobileApp {
 
     fn create(ctx: &Context<Self>) -> Self {
         let mut server_config = None;
-        if let Some(window) = web_sys::window() {
-            if let Ok(value) = js_sys::Reflect::get(&window, &JsValue::from_str("Proxmox")) {
-                if let Ok(config) = JsValueSerdeExt::into_serde::<ServerConfig>(&value) {
-                    server_config = Some(config);
-                }
-            }
+        if let Some(window) = web_sys::window()
+            && let Ok(value) = js_sys::Reflect::get(&window, &JsValue::from_str("Proxmox"))
+            && let Ok(config) = JsValueSerdeExt::into_serde::<ServerConfig>(&value)
+        {
+            server_config = Some(config);
         }
 
         // set auth info from cookie
diff --git a/src/pages/page_dashboard.rs b/src/pages/page_dashboard.rs
index f33f182..211d66d 100644
--- a/src/pages/page_dashboard.rs
+++ b/src/pages/page_dashboard.rs
@@ -472,13 +472,13 @@ impl Component for PvePageDashboard {
 
         let alert = CACHE.with_borrow(|cache| {
             let mut alert = None;
-            if let Some(status) = &cache.subscription_error {
-                if self.show_subscription_alert || !cache.subscription_confirmed {
-                    alert = Some(
-                        SubscriptionAlert::new(status.clone())
-                            .on_close(ctx.link().callback(|_| Msg::ConfirmSubscription)),
-                    );
-                }
+            if let Some(status) = &cache.subscription_error
+                && (self.show_subscription_alert || !cache.subscription_confirmed)
+            {
+                alert = Some(
+                    SubscriptionAlert::new(status.clone())
+                        .on_close(ctx.link().callback(|_| Msg::ConfirmSubscription)),
+                );
             }
             alert
         });
diff --git a/src/pages/page_lxc_status/dashboard_panel.rs b/src/pages/page_lxc_status/dashboard_panel.rs
index 91afd24..8009dcc 100644
--- a/src/pages/page_lxc_status/dashboard_panel.rs
+++ b/src/pages/page_lxc_status/dashboard_panel.rs
@@ -144,42 +144,38 @@ impl PveLxcDashboardPanel {
             data.status.to_string(),
         ));
 
-        if let Some(Ok(data)) = &self.data {
-            if data.status == IsRunning::Running {
-                if let (Some(cpu), Some(maxcpu)) = (data.cpu, data.cpus) {
-                    let cpu_percentage = if maxcpu == 0.0 {
-                        0.0
-                    } else {
-                        (cpu as f32) / (maxcpu as f32)
-                    };
+        if let Some(Ok(data)) = &self.data
+            && data.status == IsRunning::Running
+        {
+            if let (Some(cpu), Some(maxcpu)) = (data.cpu, data.cpus) {
+                let cpu_percentage = if maxcpu == 0.0 {
+                    0.0
+                } else {
+                    (cpu as f32) / (maxcpu as f32)
+                };
 
-                    tiles.push(
-                        icon_list_tile(Fa::new("cpu"), "CPU", None::<&str>, ()).with_child(
-                            list_tile_usage(
-                                format!("{:.2}", cpu),
-                                maxcpu.to_string(),
-                                cpu_percentage,
-                            ),
-                        ),
-                    );
-                }
+                tiles.push(
+                    icon_list_tile(Fa::new("cpu"), "CPU", None::<&str>, ()).with_child(
+                        list_tile_usage(format!("{:.2}", cpu), maxcpu.to_string(), cpu_percentage),
+                    ),
+                );
+            }
 
-                if let (Some(mem), Some(maxmem)) = (data.mem, data.maxmem) {
-                    let mem_percentage = if maxmem <= 0 {
-                        0.0
-                    } else {
-                        (mem as f32) / (maxmem as f32)
-                    };
-                    tiles.push(
-                        icon_list_tile(Fa::new("memory"), "Memory", (), ()).with_child(
-                            list_tile_usage(
-                                HumanByte::new_binary(mem as f64).to_string(),
-                                HumanByte::new_binary(maxmem as f64).to_string(),
-                                mem_percentage,
-                            ),
+            if let (Some(mem), Some(maxmem)) = (data.mem, data.maxmem) {
+                let mem_percentage = if maxmem <= 0 {
+                    0.0
+                } else {
+                    (mem as f32) / (maxmem as f32)
+                };
+                tiles.push(
+                    icon_list_tile(Fa::new("memory"), "Memory", (), ()).with_child(
+                        list_tile_usage(
+                            HumanByte::new_binary(mem as f64).to_string(),
+                            HumanByte::new_binary(maxmem as f64).to_string(),
+                            mem_percentage,
                         ),
-                    );
-                }
+                    ),
+                );
             }
         }
 
diff --git a/src/pages/page_qemu_status/dashboard_panel.rs b/src/pages/page_qemu_status/dashboard_panel.rs
index 63669e0..3120046 100644
--- a/src/pages/page_qemu_status/dashboard_panel.rs
+++ b/src/pages/page_qemu_status/dashboard_panel.rs
@@ -153,42 +153,40 @@ impl PveQemuDashboardPanel {
             data.qmpstatus.clone().unwrap_or(data.status.to_string()),
         ));
 
-        if let Some(Ok(data)) = &self.data {
-            if data.status == IsRunning::Running {
-                if let (Some(cpu), Some(maxcpu)) = (data.cpu, data.cpus) {
-                    let cpu_percentage = if maxcpu == 0.0 {
-                        0.0
-                    } else {
-                        (cpu as f32) / (maxcpu as f32)
-                    };
+        if let Some(Ok(data)) = &self.data
+            && data.status == IsRunning::Running
+        {
+            if let (Some(cpu), Some(maxcpu)) = (data.cpu, data.cpus) {
+                let cpu_percentage = if maxcpu == 0.0 {
+                    0.0
+                } else {
+                    (cpu as f32) / (maxcpu as f32)
+                };
 
-                    tiles.push(
-                        icon_list_tile(Fa::new("cpu"), tr!("CPU"), (), ()).with_child(
-                            list_tile_usage(
-                                format!("{:.2}", cpu),
-                                maxcpu.to_string(),
-                                cpu_percentage,
-                            ),
-                        ),
-                    );
-                }
+                tiles.push(
+                    icon_list_tile(Fa::new("cpu"), tr!("CPU"), (), ()).with_child(list_tile_usage(
+                        format!("{:.2}", cpu),
+                        maxcpu.to_string(),
+                        cpu_percentage,
+                    )),
+                );
+            }
 
-                if let (Some(mem), Some(maxmem)) = (data.mem, data.maxmem) {
-                    let mem_percentage = if maxmem <= 0 {
-                        0.0
-                    } else {
-                        (mem as f32) / (maxmem as f32)
-                    };
-                    tiles.push(
-                        icon_list_tile(Fa::new("memory"), tr!("Memory"), (), ()).with_child(
-                            list_tile_usage(
-                                HumanByte::new_binary(mem as f64).to_string(),
-                                HumanByte::new_binary(maxmem as f64).to_string(),
-                                mem_percentage,
-                            ),
+            if let (Some(mem), Some(maxmem)) = (data.mem, data.maxmem) {
+                let mem_percentage = if maxmem <= 0 {
+                    0.0
+                } else {
+                    (mem as f32) / (maxmem as f32)
+                };
+                tiles.push(
+                    icon_list_tile(Fa::new("memory"), tr!("Memory"), (), ()).with_child(
+                        list_tile_usage(
+                            HumanByte::new_binary(mem as f64).to_string(),
+                            HumanByte::new_binary(maxmem as f64).to_string(),
+                            mem_percentage,
                         ),
-                    );
-                }
+                    ),
+                );
             }
         }
 
diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
index 7302229..2d41e35 100644
--- a/src/pages/page_resources.rs
+++ b/src/pages/page_resources.rs
@@ -72,10 +72,10 @@ fn filter_match(item: &ClusterResource, filter: &ResourceFilter) -> bool {
         if item.id.to_lowercase().contains(&filter.name) {
             return true;
         }
-        if let Some(name) = &item.name {
-            if name.contains(&filter.name) {
-                return true;
-            }
+        if let Some(name) = &item.name
+            && name.contains(&filter.name)
+        {
+            return true;
         }
         false
     } else {
@@ -360,10 +360,10 @@ impl Component for PvePageResources {
         let mut filter: PersistentState<ResourceFilter> =
             PersistentState::new("pve-resource-filter");
 
-        if let Some(location) = ctx.link().location() {
-            if let Some(state) = location.state::<ResourceFilter>() {
-                filter.update(state.as_ref().clone());
-            }
+        if let Some(location) = ctx.link().location()
+            && let Some(state) = location.state::<ResourceFilter>()
+        {
+            filter.update(state.as_ref().clone());
         }
 
         Self {
-- 
2.47.3





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

* [PATCH yew-mobile-gui 05/20] tree-wide: implement the `From` trait instead of the `Into` trait
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (3 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 04/20] tree-wide: collapse if statements Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 06/20] tree-wide: implement `Default` for types with an `new()` constructor Shannon Sterz
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

this is usually more flexible, as a `From` implementation yields an
`Into` implementation for free. fixes the clippy lint
"clippy::from_over_into" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_cluster_firewall/mod.rs        | 6 +++---
 src/pages/page_configuartion.rs               | 6 +++---
 src/pages/page_dashboard.rs                   | 6 +++---
 src/pages/page_login.rs                       | 6 +++---
 src/pages/page_lxc_status/dashboard_panel.rs  | 6 +++---
 src/pages/page_lxc_status/mod.rs              | 6 +++---
 src/pages/page_lxc_tasks.rs                   | 6 +++---
 src/pages/page_node_status/dashboard_panel.rs | 6 +++---
 src/pages/page_node_status/mod.rs             | 6 +++---
 src/pages/page_node_tasks.rs                  | 6 +++---
 src/pages/page_qemu_status/dashboard_panel.rs | 6 +++---
 src/pages/page_qemu_status/firewall_panel.rs  | 6 +++---
 src/pages/page_qemu_status/mod.rs             | 6 +++---
 src/pages/page_qemu_tasks.rs                  | 6 +++---
 src/pages/page_resources.rs                   | 6 +++---
 src/pages/page_settings.rs                    | 6 +++---
 src/pages/page_storage_status.rs              | 6 +++---
 src/pages/page_task_status.rs                 | 6 +++---
 src/widgets/top_nav_bar.rs                    | 6 +++---
 19 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/src/pages/page_cluster_firewall/mod.rs b/src/pages/page_cluster_firewall/mod.rs
index 278de59..d422417 100644
--- a/src/pages/page_cluster_firewall/mod.rs
+++ b/src/pages/page_cluster_firewall/mod.rs
@@ -158,9 +158,9 @@ impl Component for PvePageClusterFirewall {
     }
 }
 
-impl Into<VNode> for PageClusterFirewall {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageClusterFirewall>(Rc::new(self), None);
+impl From<PageClusterFirewall> for VNode {
+    fn from(val: PageClusterFirewall) -> Self {
+        let comp = VComp::new::<PvePageClusterFirewall>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_configuartion.rs b/src/pages/page_configuartion.rs
index 7a60825..debcbd7 100644
--- a/src/pages/page_configuartion.rs
+++ b/src/pages/page_configuartion.rs
@@ -97,9 +97,9 @@ impl Component for PvePageConfiguration {
     }
 }
 
-impl Into<VNode> for PageConfiguration {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageConfiguration>(Rc::new(self), None);
+impl From<PageConfiguration> for VNode {
+    fn from(val: PageConfiguration) -> Self {
+        let comp = VComp::new::<PvePageConfiguration>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_dashboard.rs b/src/pages/page_dashboard.rs
index 211d66d..18640d4 100644
--- a/src/pages/page_dashboard.rs
+++ b/src/pages/page_dashboard.rs
@@ -492,9 +492,9 @@ impl Component for PvePageDashboard {
     }
 }
 
-impl Into<VNode> for PageDashboard {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageDashboard>(Rc::new(self), None);
+impl From<PageDashboard> for VNode {
+    fn from(val: PageDashboard) -> Self {
+        let comp = VComp::new::<PvePageDashboard>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_login.rs b/src/pages/page_login.rs
index 63fad30..98773bf 100644
--- a/src/pages/page_login.rs
+++ b/src/pages/page_login.rs
@@ -108,9 +108,9 @@ impl Component for PvePageLogin {
     }
 }
 
-impl Into<VNode> for PageLogin {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageLogin>(Rc::new(self), None);
+impl From<PageLogin> for VNode {
+    fn from(val: PageLogin) -> Self {
+        let comp = VComp::new::<PvePageLogin>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_lxc_status/dashboard_panel.rs b/src/pages/page_lxc_status/dashboard_panel.rs
index 8009dcc..e597116 100644
--- a/src/pages/page_lxc_status/dashboard_panel.rs
+++ b/src/pages/page_lxc_status/dashboard_panel.rs
@@ -363,9 +363,9 @@ impl Component for PveLxcDashboardPanel {
     }
 }
 
-impl Into<VNode> for LxcDashboardPanel {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PveLxcDashboardPanel>(Rc::new(self), None);
+impl From<LxcDashboardPanel> for VNode {
+    fn from(val: LxcDashboardPanel) -> Self {
+        let comp = VComp::new::<PveLxcDashboardPanel>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_lxc_status/mod.rs b/src/pages/page_lxc_status/mod.rs
index 71bd707..97ebddf 100644
--- a/src/pages/page_lxc_status/mod.rs
+++ b/src/pages/page_lxc_status/mod.rs
@@ -134,9 +134,9 @@ impl Component for PvePageLxcStatus {
     }
 }
 
-impl Into<VNode> for PageLxcStatus {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageLxcStatus>(Rc::new(self), None);
+impl From<PageLxcStatus> for VNode {
+    fn from(val: PageLxcStatus) -> Self {
+        let comp = VComp::new::<PvePageLxcStatus>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_lxc_tasks.rs b/src/pages/page_lxc_tasks.rs
index 30d00c2..044d393 100644
--- a/src/pages/page_lxc_tasks.rs
+++ b/src/pages/page_lxc_tasks.rs
@@ -68,9 +68,9 @@ pub fn PvePageLxcTasks(props: &PageLxcTasks) -> Html {
         .into()
 }
 
-impl Into<VNode> for PageLxcTasks {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageLxcTasks>(Rc::new(self), None);
+impl From<PageLxcTasks> for VNode {
+    fn from(val: PageLxcTasks) -> Self {
+        let comp = VComp::new::<PvePageLxcTasks>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_node_status/dashboard_panel.rs b/src/pages/page_node_status/dashboard_panel.rs
index 1a723fe..848fb6f 100644
--- a/src/pages/page_node_status/dashboard_panel.rs
+++ b/src/pages/page_node_status/dashboard_panel.rs
@@ -232,9 +232,9 @@ impl Component for PveNodeDashboardPanel {
     }
 }
 
-impl Into<VNode> for NodeDashboardPanel {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PveNodeDashboardPanel>(Rc::new(self), None);
+impl From<NodeDashboardPanel> for VNode {
+    fn from(val: NodeDashboardPanel) -> Self {
+        let comp = VComp::new::<PveNodeDashboardPanel>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_node_status/mod.rs b/src/pages/page_node_status/mod.rs
index 5766b61..be6a98c 100644
--- a/src/pages/page_node_status/mod.rs
+++ b/src/pages/page_node_status/mod.rs
@@ -164,9 +164,9 @@ impl Component for PvePageNodeStatus {
     }
 }
 
-impl Into<VNode> for PageNodeStatus {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageNodeStatus>(Rc::new(self), None);
+impl From<PageNodeStatus> for VNode {
+    fn from(val: PageNodeStatus) -> Self {
+        let comp = VComp::new::<PvePageNodeStatus>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_node_tasks.rs b/src/pages/page_node_tasks.rs
index 5ea3bea..2f4773b 100644
--- a/src/pages/page_node_tasks.rs
+++ b/src/pages/page_node_tasks.rs
@@ -59,9 +59,9 @@ pub fn PvePageNodeTasks(props: &PageNodeTasks) -> Html {
         .into()
 }
 
-impl Into<VNode> for PageNodeTasks {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageNodeTasks>(Rc::new(self), None);
+impl From<PageNodeTasks> for VNode {
+    fn from(val: PageNodeTasks) -> Self {
+        let comp = VComp::new::<PvePageNodeTasks>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_qemu_status/dashboard_panel.rs b/src/pages/page_qemu_status/dashboard_panel.rs
index 3120046..47aa89c 100644
--- a/src/pages/page_qemu_status/dashboard_panel.rs
+++ b/src/pages/page_qemu_status/dashboard_panel.rs
@@ -409,9 +409,9 @@ impl Component for PveQemuDashboardPanel {
     }
 }
 
-impl Into<VNode> for QemuDashboardPanel {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PveQemuDashboardPanel>(Rc::new(self), None);
+impl From<QemuDashboardPanel> for VNode {
+    fn from(val: QemuDashboardPanel) -> Self {
+        let comp = VComp::new::<PveQemuDashboardPanel>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_qemu_status/firewall_panel.rs b/src/pages/page_qemu_status/firewall_panel.rs
index 3a30c1b..bcc6213 100644
--- a/src/pages/page_qemu_status/firewall_panel.rs
+++ b/src/pages/page_qemu_status/firewall_panel.rs
@@ -159,9 +159,9 @@ impl Component for PveQemuFirewallPanel {
     }
 }
 
-impl Into<VNode> for QemuFirewallPanel {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PveQemuFirewallPanel>(Rc::new(self), None);
+impl From<QemuFirewallPanel> for VNode {
+    fn from(val: QemuFirewallPanel) -> Self {
+        let comp = VComp::new::<PveQemuFirewallPanel>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_qemu_status/mod.rs b/src/pages/page_qemu_status/mod.rs
index 068b579..bbd4fcf 100644
--- a/src/pages/page_qemu_status/mod.rs
+++ b/src/pages/page_qemu_status/mod.rs
@@ -177,9 +177,9 @@ impl Component for PvePageQemuStatus {
     }
 }
 
-impl Into<VNode> for PageQemuStatus {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageQemuStatus>(Rc::new(self), None);
+impl From<PageQemuStatus> for VNode {
+    fn from(val: PageQemuStatus) -> Self {
+        let comp = VComp::new::<PvePageQemuStatus>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_qemu_tasks.rs b/src/pages/page_qemu_tasks.rs
index 7639b09..bac33a9 100644
--- a/src/pages/page_qemu_tasks.rs
+++ b/src/pages/page_qemu_tasks.rs
@@ -68,9 +68,9 @@ pub fn PvePageQemuTasks(props: &PageQemuTasks) -> Html {
         .into()
 }
 
-impl Into<VNode> for PageQemuTasks {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageQemuTasks>(Rc::new(self), None);
+impl From<PageQemuTasks> for VNode {
+    fn from(val: PageQemuTasks) -> Self {
+        let comp = VComp::new::<PvePageQemuTasks>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
index 2d41e35..20bd124 100644
--- a/src/pages/page_resources.rs
+++ b/src/pages/page_resources.rs
@@ -448,9 +448,9 @@ impl Component for PvePageResources {
     }
 }
 
-impl Into<VNode> for PageResources {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageResources>(Rc::new(self), None);
+impl From<PageResources> for VNode {
+    fn from(val: PageResources) -> Self {
+        let comp = VComp::new::<PvePageResources>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_settings.rs b/src/pages/page_settings.rs
index b410b8a..881c219 100644
--- a/src/pages/page_settings.rs
+++ b/src/pages/page_settings.rs
@@ -48,9 +48,9 @@ impl Component for PvePageSettings {
     }
 }
 
-impl Into<VNode> for PageSettings {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageSettings>(Rc::new(self), None);
+impl From<PageSettings> for VNode {
+    fn from(val: PageSettings) -> Self {
+        let comp = VComp::new::<PvePageSettings>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_storage_status.rs b/src/pages/page_storage_status.rs
index 939a7c6..8766afb 100644
--- a/src/pages/page_storage_status.rs
+++ b/src/pages/page_storage_status.rs
@@ -113,9 +113,9 @@ impl Component for PvePageStorageStatus {
     }
 }
 
-impl Into<VNode> for PageStorageStatus {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageStorageStatus>(Rc::new(self), None);
+impl From<PageStorageStatus> for VNode {
+    fn from(val: PageStorageStatus) -> Self {
+        let comp = VComp::new::<PvePageStorageStatus>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/pages/page_task_status.rs b/src/pages/page_task_status.rs
index 9217e75..75076f5 100644
--- a/src/pages/page_task_status.rs
+++ b/src/pages/page_task_status.rs
@@ -281,9 +281,9 @@ impl Component for PvePageTaskStatus {
     }
 }
 
-impl Into<VNode> for PageTaskStatus {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PvePageTaskStatus>(Rc::new(self), None);
+impl From<PageTaskStatus> for VNode {
+    fn from(val: PageTaskStatus) -> Self {
+        let comp = VComp::new::<PvePageTaskStatus>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
diff --git a/src/widgets/top_nav_bar.rs b/src/widgets/top_nav_bar.rs
index c8234f0..128ce3e 100644
--- a/src/widgets/top_nav_bar.rs
+++ b/src/widgets/top_nav_bar.rs
@@ -195,9 +195,9 @@ impl Component for PveTopNavBar {
     }
 }
 
-impl Into<VNode> for TopNavBar {
-    fn into(self) -> VNode {
-        let comp = VComp::new::<PveTopNavBar>(Rc::new(self), None);
+impl From<TopNavBar> for VNode {
+    fn from(val: TopNavBar) -> Self {
+        let comp = VComp::new::<PveTopNavBar>(Rc::new(val), None);
         VNode::from(comp)
     }
 }
-- 
2.47.3





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

* [PATCH yew-mobile-gui 06/20] tree-wide: implement `Default` for types with an `new()` constructor
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (4 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 05/20] tree-wide: implement the `From` trait instead of the `Into` trait Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 07/20] tree-wide: remove unnecessary lazy evaluations Shannon Sterz
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

... that does not take any parameters. fixes the clippy lint
"clippy::new_without_default" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_cluster_firewall/mod.rs | 6 ++++++
 src/pages/page_configuartion.rs        | 6 ++++++
 src/pages/page_dashboard.rs            | 6 ++++++
 src/pages/page_login.rs                | 6 ++++++
 src/pages/page_resources.rs            | 6 ++++++
 src/pages/page_settings.rs             | 6 ++++++
 src/widgets/task_list_button.rs        | 6 ++++++
 src/widgets/top_nav_bar.rs             | 6 ++++++
 8 files changed, 48 insertions(+)

diff --git a/src/pages/page_cluster_firewall/mod.rs b/src/pages/page_cluster_firewall/mod.rs
index d422417..6bb8253 100644
--- a/src/pages/page_cluster_firewall/mod.rs
+++ b/src/pages/page_cluster_firewall/mod.rs
@@ -16,6 +16,12 @@ use crate::widgets::TopNavBar;
 #[derive(Clone, PartialEq, Properties)]
 pub struct PageClusterFirewall {}
 
+impl Default for PageClusterFirewall {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl PageClusterFirewall {
     pub fn new() -> Self {
         Self {}
diff --git a/src/pages/page_configuartion.rs b/src/pages/page_configuartion.rs
index debcbd7..36e3a69 100644
--- a/src/pages/page_configuartion.rs
+++ b/src/pages/page_configuartion.rs
@@ -14,6 +14,12 @@ use proxmox_yew_comp::layout::list_tile::icon_list_tile;
 use crate::Route;
 use crate::widgets::TopNavBar;
 
+impl Default for PageConfiguration {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl PageConfiguration {
     pub fn new() -> Self {
         Self {}
diff --git a/src/pages/page_dashboard.rs b/src/pages/page_dashboard.rs
index 18640d4..ff890ca 100644
--- a/src/pages/page_dashboard.rs
+++ b/src/pages/page_dashboard.rs
@@ -26,6 +26,12 @@ use crate::widgets::TopNavBar;
 #[derive(Clone, PartialEq, Properties)]
 pub struct PageDashboard {}
 
+impl Default for PageDashboard {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl PageDashboard {
     pub fn new() -> Self {
         Self {}
diff --git a/src/pages/page_login.rs b/src/pages/page_login.rs
index 98773bf..8b7fa42 100644
--- a/src/pages/page_login.rs
+++ b/src/pages/page_login.rs
@@ -29,6 +29,12 @@ pub struct PageLogin {
     pub consent_text: Option<AttrValue>,
 }
 
+impl Default for PageLogin {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl PageLogin {
     pub fn new() -> Self {
         yew::props!(Self {})
diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
index 20bd124..1365d63 100644
--- a/src/pages/page_resources.rs
+++ b/src/pages/page_resources.rs
@@ -26,6 +26,12 @@ use pve_api_types::{ClusterResource, ClusterResourceType};
 #[derive(Clone, PartialEq, Properties)]
 pub struct PageResources {}
 
+impl Default for PageResources {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl PageResources {
     pub fn new() -> Self {
         Self {}
diff --git a/src/pages/page_settings.rs b/src/pages/page_settings.rs
index 881c219..28ef32d 100644
--- a/src/pages/page_settings.rs
+++ b/src/pages/page_settings.rs
@@ -14,6 +14,12 @@ use proxmox_yew_comp::layout::mobile_form::label_widget;
 #[derive(Clone, PartialEq, Properties)]
 pub struct PageSettings {}
 
+impl Default for PageSettings {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl PageSettings {
     pub fn new() -> Self {
         Self {}
diff --git a/src/widgets/task_list_button.rs b/src/widgets/task_list_button.rs
index 7321b1d..bd42199 100644
--- a/src/widgets/task_list_button.rs
+++ b/src/widgets/task_list_button.rs
@@ -36,6 +36,12 @@ pub struct TasksListButton {
     pub on_show_task_list: Option<Callback<MouseEvent>>,
 }
 
+impl Default for TasksListButton {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl TasksListButton {
     pub fn new() -> Self {
         yew::props!(Self {})
diff --git a/src/widgets/top_nav_bar.rs b/src/widgets/top_nav_bar.rs
index 128ce3e..7adf2ee 100644
--- a/src/widgets/top_nav_bar.rs
+++ b/src/widgets/top_nav_bar.rs
@@ -36,6 +36,12 @@ pub struct TopNavBar {
     menu_items: Vec<MenuEntry>,
 }
 
+impl Default for TopNavBar {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl TopNavBar {
     pub fn new() -> Self {
         yew::props!(Self {})
-- 
2.47.3





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

* [PATCH yew-mobile-gui 07/20] tree-wide: remove unnecessary lazy evaluations
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (5 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 06/20] tree-wide: implement `Default` for types with an `new()` constructor Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 08/20] tree-wide: remove needless borrows Shannon Sterz
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

fixes the clippy lint "clippy::unnecessary_lazy_evaluations" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_dashboard.rs                   | 2 +-
 src/pages/page_lxc_status/dashboard_panel.rs  | 2 +-
 src/pages/page_qemu_status/dashboard_panel.rs | 2 +-
 src/pages/page_resources.rs                   | 9 +++++----
 src/widgets/guest_backup_panel.rs             | 2 +-
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/pages/page_dashboard.rs b/src/pages/page_dashboard.rs
index ff890ca..519b22e 100644
--- a/src/pages/page_dashboard.rs
+++ b/src/pages/page_dashboard.rs
@@ -216,7 +216,7 @@ impl PvePageDashboard {
                     icon_list_tile(
                         Fa::new("server").class(
                             (item.status == ClusterNodeIndexResponseStatus::Online)
-                                .then(|| "pwt-color-primary"),
+                                .then_some("pwt-color-primary"),
                         ),
                         nodename.clone(),
                         subtitle.to_string(),
diff --git a/src/pages/page_lxc_status/dashboard_panel.rs b/src/pages/page_lxc_status/dashboard_panel.rs
index e597116..00fec11 100644
--- a/src/pages/page_lxc_status/dashboard_panel.rs
+++ b/src/pages/page_lxc_status/dashboard_panel.rs
@@ -82,7 +82,7 @@ fn large_fa_icon(name: &str, running: bool) -> Fa {
     Fa::new(name)
         .fixed_width()
         .class("pwt-font-size-title-large")
-        .class(running.then(|| "pwt-color-primary"))
+        .class(running.then_some("pwt-color-primary"))
 }
 
 fn format_guest_task_confirmation(
diff --git a/src/pages/page_qemu_status/dashboard_panel.rs b/src/pages/page_qemu_status/dashboard_panel.rs
index 47aa89c..27098f4 100644
--- a/src/pages/page_qemu_status/dashboard_panel.rs
+++ b/src/pages/page_qemu_status/dashboard_panel.rs
@@ -85,7 +85,7 @@ fn large_fa_icon(name: &str, running: bool) -> Fa {
     Fa::new(name)
         .fixed_width()
         .class("pwt-font-size-title-large")
-        .class(running.then(|| "pwt-color-primary"))
+        .class(running.then_some("pwt-color-primary"))
 }
 
 fn format_guest_task_confirmation(
diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
index 1365d63..b20a8e2 100644
--- a/src/pages/page_resources.rs
+++ b/src/pages/page_resources.rs
@@ -117,7 +117,7 @@ impl PvePageResources {
         let nodename = item.node.clone().unwrap();
         icon_list_tile(
             Fa::new("server")
-                .class((item.status.as_deref() == Some("online")).then(|| "pwt-color-primary")),
+                .class((item.status.as_deref() == Some("online")).then_some("pwt-color-primary")),
             nodename.clone(),
             match item.level.as_deref() {
                 Some("") | None => "no subscription",
@@ -141,7 +141,7 @@ impl PvePageResources {
     fn create_vm_list_item(&self, icon: &str, item: &ClusterResource) -> ListTile {
         icon_list_tile(
             Fa::new(icon)
-                .class((item.status.as_deref() == Some("running")).then(|| "pwt-color-primary")),
+                .class((item.status.as_deref() == Some("running")).then_some("pwt-color-primary")),
             format!(
                 "{} {}",
                 item.vmid.unwrap(),
@@ -187,8 +187,9 @@ impl PvePageResources {
         let plugin_type = item.plugintype.clone().unwrap();
 
         let mut tile = icon_list_tile(
-            Fa::new("database")
-                .class((item.status.as_deref() == Some("available")).then(|| "pwt-color-primary")),
+            Fa::new("database").class(
+                (item.status.as_deref() == Some("available")).then_some("pwt-color-primary"),
+            ),
             format!("{} ({})", name, plugin_type),
             item.node.clone(),
             item.status.clone(),
diff --git a/src/widgets/guest_backup_panel.rs b/src/widgets/guest_backup_panel.rs
index fac281b..00f211e 100644
--- a/src/widgets/guest_backup_panel.rs
+++ b/src/widgets/guest_backup_panel.rs
@@ -158,7 +158,7 @@ impl PveGuestBackupPanel {
                         info.total,
                         info.used,
                     )
-                    .class(active.then(|| pwt::css::ColorScheme::PrimaryContainer))
+                    .class(active.then_some(pwt::css::ColorScheme::PrimaryContainer))
                     .class(if active {
                         "pwt-elevation4"
                     } else {
-- 
2.47.3





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

* [PATCH yew-mobile-gui 08/20] tree-wide: remove needless borrows
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (6 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 07/20] tree-wide: remove unnecessary lazy evaluations Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 09/20] configuration page: remove redundant static lifetimes Shannon Sterz
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

fixes the clippy lint "clippy::needless_borrow" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/main.rs                                  | 2 +-
 src/pages/page_node_status/services_panel.rs | 2 +-
 src/widgets/guest_backup_panel.rs            | 2 +-
 src/widgets/task_list_button.rs              | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 2a91379..3b22e41 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -97,7 +97,7 @@ enum Route {
 }
 
 fn switch(path: &str) -> Vec<Html> {
-    let route = Route::recognize(&path).unwrap();
+    let route = Route::recognize(path).unwrap();
     switch_route(route)
 }
 
diff --git a/src/pages/page_node_status/services_panel.rs b/src/pages/page_node_status/services_panel.rs
index 6e3e2e0..7e495ee 100644
--- a/src/pages/page_node_status/services_panel.rs
+++ b/src/pages/page_node_status/services_panel.rs
@@ -87,7 +87,7 @@ impl PveNodeServicesPanel {
             .map(|s| {
                 ListTile::new()
                     .with_child(title_subtitle_column(s.name.clone(), s.desc.clone()))
-                    .with_child(service_state_icon(&s))
+                    .with_child(service_state_icon(s))
             })
             .collect();
 
diff --git a/src/widgets/guest_backup_panel.rs b/src/widgets/guest_backup_panel.rs
index 00f211e..1db0657 100644
--- a/src/widgets/guest_backup_panel.rs
+++ b/src/widgets/guest_backup_panel.rs
@@ -114,7 +114,7 @@ impl PveGuestBackupPanel {
         let url = format!(
             "/nodes/{}/tasks/{}/log",
             props.node,
-            percent_encode_component(&upid),
+            percent_encode_component(upid),
         );
 
         SideDialog::new()
diff --git a/src/widgets/task_list_button.rs b/src/widgets/task_list_button.rs
index bd42199..d449428 100644
--- a/src/widgets/task_list_button.rs
+++ b/src/widgets/task_list_button.rs
@@ -62,7 +62,7 @@ pub enum Msg {
 impl ProxmoxTaskListButton {
     fn update_upid(&mut self, ctx: &Context<Self>, upid: &str) {
         self.running_upid = Some(upid.to_string().into());
-        let task_descr = format_upid(&upid);
+        let task_descr = format_upid(upid);
         self.last_task_status = Some(format!("{task_descr} (running)"));
         self.check_running_task_status(ctx);
     }
-- 
2.47.3





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

* [PATCH yew-mobile-gui 09/20] configuration page: remove redundant static lifetimes
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (7 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 08/20] tree-wide: remove needless borrows Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 10/20] resources/configuration page: remove useless `.into()` calls Shannon Sterz
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

fixes the clippy lint "clippy::redundant_static_lifetimes" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_configuartion.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/page_configuartion.rs b/src/pages/page_configuartion.rs
index 36e3a69..2e283ba 100644
--- a/src/pages/page_configuartion.rs
+++ b/src/pages/page_configuartion.rs
@@ -27,7 +27,7 @@ impl PageConfiguration {
 }
 pub struct PvePageConfiguration {}
 
-static CONFIGS: &[(&'static str, &'static str, &'static Route)] = &[
+static CONFIGS: &[(&str, &str, &Route)] = &[
     ("asterisk", "Settings", &Route::Settings),
     ("shield", "Firewall", &Route::ClusterFirewall),
     //("unlock", "Permissions", &Route::Settings),
-- 
2.47.3





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

* [PATCH yew-mobile-gui 10/20] resources/configuration page: remove useless `.into()` calls
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (8 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 09/20] configuration page: remove redundant static lifetimes Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 11/20] tree-wide: fix several clippy lints Shannon Sterz
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

fixes the clippy lint "clippy::useless_conversion" [1].

[1]:
https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_configuartion.rs | 1 -
 src/pages/page_resources.rs     | 1 -
 2 files changed, 2 deletions(-)

diff --git a/src/pages/page_configuartion.rs b/src/pages/page_configuartion.rs
index 2e283ba..46077c8 100644
--- a/src/pages/page_configuartion.rs
+++ b/src/pages/page_configuartion.rs
@@ -78,7 +78,6 @@ impl PvePageConfiguration {
                     let navigator = navigator.clone();
                     move |_| navigator.push(item.2)
                 })
-                .into()
         })
         .grid_template_columns("auto 1fr")
         .class("pwt-fit")
diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
index b20a8e2..fdd9af4 100644
--- a/src/pages/page_resources.rs
+++ b/src/pages/page_resources.rs
@@ -135,7 +135,6 @@ impl PvePageResources {
                 });
             }
         })
-        .into()
     }
 
     fn create_vm_list_item(&self, icon: &str, item: &ClusterResource) -> ListTile {
-- 
2.47.3





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

* [PATCH yew-mobile-gui 11/20] tree-wide: fix several clippy lints
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (9 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 10/20] resources/configuration page: remove useless `.into()` calls Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 12/20] dashboard: use proper plural translation string instead of "CPU(s)" Shannon Sterz
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

this fixes the following clippy lints:

* let_and_return
* just_underscores_and_digits
* manual_map
* match_like_matches_macro
* missing_const_for_thread_local
* needless_return
* redundant_closure
* unnecessary_to_owned

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/main.rs                                   |  4 ++--
 src/pages/page_configuartion.rs               |  2 +-
 src/pages/page_qemu_status/dashboard_panel.rs |  5 ++---
 src/pages/page_resources.rs                   |  4 ++--
 src/widgets/task_list_button.rs               | 21 +++++++------------
 src/widgets/tasks_panel.rs                    |  2 +-
 6 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 3b22e41..74d4044 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -344,12 +344,12 @@ impl Component for PveMobileApp {
             if auth {
                 switch(path)
             } else {
-                return vec![
+                vec![
                     PageLogin::new()
                         .consent_text(consent_text.clone())
                         .on_login(link.callback(Msg::Login))
                         .into(),
-                ];
+                ]
             }
         };
 
diff --git a/src/pages/page_configuartion.rs b/src/pages/page_configuartion.rs
index 46077c8..73c9eac 100644
--- a/src/pages/page_configuartion.rs
+++ b/src/pages/page_configuartion.rs
@@ -72,7 +72,7 @@ impl PvePageConfiguration {
         List::new(CONFIGS.len() as u64, move |pos| {
             let item = CONFIGS[pos as usize];
 
-            icon_list_tile(Fa::new(item.0.to_string()), item.1.to_string(), (), ())
+            icon_list_tile(Fa::new(item.0), item.1.to_string(), (), ())
                 .interactive(true)
                 .onclick({
                     let navigator = navigator.clone();
diff --git a/src/pages/page_qemu_status/dashboard_panel.rs b/src/pages/page_qemu_status/dashboard_panel.rs
index 27098f4..dc5a8c5 100644
--- a/src/pages/page_qemu_status/dashboard_panel.rs
+++ b/src/pages/page_qemu_status/dashboard_panel.rs
@@ -336,9 +336,8 @@ impl Component for PveQemuDashboardPanel {
                             if let Value::Object(map) = &mut data {
                                 map.retain(|_k, v| v != &Value::Null);
                             }
-                            let data = serde_json::from_value::<QemuStatus>(data)
-                                .map_err(|err| err.into());
-                            data
+
+                            serde_json::from_value::<QemuStatus>(data).map_err(|err| err.into())
                         }
                         Err(err) => Err(err),
                     };
diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
index fdd9af4..469bbf3 100644
--- a/src/pages/page_resources.rs
+++ b/src/pages/page_resources.rs
@@ -90,7 +90,7 @@ fn filter_match(item: &ClusterResource, filter: &ResourceFilter) -> bool {
 }
 
 thread_local! {
-    static RESOURCES: RefCell<Option<Result<Vec<ClusterResource>, Error>>> = RefCell::new(None);
+    static RESOURCES: RefCell<Option<Result<Vec<ClusterResource>, Error>>> = const { RefCell::new(None) };
 }
 pub struct PvePageResources {
     reload_timeout: Option<Timeout>,
@@ -303,7 +303,7 @@ impl PvePageResources {
     fn create_top_bar(&self, ctx: &Context<Self>) -> Html {
         let mut search = Field::new()
             .value(self.filter.name.clone())
-            .on_change(ctx.link().callback(|value| Msg::SetTextFilter(value)))
+            .on_change(ctx.link().callback(Msg::SetTextFilter))
             .class(pwt::css::Flex::Fill);
 
         search.add_trigger(
diff --git a/src/widgets/task_list_button.rs b/src/widgets/task_list_button.rs
index d449428..3b28162 100644
--- a/src/widgets/task_list_button.rs
+++ b/src/widgets/task_list_button.rs
@@ -133,12 +133,10 @@ impl Component for ProxmoxTaskListButton {
                 if Some(&upid) != self.running_upid.as_ref() {
                     return false;
                 }
-                let running = match &result {
-                    Ok(status) if status.status == IsRunning::Running => true,
-                    _ => false,
-                };
 
-                if running {
+                if let Ok(status) = &result
+                    && status.status == IsRunning::Running
+                {
                     let link = ctx.link().clone();
                     self.check_task_status_timeout = Some(Timeout::new(1000, move || {
                         link.send_message(Msg::CheckTaskStatus);
@@ -165,14 +163,11 @@ impl Component for ProxmoxTaskListButton {
     fn view(&self, ctx: &Context<Self>) -> Html {
         let props = ctx.props();
 
-        let content = match &self.last_task_status {
-            Some(last_task_status) => Some(
-                Container::new()
-                    .class("pwt-font-size-title-medium")
-                    .with_child(last_task_status),
-            ),
-            None => None,
-        };
+        let content = self.last_task_status.as_ref().map(|last_task_status| {
+            Container::new()
+                .class("pwt-font-size-title-medium")
+                .with_child(last_task_status)
+        });
 
         Column::new()
             .gap(2)
diff --git a/src/widgets/tasks_panel.rs b/src/widgets/tasks_panel.rs
index 36f8c29..326aaef 100644
--- a/src/widgets/tasks_panel.rs
+++ b/src/widgets/tasks_panel.rs
@@ -57,7 +57,7 @@ fn task_icon(task: &ListTasksResponse) -> Fa {
 
     match task.status.as_deref() {
         Some("OK") => Fa::new("info-circle").class(pwt::css::FontColor::Primary),
-        Some(__) => Fa::new("exclamation-triangle").class(pwt::css::FontColor::Error),
+        Some(_) => Fa::new("exclamation-triangle").class(pwt::css::FontColor::Error),
         _ => Fa::new("question"),
     }
 }
-- 
2.47.3





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

* [PATCH yew-mobile-gui 12/20] dashboard: use proper plural translation string instead of "CPU(s)"
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (10 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 11/20] tree-wide: fix several clippy lints Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 13/20] configuration: clarify that "Firewall" shows the cluster's firewall Shannon Sterz
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_dashboard.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/page_dashboard.rs b/src/pages/page_dashboard.rs
index 519b22e..1e0243f 100644
--- a/src/pages/page_dashboard.rs
+++ b/src/pages/page_dashboard.rs
@@ -132,7 +132,7 @@ impl PvePageDashboard {
                 tiles.push(
                     icon_list_tile(Fa::new("cpu"), tr!("CPU"), (), ()).with_child(list_tile_usage(
                         tr!("{0}%", format!("{:.2}", cpu_proportion * 100.0)),
-                        tr!("{0} CPU(s)", maxcpu.to_string()),
+                        tr!("1 CPU" | "{n} CPUs" % maxcpu).to_string(),
                         cpu_proportion,
                     )),
                 );
-- 
2.47.3





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

* [PATCH yew-mobile-gui 13/20] configuration: clarify that "Firewall" shows the cluster's firewall
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (11 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 12/20] dashboard: use proper plural translation string instead of "CPU(s)" Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 14/20] cluster/qemu firewall: use rules panel and comment out unused tabs Shannon Sterz
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

and remove duplicate commented out config item

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_configuartion.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/pages/page_configuartion.rs b/src/pages/page_configuartion.rs
index 73c9eac..cde1e99 100644
--- a/src/pages/page_configuartion.rs
+++ b/src/pages/page_configuartion.rs
@@ -29,7 +29,7 @@ pub struct PvePageConfiguration {}
 
 static CONFIGS: &[(&str, &str, &Route)] = &[
     ("asterisk", "Settings", &Route::Settings),
-    ("shield", "Firewall", &Route::ClusterFirewall),
+    ("shield", "Cluster Firewall", &Route::ClusterFirewall),
     //("unlock", "Permissions", &Route::Settings),
 
     /*
@@ -54,9 +54,6 @@ static CONFIGS: &[(&str, &str, &Route)] = &[
     ("certificate", "ACME", || {
         html! {}
     }),
-    ("shield", "Firewall", || {
-        html! {}
-    }),
     ("bar-chart", "Metric Server", || {
         html! {}
     }),
-- 
2.47.3





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

* [PATCH yew-mobile-gui 14/20] cluster/qemu firewall: use rules panel and comment out unused tabs
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (12 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 13/20] configuration: clarify that "Firewall" shows the cluster's firewall Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 15/20] lxc page: align layout for lxc guest with qemu guests Shannon Sterz
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

this makes the rules panel actually display the QEMU and cluster
firewall rules. it also comments out the place-holder tabs for now as
they don't actually offer any real benefit to users yet. add them back
once appropriate components have been implemented.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_cluster_firewall/mod.rs       | 23 +++++++++--------
 src/pages/page_qemu_status/firewall_panel.rs | 27 ++++++++++++--------
 2 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/src/pages/page_cluster_firewall/mod.rs b/src/pages/page_cluster_firewall/mod.rs
index 6bb8253..f607b22 100644
--- a/src/pages/page_cluster_firewall/mod.rs
+++ b/src/pages/page_cluster_firewall/mod.rs
@@ -8,7 +8,7 @@ use pwt::prelude::*;
 use pwt::state::PersistentState;
 use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
 
-use proxmox_yew_comp::configuration::pve::FirewallOptionsClusterPanel;
+use proxmox_yew_comp::configuration::pve::{FirewallOptionsClusterPanel, FirewallRulesPanel};
 use pwt::props::StorageLocation;
 
 use crate::widgets::TopNavBar;
@@ -37,9 +37,9 @@ pub enum ViewState {
     #[default]
     Rules,
     Options,
-    SecurityGroup,
-    Alias,
-    IPSet,
+    //IPSet,
+    //Alias,
+    //SecurityGroup,
 }
 
 pub enum Msg {
@@ -69,9 +69,10 @@ impl Component for PvePageClusterFirewall {
         let (active_tab, content): (_, Html) = match *self.view_state {
             ViewState::Rules => (
                 "rules",
-                html! {
-                    <div>{ format!("Firewall rules for cluster") }</div>
-                },
+                FirewallRulesPanel::cluster_firewall()
+                    .mobile(true)
+                    .readonly(true)
+                    .into(),
             ),
             ViewState::Options => (
                 "options",
@@ -80,7 +81,7 @@ impl Component for PvePageClusterFirewall {
                     .readonly(true)
                     .into(),
             ),
-            ViewState::Alias => (
+            /*ViewState::Alias => (
                 "alias",
                 html! {
                     <div>{ format!("Firewall alias for cluster") }</div>
@@ -97,7 +98,7 @@ impl Component for PvePageClusterFirewall {
                 html! {
                     <div>{ format!("Firewall security group for cluster") }</div>
                 },
-            ),
+            ),*/
         };
 
         let tab_bar = TabBar::new()
@@ -122,7 +123,7 @@ impl Component for PvePageClusterFirewall {
                             .callback(|_| Msg::SetViewState(ViewState::Options)),
                     ),
             )
-            .with_item(
+            /*.with_item(
                 TabBarItem::new()
                     .key("alias")
                     .label(tr!("Alias"))
@@ -145,7 +146,7 @@ impl Component for PvePageClusterFirewall {
                         ctx.link()
                             .callback(|_| Msg::SetViewState(ViewState::SecurityGroup)),
                     ),
-            );
+            )*/;
 
         Column::new()
             .class("pwt-fit")
diff --git a/src/pages/page_qemu_status/firewall_panel.rs b/src/pages/page_qemu_status/firewall_panel.rs
index bcc6213..2c420c8 100644
--- a/src/pages/page_qemu_status/firewall_panel.rs
+++ b/src/pages/page_qemu_status/firewall_panel.rs
@@ -8,7 +8,7 @@ use pwt::props::StorageLocation;
 use pwt::state::PersistentState;
 use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
 
-use proxmox_yew_comp::configuration::pve::FirewallOptionsGuestPanel;
+use proxmox_yew_comp::configuration::pve::{FirewallOptionsGuestPanel, FirewallRulesPanel};
 use proxmox_yew_comp::form::pve::PveGuestType;
 
 #[derive(Clone, PartialEq, Properties)]
@@ -31,9 +31,9 @@ pub enum ViewState {
     #[default]
     Rules,
     Options,
-    Alias,
-    IPSet,
-    Log,
+    //Alias,
+    //IPSet,
+    //Log,
 }
 pub struct PveQemuFirewallPanel {
     view_state: PersistentState<ViewState>,
@@ -72,9 +72,14 @@ impl Component for PveQemuFirewallPanel {
         let (active_tab, content): (_, Html) = match *self.view_state {
             ViewState::Rules => (
                 "rules",
-                html! {
-                    <div>{ format!("Firewall rules for VM {}", props.vmid) }</div>
-                },
+                FirewallRulesPanel::guest_firewall(
+                    PveGuestType::Qemu,
+                    props.node.clone(),
+                    props.vmid,
+                )
+                .mobile(true)
+                .readonly(true)
+                .into(),
             ),
             ViewState::Options => (
                 "options",
@@ -83,7 +88,7 @@ impl Component for PveQemuFirewallPanel {
                     .readonly(true)
                     .into(),
             ),
-            ViewState::Alias => (
+            /*ViewState::Alias => (
                 "alias",
                 html! {
                     <div>{ format!("Firewall alias for VM {}", props.vmid) }</div>
@@ -100,7 +105,7 @@ impl Component for PveQemuFirewallPanel {
                 html! {
                     <div>{ format!("Firewall log for VM {}", props.vmid) }</div>
                 },
-            ),
+            ),*/
         };
 
         let tab_bar = TabBar::new()
@@ -125,7 +130,7 @@ impl Component for PveQemuFirewallPanel {
                             .callback(|_| Msg::SetViewState(ViewState::Options)),
                     ),
             )
-            .with_item(
+            /*.with_item(
                 TabBarItem::new()
                     .key("alias")
                     .label(tr!("Alias"))
@@ -145,7 +150,7 @@ impl Component for PveQemuFirewallPanel {
                     .label(tr!("Log"))
                     .icon_class("fa fa-list")
                     .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::Log))),
-            );
+            )*/;
 
         Column::new()
             .class(pwt::css::FlexFit)
-- 
2.47.3





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

* [PATCH yew-mobile-gui 15/20] lxc page: align layout for lxc guest with qemu guests
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (13 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 14/20] cluster/qemu firewall: use rules panel and comment out unused tabs Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:43   ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 16/20] lxc: add support for a rudimentary firewall tab for lxc guests Shannon Sterz
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

by adding icons and scrolling to the top-level tab panel

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_lxc_status/mod.rs | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/pages/page_lxc_status/mod.rs b/src/pages/page_lxc_status/mod.rs
index 97ebddf..4092dd5 100644
--- a/src/pages/page_lxc_status/mod.rs
+++ b/src/pages/page_lxc_status/mod.rs
@@ -1,5 +1,6 @@
 use std::rc::Rc;
 
+use pwt::css::Flex;
 use pwt::props::StorageLocation;
 use serde::{Deserialize, Serialize};
 
@@ -8,7 +9,7 @@ use yew::virtual_dom::{VComp, VNode};
 
 use pwt::prelude::*;
 use pwt::state::PersistentState;
-use pwt::widget::{Column, TabBar, TabBarItem};
+use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
 
 use crate::widgets::{GuestBackupPanel, TopNavBar};
 
@@ -95,10 +96,12 @@ impl Component for PvePageLxcStatus {
 
         let tab_bar = TabBar::new()
             .class(pwt::css::JustifyContent::Center)
+            .class(Flex::Fill)
             .active(active_tab)
             .with_item(
                 TabBarItem::new()
                     .label("Dashboard")
+                    .icon_class("fa fa-book")
                     .key("dashboard")
                     .on_activate(
                         ctx.link()
@@ -108,6 +111,7 @@ impl Component for PvePageLxcStatus {
             .with_item(
                 TabBarItem::new()
                     .label("Options")
+                    .icon_class("fa fa-floppy-o")
                     .key("options")
                     .on_activate(
                         ctx.link()
@@ -115,10 +119,14 @@ impl Component for PvePageLxcStatus {
                     ),
             )
             .with_item(
-                TabBarItem::new().label("Backup").key("backup").on_activate(
-                    ctx.link()
-                        .callback(|_| Msg::SetViewState(ViewState::Backup)),
-                ),
+                TabBarItem::new()
+                    .label("Backup")
+                    .icon_class("fa fa-gear")
+                    .key("backup")
+                    .on_activate(
+                        ctx.link()
+                            .callback(|_| Msg::SetViewState(ViewState::Backup)),
+                    ),
             );
 
         Column::new()
@@ -128,7 +136,11 @@ impl Component for PvePageLxcStatus {
                     .title(format!("CT {}", props.vmid))
                     .back("/resources"),
             )
-            .with_child(tab_bar)
+            .with_child(
+                MiniScroll::new(tab_bar)
+                    .class(Flex::None)
+                    .scroll_mode(pwt::widget::MiniScrollMode::Native),
+            )
             .with_child(content)
             .into()
     }
-- 
2.47.3





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

* [PATCH yew-mobile-gui 16/20] lxc: add support for a rudimentary firewall tab for lxc guests
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (14 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 15/20] lxc page: align layout for lxc guest with qemu guests Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 17/20] node status: align layout for node status with guest pages Shannon Sterz
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_lxc_status/firewall_panel.rs | 172 ++++++++++++++++++++
 src/pages/page_lxc_status/mod.rs            |  17 ++
 2 files changed, 189 insertions(+)
 create mode 100644 src/pages/page_lxc_status/firewall_panel.rs

diff --git a/src/pages/page_lxc_status/firewall_panel.rs b/src/pages/page_lxc_status/firewall_panel.rs
new file mode 100644
index 0000000..10d76dd
--- /dev/null
+++ b/src/pages/page_lxc_status/firewall_panel.rs
@@ -0,0 +1,172 @@
+use std::rc::Rc;
+
+use serde::{Deserialize, Serialize};
+use yew::virtual_dom::{VComp, VNode};
+
+use pwt::prelude::*;
+use pwt::props::StorageLocation;
+use pwt::state::PersistentState;
+use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
+
+use proxmox_yew_comp::configuration::pve::{FirewallOptionsGuestPanel, FirewallRulesPanel};
+use proxmox_yew_comp::form::pve::PveGuestType;
+
+#[derive(Clone, PartialEq, Properties)]
+pub struct LxcFirewallPanel {
+    vmid: u32,
+    node: AttrValue,
+}
+
+impl LxcFirewallPanel {
+    pub fn new(node: impl Into<AttrValue>, vmid: u32) -> Self {
+        Self {
+            node: node.into(),
+            vmid,
+        }
+    }
+}
+
+#[derive(Copy, Clone, Default, PartialEq, Serialize, Deserialize)]
+pub enum ViewState {
+    #[default]
+    Rules,
+    Options,
+    //Alias,
+    //IPSet,
+    //Log,
+}
+pub struct PveLxcFirewallPanel {
+    view_state: PersistentState<ViewState>,
+}
+
+pub enum Msg {
+    SetViewState(ViewState),
+}
+
+impl Component for PveLxcFirewallPanel {
+    type Message = Msg;
+    type Properties = LxcFirewallPanel;
+
+    fn create(ctx: &Context<Self>) -> Self {
+        let props = ctx.props();
+
+        let view_state = PersistentState::new(StorageLocation::session(format!(
+            "ct-{}-firewall-tab-bar-state",
+            props.vmid
+        )));
+
+        Self { view_state }
+    }
+
+    fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
+        match msg {
+            Msg::SetViewState(view_state) => {
+                self.view_state.update(view_state);
+            }
+        }
+        true
+    }
+    fn view(&self, ctx: &Context<Self>) -> Html {
+        let props = ctx.props();
+
+        let (active_tab, content): (_, Html) = match *self.view_state {
+            ViewState::Rules => (
+                "rules",
+                FirewallRulesPanel::guest_firewall(
+                    PveGuestType::Lxc,
+                    props.node.clone(),
+                    props.vmid,
+                )
+                .mobile(true)
+                .readonly(true)
+                .into(),
+            ),
+            ViewState::Options => (
+                "options",
+                FirewallOptionsGuestPanel::new(PveGuestType::Lxc, props.node.clone(), props.vmid)
+                    .mobile(true)
+                    .readonly(true)
+                    .into(),
+            ),
+            /*ViewState::Alias => (
+                "alias",
+                html! {
+                    <div>{ format!("Firewall alias for VM {}", props.vmid) }</div>
+                },
+            ),
+            ViewState::IPSet => (
+                "ipset",
+                html! {
+                    <div>{ format!("Firewall ipset for VM {}", props.vmid) }</div>
+                },
+            ),
+            ViewState::Log => (
+                "log",
+                html! {
+                    <div>{ format!("Firewall log for VM {}", props.vmid) }</div>
+                },
+            ),*/
+        };
+
+        let tab_bar = TabBar::new()
+            .style(pwt::widget::TabBarStyle::MaterialSecondary)
+            .class(pwt::css::JustifyContent::Center)
+            .class("pwt-flex-fill")
+            .active(active_tab)
+            .with_item(
+                TabBarItem::new()
+                    .key("rules")
+                    .label(tr!("Rules"))
+                    .icon_class("fa fa-shield")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::Rules))),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .key("options")
+                    .label(tr!("Options"))
+                    .icon_class("fa fa-gear")
+                    .on_activate(
+                        ctx.link()
+                            .callback(|_| Msg::SetViewState(ViewState::Options)),
+                    ),
+            )
+            /*.with_item(
+                TabBarItem::new()
+                    .key("alias")
+                    .label(tr!("Alias"))
+                    .icon_class("fa fa-external-link")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::Alias))),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .key("ipset")
+                    .label(tr!("IPSet"))
+                    .icon_class("fa fa-list-ol")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::IPSet))),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .key("log")
+                    .label(tr!("Log"))
+                    .icon_class("fa fa-list")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::Log))),
+            )*/;
+
+        Column::new()
+            .class(pwt::css::FlexFit)
+            .with_child(
+                MiniScroll::new(tab_bar)
+                    .class("pwt-flex-none")
+                    .scroll_mode(pwt::widget::MiniScrollMode::Native),
+            )
+            .with_child(content)
+            .into()
+    }
+}
+
+impl From<LxcFirewallPanel> for VNode {
+    fn from(val: LxcFirewallPanel) -> Self {
+        let comp = VComp::new::<PveLxcFirewallPanel>(Rc::new(val), None);
+        VNode::from(comp)
+    }
+}
diff --git a/src/pages/page_lxc_status/mod.rs b/src/pages/page_lxc_status/mod.rs
index 4092dd5..7d616eb 100644
--- a/src/pages/page_lxc_status/mod.rs
+++ b/src/pages/page_lxc_status/mod.rs
@@ -14,7 +14,9 @@ use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
 use crate::widgets::{GuestBackupPanel, TopNavBar};
 
 mod dashboard_panel;
+mod firewall_panel;
 pub use dashboard_panel::LxcDashboardPanel;
+use firewall_panel::LxcFirewallPanel;
 
 use proxmox_yew_comp::configuration::pve::LxcOptionsPanel;
 
@@ -39,6 +41,7 @@ pub enum ViewState {
     Dashboard,
     Options,
     Backup,
+    Firewall,
 }
 
 pub enum Msg {
@@ -92,6 +95,10 @@ impl Component for PvePageLxcStatus {
                     .readonly(true)
                     .into(),
             ),
+            ViewState::Firewall => (
+                "firewall",
+                LxcFirewallPanel::new(props.node.clone(), props.vmid).into(),
+            ),
         };
 
         let tab_bar = TabBar::new()
@@ -127,6 +134,16 @@ impl Component for PvePageLxcStatus {
                         ctx.link()
                             .callback(|_| Msg::SetViewState(ViewState::Backup)),
                     ),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .label(tr!("Firewall"))
+                    .icon_class("fa fa-shield")
+                    .key("firewall")
+                    .on_activate(
+                        ctx.link()
+                            .callback(|_| Msg::SetViewState(ViewState::Firewall)),
+                    ),
             );
 
         Column::new()
-- 
2.47.3





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

* [PATCH yew-mobile-gui 17/20] node status: align layout for node status with guest pages
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (15 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 16/20] lxc: add support for a rudimentary firewall tab for lxc guests Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 18/20] node: add a rudimentary firewall tab for cluster nodes Shannon Sterz
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

by adding icons and scrolling to the top-level tab bar.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_node_status/mod.rs | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/pages/page_node_status/mod.rs b/src/pages/page_node_status/mod.rs
index be6a98c..a566179 100644
--- a/src/pages/page_node_status/mod.rs
+++ b/src/pages/page_node_status/mod.rs
@@ -1,6 +1,7 @@
 use std::rc::Rc;
 
 use anyhow::Error;
+use pwt::css::Flex;
 use serde::{Deserialize, Serialize};
 
 use yew::prelude::*;
@@ -10,7 +11,7 @@ use pwt::AsyncAbortGuard;
 use pwt::prelude::*;
 use pwt::props::StorageLocation;
 use pwt::state::PersistentState;
-use pwt::widget::{Column, TabBar, TabBarItem};
+use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
 
 use proxmox_yew_comp::http_get;
 
@@ -122,10 +123,12 @@ impl Component for PvePageNodeStatus {
 
         let tab_bar = TabBar::new()
             .class(pwt::css::JustifyContent::Center)
+            .class(Flex::Fill)
             .active(active_tab)
             .with_item(
                 TabBarItem::new()
                     .label(tr!("Dashboard"))
+                    .icon_class("fa fa-book")
                     .key("dashboard")
                     .on_activate(
                         ctx.link()
@@ -135,6 +138,7 @@ impl Component for PvePageNodeStatus {
             .with_item(
                 TabBarItem::new()
                     .label(tr!("Services"))
+                    .icon_class("fa fa-cogs")
                     .key("services")
                     .on_activate(
                         ctx.link()
@@ -144,6 +148,7 @@ impl Component for PvePageNodeStatus {
             .with_item(
                 TabBarItem::new()
                     .label(tr!("Updates"))
+                    .icon_class("fa fa-refresh")
                     .key("updates")
                     .on_activate(
                         ctx.link()
@@ -158,7 +163,11 @@ impl Component for PvePageNodeStatus {
                     .title(format!("Node {}", props.node))
                     .back("/resources"),
             )
-            .with_child(tab_bar)
+            .with_child(
+                MiniScroll::new(tab_bar)
+                    .class(Flex::None)
+                    .scroll_mode(pwt::widget::MiniScrollMode::Native),
+            )
             .with_child(content)
             .into()
     }
-- 
2.47.3





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

* [PATCH yew-mobile-gui 18/20] node: add a rudimentary firewall tab for cluster nodes
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (16 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 17/20] node status: align layout for node status with guest pages Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 19/20] api types: remove unused file Shannon Sterz
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/pages/page_node_status/firewall_panel.rs | 163 +++++++++++++++++++
 src/pages/page_node_status/mod.rs            |  18 ++
 2 files changed, 181 insertions(+)
 create mode 100644 src/pages/page_node_status/firewall_panel.rs

diff --git a/src/pages/page_node_status/firewall_panel.rs b/src/pages/page_node_status/firewall_panel.rs
new file mode 100644
index 0000000..c64c05e
--- /dev/null
+++ b/src/pages/page_node_status/firewall_panel.rs
@@ -0,0 +1,163 @@
+use std::rc::Rc;
+
+use serde::{Deserialize, Serialize};
+use yew::virtual_dom::{VComp, VNode};
+
+use pwt::prelude::*;
+use pwt::props::StorageLocation;
+use pwt::state::PersistentState;
+use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
+
+use proxmox_yew_comp::configuration::pve::{FirewallOptionsNodePanel, FirewallRulesPanel};
+
+#[derive(Clone, PartialEq, Properties)]
+pub struct NodeFirewallPanel {
+    node: AttrValue,
+}
+
+impl NodeFirewallPanel {
+    pub fn new(node: impl Into<AttrValue>) -> Self {
+        Self { node: node.into() }
+    }
+}
+
+#[derive(Copy, Clone, Default, PartialEq, Serialize, Deserialize)]
+pub enum ViewState {
+    #[default]
+    Rules,
+    Options,
+    //Alias,
+    //IPSet,
+    //Log,
+}
+pub struct PveNodeFirewallPanel {
+    view_state: PersistentState<ViewState>,
+}
+
+pub enum Msg {
+    SetViewState(ViewState),
+}
+
+impl Component for PveNodeFirewallPanel {
+    type Message = Msg;
+    type Properties = NodeFirewallPanel;
+
+    fn create(ctx: &Context<Self>) -> Self {
+        let props = ctx.props();
+
+        let view_state = PersistentState::new(StorageLocation::session(format!(
+            "node-{}-firewall-tab-bar-state",
+            props.node
+        )));
+
+        Self { view_state }
+    }
+
+    fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
+        match msg {
+            Msg::SetViewState(view_state) => {
+                self.view_state.update(view_state);
+            }
+        }
+        true
+    }
+    fn view(&self, ctx: &Context<Self>) -> Html {
+        let props = ctx.props();
+
+        let (active_tab, content): (_, Html) = match *self.view_state {
+            ViewState::Rules => (
+                "rules",
+                FirewallRulesPanel::node_firewall(props.node.clone())
+                    .mobile(true)
+                    .readonly(true)
+                    .into(),
+            ),
+            ViewState::Options => (
+                "options",
+                FirewallOptionsNodePanel::new(props.node.clone())
+                    .mobile(true)
+                    .readonly(true)
+                    .into(),
+            ),
+            /*ViewState::Alias => (
+                "alias",
+                html! {
+                    <div>{ format!("Firewall alias for VM {}", props.vmid) }</div>
+                },
+            ),
+            ViewState::IPSet => (
+                "ipset",
+                html! {
+                    <div>{ format!("Firewall ipset for VM {}", props.vmid) }</div>
+                },
+            ),
+            ViewState::Log => (
+                "log",
+                html! {
+                    <div>{ format!("Firewall log for VM {}", props.vmid) }</div>
+                },
+            ),*/
+        };
+
+        let tab_bar = TabBar::new()
+            .style(pwt::widget::TabBarStyle::MaterialSecondary)
+            .class(pwt::css::JustifyContent::Center)
+            .class("pwt-flex-fill")
+            .active(active_tab)
+            .with_item(
+                TabBarItem::new()
+                    .key("rules")
+                    .label(tr!("Rules"))
+                    .icon_class("fa fa-shield")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::Rules))),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .key("options")
+                    .label(tr!("Options"))
+                    .icon_class("fa fa-gear")
+                    .on_activate(
+                        ctx.link()
+                            .callback(|_| Msg::SetViewState(ViewState::Options)),
+                    ),
+            )
+            /*.with_item(
+                TabBarItem::new()
+                    .key("alias")
+                    .label(tr!("Alias"))
+                    .icon_class("fa fa-external-link")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::Alias))),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .key("ipset")
+                    .label(tr!("IPSet"))
+                    .icon_class("fa fa-list-ol")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::IPSet))),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .key("log")
+                    .label(tr!("Log"))
+                    .icon_class("fa fa-list")
+                    .on_activate(ctx.link().callback(|_| Msg::SetViewState(ViewState::Log))),
+            )*/;
+
+        Column::new()
+            .class(pwt::css::FlexFit)
+            .with_child(
+                MiniScroll::new(tab_bar)
+                    .class("pwt-flex-none")
+                    .scroll_mode(pwt::widget::MiniScrollMode::Native),
+            )
+            .with_child(content)
+            .into()
+    }
+}
+
+impl From<NodeFirewallPanel> for VNode {
+    fn from(val: NodeFirewallPanel) -> Self {
+        let comp = VComp::new::<PveNodeFirewallPanel>(Rc::new(val), None);
+        VNode::from(comp)
+    }
+}
diff --git a/src/pages/page_node_status/mod.rs b/src/pages/page_node_status/mod.rs
index a566179..efb3d92 100644
--- a/src/pages/page_node_status/mod.rs
+++ b/src/pages/page_node_status/mod.rs
@@ -28,6 +28,9 @@ pub use services_panel::NodeServicesPanel;
 mod updates_panel;
 pub use updates_panel::NodeUpdatesPanel;
 
+mod firewall_panel;
+use firewall_panel::NodeFirewallPanel;
+
 #[derive(Clone, PartialEq, Properties)]
 pub struct PageNodeStatus {
     node: AttrValue,
@@ -47,6 +50,7 @@ pub enum ViewState {
     Dashboard,
     Services,
     Updates,
+    Firewall,
 }
 
 pub enum Msg {
@@ -119,6 +123,10 @@ impl Component for PvePageNodeStatus {
                 NodeServicesPanel::new(props.node.clone(), standalone).into(),
             ),
             ViewState::Updates => ("updates", NodeUpdatesPanel::new(props.node.clone()).into()),
+            ViewState::Firewall => (
+                "firewall",
+                NodeFirewallPanel::new(props.node.clone()).into(),
+            ),
         };
 
         let tab_bar = TabBar::new()
@@ -154,6 +162,16 @@ impl Component for PvePageNodeStatus {
                         ctx.link()
                             .callback(|_| Msg::SetViewState(ViewState::Updates)),
                     ),
+            )
+            .with_item(
+                TabBarItem::new()
+                    .label(tr!("Firewall"))
+                    .icon_class("fa fa-shield")
+                    .key("firewall")
+                    .on_activate(
+                        ctx.link()
+                            .callback(|_| Msg::SetViewState(ViewState::Firewall)),
+                    ),
             );
 
         Column::new()
-- 
2.47.3





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

* [PATCH yew-mobile-gui 19/20] api types: remove unused file
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (17 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 18/20] node: add a rudimentary firewall tab for cluster nodes Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 20/20] resources page: map subscription level analogous to dashboard Shannon Sterz
  2026-05-08 15:59 ` Superseded: Re: [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

the api types defined here are no longer used, remove them

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 src/api_types.rs | 131 -----------------------------------------------
 1 file changed, 131 deletions(-)
 delete mode 100644 src/api_types.rs

diff --git a/src/api_types.rs b/src/api_types.rs
deleted file mode 100644
index d2bda9a..0000000
--- a/src/api_types.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-use serde::{Deserialize, Serialize};
-use serde_json::Value;
-
-use proxmox_schema::{api, ApiStringFormat};
-
-// fixme: define all those types in pve-api-types
-
-#[derive(Deserialize, Serialize, PartialEq, Clone)]
-pub struct StorageEntry {
-    pub format: String,
-    pub content: String,
-    pub size: i64,
-    pub volid: String,
-}
-
-#[derive(Deserialize, Serialize, PartialEq, Clone)]
-#[serde(rename_all = "kebab-case")]
-pub struct ServiceStatus {
-    pub state: String,
-    pub active_state: String,
-    pub unit_state: String,
-    pub name: String,
-    pub service: String,
-    pub desc: String,
-}
-
-#[api {
-    default_key: "order",
-    properties: {
-        order: {
-            type: u32,
-            optional: true,
-            minimum: 0,
-        },
-           up: {
-            type: u32,
-            optional: true,
-            minimum: 0,
-        },
-        down: {
-            type: u32,
-            optional: true,
-            minimum: 0,
-        },
-    }
-}]
-#[derive(Deserialize, Serialize, PartialEq, Clone)]
-/// Qemu Startup ordering
-pub struct QemuConfigStartup {
-    /// Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub order: Option<u32>,
-    /// Delay (seconds) to wait before the next VM is started.
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub up: Option<u32>,
-    /// Delay (seconds) to wait before the next VM is stopped.
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub down: Option<u32>,
-}
-
-#[api]
-#[derive(Deserialize, Serialize, PartialEq, Clone)]
-/// Qemu CPU model info (GET /api2/json/nodes/{node}/capabilities/qemu/cpu
-pub struct QemuCpuModel {
-    /// True if this is a custom CPU model.
-    #[serde(deserialize_with = "proxmox_serde::perl::deserialize_bool")]
-    pub custom: bool,
-    /// Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.
-    pub name: String,
-    /// CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.
-    pub vendor: String,
-}
-
-#[api]
-/// Qemu Machine Type (q35 or pc)
-#[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
-pub enum QemuMachineType {
-    #[serde(rename = "q35")]
-    /// Q35
-    Q35,
-    #[serde(rename = "i440fx")]
-    /// I440FX
-    I440fx,
-    #[serde(rename = "virt")]
-    /// Virt (Arm)
-    ///
-    /// Note: Not returned by the api for now.
-    Virt,
-}
-serde_plain::derive_display_from_serialize!(QemuMachineType);
-serde_plain::derive_fromstr_from_deserialize!(QemuMachineType);
-
-#[api(
-    properties: {
-        type: {
-            format: &ApiStringFormat::PropertyString(&QemuMachineType::API_SCHEMA),
-            type: String,
-        }
-    }
-)]
-#[derive(Deserialize, Serialize, PartialEq, Clone)]
-/// Machine type info (GET /api2/json/nodes/{node}/capabilities/qemu/machines
-pub struct QemuMachineInfo {
-    /// Full name of machine type and version.
-    pub id: String,
-    /// Machine type
-    #[serde(rename = "type")]
-    pub ty: QemuMachineType,
-    /// The machine version.
-    pub version: String,
-    /// Notable changes of a version, currently only set for +pveX versions.
-    #[serde(default, skip_serializing_if = "Option::is_none")]
-    pub changes: Option<String>,
-}
-
-#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
-/// Get the virtual machine configuration with both current and pending values.
-///
-/// (`GET /api2/json/nodes/{node}/qemu/{vmid}/pending) -> Vec<QemuPendingConfigValue>`
-pub struct QemuPendingConfigValue {
-    /// Configuration option name.
-    pub key: String,
-    /// Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.
-    #[serde(default, skip_serializing_if = "Option::is_none")]
-    pub delete: Option<u8>,
-    /// Current value.
-    pub value: Option<Value>,
-    /// Pending value.
-    #[serde(default, skip_serializing_if = "Option::is_none")]
-    pub pending: Option<Value>,
-}
-- 
2.47.3





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

* [PATCH yew-mobile-gui 20/20] resources page: map subscription level analogous to dashboard
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (18 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 19/20] api types: remove unused file Shannon Sterz
@ 2026-05-08 15:05 ` Shannon Sterz
  2026-05-08 15:22   ` Shan Shaji
  2026-05-08 15:59 ` Superseded: Re: [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
  20 siblings, 1 reply; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:05 UTC (permalink / raw)
  To: yew-devel

and unify the mapping logic.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---

Notes:
    i couldn't find a similar helper anyway in yew-comp yet, so i added
    this here for now. Thomas' recent series [1] added something like
    that, but that would only be available for pdm. maybe we should have
    something like this in yew-comp?
    
    [1]: https://lore.proxmox.com/pdm-devel/20260507082943.2749725-3-t.lamprecht@proxmox.com/

 src/pages/mod.rs            | 13 +++++++++++++
 src/pages/page_dashboard.rs | 13 ++-----------
 src/pages/page_resources.rs |  8 +++-----
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/pages/mod.rs b/src/pages/mod.rs
index bc5ff97..3d945a0 100644
--- a/src/pages/mod.rs
+++ b/src/pages/mod.rs
@@ -45,3 +45,16 @@ pub use page_cluster_firewall::PageClusterFirewall;
 
 mod page_not_found;
 pub use page_not_found::PageNotFound;
+
+fn map_subscription(level: &Option<String>) -> &str {
+    match level.as_deref() {
+        Some("") | None => "no subscription",
+        Some(level) => match level {
+            "c" => "Community",
+            "b" => "Basic",
+            "s" => "Standard",
+            "p" => "Premium",
+            _ => "-",
+        },
+    }
+}
diff --git a/src/pages/page_dashboard.rs b/src/pages/page_dashboard.rs
index 1e0243f..fe2f5b4 100644
--- a/src/pages/page_dashboard.rs
+++ b/src/pages/page_dashboard.rs
@@ -20,7 +20,7 @@ use proxmox_yew_comp::layout::list_tile::{icon_list_tile, list_tile_usage};
 use proxmox_yew_comp::layout::render_loaded_data;
 use proxmox_yew_comp::{SubscriptionAlert, http_get};
 
-use crate::pages::ResourceFilter;
+use crate::pages::{ResourceFilter, map_subscription};
 use crate::widgets::TopNavBar;
 
 #[derive(Clone, PartialEq, Properties)]
@@ -202,16 +202,7 @@ impl PvePageDashboard {
                     let navigator = navigator.clone();
                     let item = &nodes[pos as usize];
                     let nodename = item.node.clone();
-                    let subtitle = match item.level.as_deref() {
-                        Some("") | None => "no subscription",
-                        Some(level) => match level {
-                            "c" => "Community",
-                            "b" => "Basic",
-                            "s" => "Standard",
-                            "p" => "Premium",
-                            _ => "-",
-                        },
-                    };
+                    let subtitle = map_subscription(&item.level);
 
                     icon_list_tile(
                         Fa::new("server").class(
diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
index 469bbf3..470a054 100644
--- a/src/pages/page_resources.rs
+++ b/src/pages/page_resources.rs
@@ -23,6 +23,8 @@ use proxmox_yew_comp::layout::render_loaded_data;
 
 use pve_api_types::{ClusterResource, ClusterResourceType};
 
+use crate::pages::map_subscription;
+
 #[derive(Clone, PartialEq, Properties)]
 pub struct PageResources {}
 
@@ -119,11 +121,7 @@ impl PvePageResources {
             Fa::new("server")
                 .class((item.status.as_deref() == Some("online")).then_some("pwt-color-primary")),
             nodename.clone(),
-            match item.level.as_deref() {
-                Some("") | None => "no subscription",
-                Some(level) => level,
-            }
-            .to_string(),
+            map_subscription(&item.level),
             item.status.clone(),
         )
         .interactive(true)
-- 
2.47.3





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

* Re: [PATCH yew-mobile-gui 20/20] resources page: map subscription level analogous to dashboard
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 20/20] resources page: map subscription level analogous to dashboard Shannon Sterz
@ 2026-05-08 15:22   ` Shan Shaji
  0 siblings, 0 replies; 24+ messages in thread
From: Shan Shaji @ 2026-05-08 15:22 UTC (permalink / raw)
  To: Shannon Sterz, yew-devel

Hi,

I have tested this patch with my community subscription. Now the status
is correctly shown on both dashboard and resources pages.

Tested-by: Shan Shaji <s.shaji@proxmox.com>

On Fri May 8, 2026 at 5:05 PM CEST, Shannon Sterz wrote:
> and unify the mapping logic.
>
> Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
> ---
>
> Notes:
>     i couldn't find a similar helper anyway in yew-comp yet, so i added
>     this here for now. Thomas' recent series [1] added something like
>     that, but that would only be available for pdm. maybe we should have
>     something like this in yew-comp?
>     
>     [1]: https://lore.proxmox.com/pdm-devel/20260507082943.2749725-3-t.lamprecht@proxmox.com/
>
>  src/pages/mod.rs            | 13 +++++++++++++
>  src/pages/page_dashboard.rs | 13 ++-----------
>  src/pages/page_resources.rs |  8 +++-----
>  3 files changed, 18 insertions(+), 16 deletions(-)
>
> diff --git a/src/pages/mod.rs b/src/pages/mod.rs
> index bc5ff97..3d945a0 100644
> --- a/src/pages/mod.rs
> +++ b/src/pages/mod.rs
> @@ -45,3 +45,16 @@ pub use page_cluster_firewall::PageClusterFirewall;
>  
>  mod page_not_found;
>  pub use page_not_found::PageNotFound;
> +
> +fn map_subscription(level: &Option<String>) -> &str {
> +    match level.as_deref() {
> +        Some("") | None => "no subscription",
> +        Some(level) => match level {
> +            "c" => "Community",
> +            "b" => "Basic",
> +            "s" => "Standard",
> +            "p" => "Premium",
> +            _ => "-",
> +        },
> +    }
> +}
> diff --git a/src/pages/page_dashboard.rs b/src/pages/page_dashboard.rs
> index 1e0243f..fe2f5b4 100644
> --- a/src/pages/page_dashboard.rs
> +++ b/src/pages/page_dashboard.rs
> @@ -20,7 +20,7 @@ use proxmox_yew_comp::layout::list_tile::{icon_list_tile, list_tile_usage};
>  use proxmox_yew_comp::layout::render_loaded_data;
>  use proxmox_yew_comp::{SubscriptionAlert, http_get};
>  
> -use crate::pages::ResourceFilter;
> +use crate::pages::{ResourceFilter, map_subscription};
>  use crate::widgets::TopNavBar;
>  
>  #[derive(Clone, PartialEq, Properties)]
> @@ -202,16 +202,7 @@ impl PvePageDashboard {
>                      let navigator = navigator.clone();
>                      let item = &nodes[pos as usize];
>                      let nodename = item.node.clone();
> -                    let subtitle = match item.level.as_deref() {
> -                        Some("") | None => "no subscription",
> -                        Some(level) => match level {
> -                            "c" => "Community",
> -                            "b" => "Basic",
> -                            "s" => "Standard",
> -                            "p" => "Premium",
> -                            _ => "-",
> -                        },
> -                    };
> +                    let subtitle = map_subscription(&item.level);
>  
>                      icon_list_tile(
>                          Fa::new("server").class(
> diff --git a/src/pages/page_resources.rs b/src/pages/page_resources.rs
> index 469bbf3..470a054 100644
> --- a/src/pages/page_resources.rs
> +++ b/src/pages/page_resources.rs
> @@ -23,6 +23,8 @@ use proxmox_yew_comp::layout::render_loaded_data;
>  
>  use pve_api_types::{ClusterResource, ClusterResourceType};
>  
> +use crate::pages::map_subscription;
> +
>  #[derive(Clone, PartialEq, Properties)]
>  pub struct PageResources {}
>  
> @@ -119,11 +121,7 @@ impl PvePageResources {
>              Fa::new("server")
>                  .class((item.status.as_deref() == Some("online")).then_some("pwt-color-primary")),
>              nodename.clone(),
> -            match item.level.as_deref() {
> -                Some("") | None => "no subscription",
> -                Some(level) => level,
> -            }
> -            .to_string(),
> +            map_subscription(&item.level),
>              item.status.clone(),
>          )
>          .interactive(true)





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

* Re: [PATCH yew-mobile-gui 15/20] lxc page: align layout for lxc guest with qemu guests
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 15/20] lxc page: align layout for lxc guest with qemu guests Shannon Sterz
@ 2026-05-08 15:43   ` Shannon Sterz
  0 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:43 UTC (permalink / raw)
  To: Shannon Sterz, yew-devel

On Fri May 8, 2026 at 5:05 PM CEST, Shannon Sterz wrote:
> by adding icons and scrolling to the top-level tab panel
>
> Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
> ---
>  src/pages/page_lxc_status/mod.rs | 24 ++++++++++++++++++------
>  1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/src/pages/page_lxc_status/mod.rs b/src/pages/page_lxc_status/mod.rs
> index 97ebddf..4092dd5 100644
> --- a/src/pages/page_lxc_status/mod.rs
> +++ b/src/pages/page_lxc_status/mod.rs
> @@ -1,5 +1,6 @@
>  use std::rc::Rc;
>
> +use pwt::css::Flex;
>  use pwt::props::StorageLocation;
>  use serde::{Deserialize, Serialize};
>
> @@ -8,7 +9,7 @@ use yew::virtual_dom::{VComp, VNode};
>
>  use pwt::prelude::*;
>  use pwt::state::PersistentState;
> -use pwt::widget::{Column, TabBar, TabBarItem};
> +use pwt::widget::{Column, MiniScroll, TabBar, TabBarItem};
>
>  use crate::widgets::{GuestBackupPanel, TopNavBar};
>
> @@ -95,10 +96,12 @@ impl Component for PvePageLxcStatus {
>
>          let tab_bar = TabBar::new()
>              .class(pwt::css::JustifyContent::Center)
> +            .class(Flex::Fill)
>              .active(active_tab)
>              .with_item(
>                  TabBarItem::new()
>                      .label("Dashboard")
> +                    .icon_class("fa fa-book")
>                      .key("dashboard")
>                      .on_activate(
>                          ctx.link()
> @@ -108,6 +111,7 @@ impl Component for PvePageLxcStatus {
>              .with_item(
>                  TabBarItem::new()
>                      .label("Options")
> +                    .icon_class("fa fa-floppy-o")

i just noticed that the icons for "Options" and "Backup" should probably
be switched. this was copied over from the qemu panel, i'll send a
commit fixing that for both components in a minute. if a v2 becomes
necessary i'll in-line that patch for this component here.

>                      .key("options")
>                      .on_activate(
>                          ctx.link()
> @@ -115,10 +119,14 @@ impl Component for PvePageLxcStatus {
>                      ),
>              )
>              .with_item(
> -                TabBarItem::new().label("Backup").key("backup").on_activate(
> -                    ctx.link()
> -                        .callback(|_| Msg::SetViewState(ViewState::Backup)),
> -                ),
> +                TabBarItem::new()
> +                    .label("Backup")
> +                    .icon_class("fa fa-gear")
> +                    .key("backup")
> +                    .on_activate(
> +                        ctx.link()
> +                            .callback(|_| Msg::SetViewState(ViewState::Backup)),
> +                    ),
>              );
>
>          Column::new()
> @@ -128,7 +136,11 @@ impl Component for PvePageLxcStatus {
>                      .title(format!("CT {}", props.vmid))
>                      .back("/resources"),
>              )
> -            .with_child(tab_bar)
> +            .with_child(
> +                MiniScroll::new(tab_bar)
> +                    .class(Flex::None)
> +                    .scroll_mode(pwt::widget::MiniScrollMode::Native),
> +            )
>              .with_child(content)
>              .into()
>      }





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

* Superseded: Re: [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui
  2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
                   ` (19 preceding siblings ...)
  2026-05-08 15:05 ` [PATCH yew-mobile-gui 20/20] resources page: map subscription level analogous to dashboard Shannon Sterz
@ 2026-05-08 15:59 ` Shannon Sterz
  20 siblings, 0 replies; 24+ messages in thread
From: Shannon Sterz @ 2026-05-08 15:59 UTC (permalink / raw)
  To: Shannon Sterz, yew-devel

discovered one more thing, so consider this:

Superseded-by: https://lore.proxmox.com/yew-devel/20260508155722.464564-1-s.sterz@proxmox.com/

On Fri May 8, 2026 at 5:05 PM CEST, Shannon Sterz wrote:
> this series cleans up the pve-yew-mobile-gui a little bit. it does so by first
> fixing a bug in proxmox-yew-comp. then pve-yew-mobile-gui is made clippy clean
> again. the last six patches add, unify and clean up functionality in the gui.
> the main changes are as follows:
>
> * properly populate the rules tab of the existing firewall tabs and comment out
>   empty sub-tabs.
> * add a firewall tab for container guests and nodes
> * two small ui clean ups in how subscription levels and cpu utilization is
>   rendered
>
>
> yew-comp:
>
> Shannon Sterz (1):
>   firewall rules panel: correct the url for the pve cluster firewall
>     rules
>
>  src/configuration/pve/firewall/firewall_rules_panel.rs | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
>
> yew-mobile-gui:
>
> Shannon Sterz (19):
>   cargo.toml: globally ignore certain clippy lints
>   main: avoid unnecessary clones
>   tree-wide: collapse if statements
>   tree-wide: implement the `From` trait instead of the `Into` trait
>   tree-wide: implement `Default` for types with an `new()` constructor
>   tree-wide: remove unnecessary lazy evaluations
>   tree-wide: remove needless borrows
>   configuration page: remove redundant static lifetimes
>   resources/configuration page: remove useless `.into()` calls
>   tree-wide: fix several clippy lints
>   dashboard: use proper plural translation string instead of "CPU(s)"
>   configuration: clarify that "Firewall" shows the cluster's firewall
>   cluster/qemu firewall: use rules panel and comment out unused tabs
>   lxc page: align layout for lxc guest with qemu guests
>   lxc: add support for a rudimentary firewall tab for lxc guests
>   node status: align layout for node status with guest pages
>   node: add a rudimentary firewall tab for cluster nodes
>   api types: remove unused file
>   resources page: map subscription level analogous to dashboard
>
>  Cargo.toml                                    |   5 +
>  src/api_types.rs                              | 131 -------------
>  src/main.rs                                   |  25 ++-
>  src/pages/mod.rs                              |  13 ++
>  src/pages/page_cluster_firewall/mod.rs        |  35 ++--
>  src/pages/page_configuartion.rs               |  22 ++-
>  src/pages/page_dashboard.rs                   |  43 ++---
>  src/pages/page_login.rs                       |  12 +-
>  src/pages/page_lxc_status/dashboard_panel.rs  |  70 ++++---
>  src/pages/page_lxc_status/firewall_panel.rs   | 172 ++++++++++++++++++
>  src/pages/page_lxc_status/mod.rs              |  47 ++++-
>  src/pages/page_lxc_tasks.rs                   |   6 +-
>  src/pages/page_node_status/dashboard_panel.rs |   6 +-
>  src/pages/page_node_status/firewall_panel.rs  | 163 +++++++++++++++++
>  src/pages/page_node_status/mod.rs             |  37 +++-
>  src/pages/page_node_status/services_panel.rs  |   2 +-
>  src/pages/page_node_tasks.rs                  |   6 +-
>  src/pages/page_qemu_status/dashboard_panel.rs |  77 ++++----
>  src/pages/page_qemu_status/firewall_panel.rs  |  33 ++--
>  src/pages/page_qemu_status/mod.rs             |   6 +-
>  src/pages/page_qemu_tasks.rs                  |   6 +-
>  src/pages/page_resources.rs                   |  50 ++---
>  src/pages/page_settings.rs                    |  12 +-
>  src/pages/page_storage_status.rs              |   6 +-
>  src/pages/page_task_status.rs                 |   6 +-
>  src/widgets/guest_backup_panel.rs             |   4 +-
>  src/widgets/task_list_button.rs               |  29 +--
>  src/widgets/tasks_panel.rs                    |   2 +-
>  src/widgets/top_nav_bar.rs                    |  12 +-
>  29 files changed, 671 insertions(+), 367 deletions(-)
>  delete mode 100644 src/api_types.rs
>  create mode 100644 src/pages/page_lxc_status/firewall_panel.rs
>  create mode 100644 src/pages/page_node_status/firewall_panel.rs
>
>
> Summary over all repositories:
>   30 files changed, 672 insertions(+), 368 deletions(-)





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

end of thread, other threads:[~2026-05-08 15:59 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-08 15:05 [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-comp 01/20] firewall rules panel: correct the url for the pve cluster firewall rules Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 02/20] cargo.toml: globally ignore certain clippy lints Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 03/20] main: avoid unnecessary clones Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 04/20] tree-wide: collapse if statements Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 05/20] tree-wide: implement the `From` trait instead of the `Into` trait Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 06/20] tree-wide: implement `Default` for types with an `new()` constructor Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 07/20] tree-wide: remove unnecessary lazy evaluations Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 08/20] tree-wide: remove needless borrows Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 09/20] configuration page: remove redundant static lifetimes Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 10/20] resources/configuration page: remove useless `.into()` calls Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 11/20] tree-wide: fix several clippy lints Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 12/20] dashboard: use proper plural translation string instead of "CPU(s)" Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 13/20] configuration: clarify that "Firewall" shows the cluster's firewall Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 14/20] cluster/qemu firewall: use rules panel and comment out unused tabs Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 15/20] lxc page: align layout for lxc guest with qemu guests Shannon Sterz
2026-05-08 15:43   ` Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 16/20] lxc: add support for a rudimentary firewall tab for lxc guests Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 17/20] node status: align layout for node status with guest pages Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 18/20] node: add a rudimentary firewall tab for cluster nodes Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 19/20] api types: remove unused file Shannon Sterz
2026-05-08 15:05 ` [PATCH yew-mobile-gui 20/20] resources page: map subscription level analogous to dashboard Shannon Sterz
2026-05-08 15:22   ` Shan Shaji
2026-05-08 15:59 ` Superseded: Re: [PATCH yew-comp/yew-mobile-gui 00/20] firewall tabs and clean up for pve-yew-mobile-gui Shannon Sterz

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