all lists on 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal