* [pdm-devel] [PATCH yew-comp/datacenter-manager] some ui improvements
@ 2025-04-11 14:05 Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status Dominik Csapak
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Dominik Csapak @ 2025-04-11 14:05 UTC (permalink / raw)
To: pdm-devel
Some smaller improvements for the ui, mostly refactor and preparation
for an upcoming series that improves the search box.
pdm patch 3/3 depends on the proxmox-yew-comp patch.
proxmox-yew-comp:
Dominik Csapak (1):
status: implement PartialEq and Clone for Status
src/status.rs | 4 ++++
1 file changed, 4 insertions(+)
proxmox-datacenter-manager:
Dominik Csapak (3):
ui: improve keyboard navigation for search box
ui: dashboard: refactor remotes panel
ui: dashboard: refactor guest panel
ui/src/dashboard/guest_panel.rs | 143 +++++++++++++++++++++++++++++++
ui/src/dashboard/mod.rs | 103 ++++++----------------
ui/src/dashboard/remote_panel.rs | 90 +++++++++++++++++++
ui/src/pve/mod.rs | 11 ++-
ui/src/widget/resource_tree.rs | 76 ++++++++++------
5 files changed, 318 insertions(+), 105 deletions(-)
create mode 100644 ui/src/dashboard/guest_panel.rs
create mode 100644 ui/src/dashboard/remote_panel.rs
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status
2025-04-11 14:05 [pdm-devel] [PATCH yew-comp/datacenter-manager] some ui improvements Dominik Csapak
@ 2025-04-11 14:05 ` Dominik Csapak
2025-04-14 14:50 ` Wolfgang Bumiller
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 1/3] ui: improve keyboard navigation for search box Dominik Csapak
` (3 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Dominik Csapak @ 2025-04-11 14:05 UTC (permalink / raw)
To: pdm-devel
this is sensible to have, e.g. when we want to have the status structs
as parto of a type for a store
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
src/status.rs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/status.rs b/src/status.rs
index 9d951c5..ab77a15 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -7,6 +7,7 @@ use pwt::{
/// Used to represent a Status of some resource or component, e.g.
/// if a PVE node is online or not.
+#[derive(PartialEq, Clone)]
pub enum Status {
Success,
Warning,
@@ -27,6 +28,7 @@ impl Status {
}
/// Used to represent the state of a Node, being PVE or PBS
+#[derive(PartialEq, Clone)]
pub enum NodeState {
Online,
Offline,
@@ -45,6 +47,7 @@ impl NodeState {
}
/// Used to represent the state of a PVE guest, such as a VM
+#[derive(PartialEq, Clone)]
pub enum GuestState {
Running,
Paused,
@@ -67,6 +70,7 @@ impl GuestState {
}
/// Used to represent the state of a Storage or Datastore
+#[derive(PartialEq, Clone)]
pub enum StorageState {
Available,
Unavailable,
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 1/3] ui: improve keyboard navigation for search box
2025-04-11 14:05 [pdm-devel] [PATCH yew-comp/datacenter-manager] some ui improvements Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status Dominik Csapak
@ 2025-04-11 14:05 ` Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard: refactor remotes panel Dominik Csapak
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Dominik Csapak @ 2025-04-11 14:05 UTC (permalink / raw)
To: pdm-devel
instead of triggering a navigation on selection change, trigger it only
on click and on pressing enter. With this, navigation in the tree is
possible without changing the current route.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
ui/src/widget/resource_tree.rs | 76 ++++++++++++++++++++++------------
1 file changed, 50 insertions(+), 26 deletions(-)
diff --git a/ui/src/widget/resource_tree.rs b/ui/src/widget/resource_tree.rs
index 1b764f7..feff308 100644
--- a/ui/src/widget/resource_tree.rs
+++ b/ui/src/widget/resource_tree.rs
@@ -12,7 +12,10 @@ use pwt::{
props::ExtractPrimaryKey,
state::{Selection, TreeStore},
widget::{
- data_table::{DataTable, DataTableColumn, DataTableHeader},
+ data_table::{
+ DataTable, DataTableColumn, DataTableHeader, DataTableKeyboardEvent,
+ DataTableMouseEvent,
+ },
ActionIcon, Column, Container, Fa, Panel, Progress, Row, Tooltip,
},
};
@@ -118,28 +121,8 @@ impl Component for PdmResourceTree {
}
let store = TreeStore::new().view_root(false);
- let selection = Selection::new().on_select({
- let store = store.clone();
- let link = ctx.link().clone();
- move |selection: Selection| {
- let store = store.read();
- let root = store.root().unwrap();
-
- if let Some(key) = selection.selected_key() {
- if let Some(node) = root.find_node_by_key(&key) {
- match node.record() {
- PdmTreeEntry::Resource(remote, resource) => {
- crate::navigate_to(&link, remote, Some(resource));
- }
- PdmTreeEntry::Remote(remote, _) => {
- crate::navigate_to(&link, remote, None);
- }
- _ => {}
- }
- }
- }
- }
- });
+ let selection = Selection::new();
+
Self {
loading: false,
last_error: None,
@@ -231,8 +214,36 @@ impl Component for PdmResourceTree {
fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
let props = ctx.props();
- let table = DataTable::new(columns(&ctx.link(), self.store.clone()), self.store.clone())
+ let table = DataTable::new(columns(ctx.link(), self.store.clone()), self.store.clone())
.selection(self.selection.clone())
+ .on_row_click({
+ let store = self.store.clone();
+ let link = ctx.link().clone();
+ move |event: &mut DataTableMouseEvent| {
+ let store = store.read();
+ let root = store.root().unwrap();
+
+ if let Some(node) = root.find_node_by_key(&event.record_key) {
+ navigate_to_entry(&link, node.record());
+ }
+ }
+ })
+ .on_row_keydown({
+ let store = self.store.clone();
+ let link = ctx.link().clone();
+ move |event: &mut DataTableKeyboardEvent| {
+ let store = store.read();
+ let root = store.root().unwrap();
+
+ if event.key().as_str() != "Enter" {
+ return;
+ }
+
+ if let Some(node) = root.find_node_by_key(&event.record_key) {
+ navigate_to_entry(&link, node.record());
+ }
+ }
+ })
.class(FlexFit)
.hover(true)
.borderless(true);
@@ -275,6 +286,18 @@ impl Component for PdmResourceTree {
}
}
+fn navigate_to_entry(link: &html::Scope<PdmResourceTree>, record: &PdmTreeEntry) {
+ match record {
+ PdmTreeEntry::Root => {}
+ PdmTreeEntry::Resource(remote, resource) => {
+ crate::navigate_to(link, remote, Some(resource));
+ }
+ PdmTreeEntry::Remote(remote, _) => {
+ crate::navigate_to(link, remote, None);
+ }
+ }
+}
+
fn columns(
link: &html::Scope<PdmResourceTree>,
store: TreeStore<PdmTreeEntry>,
@@ -316,14 +339,15 @@ fn columns(
.into()
})
.into(),
- DataTableColumn::new(tr!("Node"))
+ DataTableColumn::new(tr!("Node/Error"))
.flex(2)
.render(|item: &PdmTreeEntry| {
match item {
PdmTreeEntry::Root => "",
PdmTreeEntry::Resource(_, resource) => {
- get_resource_node(&resource).unwrap_or("")
+ get_resource_node(resource).unwrap_or("")
}
+ PdmTreeEntry::Remote(_, Some(err)) => err,
PdmTreeEntry::Remote(_, _) => "",
}
.into()
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard: refactor remotes panel
2025-04-11 14:05 [pdm-devel] [PATCH yew-comp/datacenter-manager] some ui improvements Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 1/3] ui: improve keyboard navigation for search box Dominik Csapak
@ 2025-04-11 14:05 ` Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: dashboard: refactor guest panel Dominik Csapak
2025-04-16 9:01 ` [pdm-devel] applied-series: [PATCH yew-comp/datacenter-manager] some ui improvements Wolfgang Bumiller
4 siblings, 0 replies; 9+ messages in thread
From: Dominik Csapak @ 2025-04-11 14:05 UTC (permalink / raw)
To: pdm-devel
put the remotes panel into it's own component to keep the dashboard code
shorter when adding more functionality here.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
ui/src/dashboard/mod.rs | 38 ++++----------
ui/src/dashboard/remote_panel.rs | 90 ++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 29 deletions(-)
create mode 100644 ui/src/dashboard/remote_panel.rs
diff --git a/ui/src/dashboard/mod.rs b/ui/src/dashboard/mod.rs
index ea0cf5e..016fccb 100644
--- a/ui/src/dashboard/mod.rs
+++ b/ui/src/dashboard/mod.rs
@@ -26,6 +26,9 @@ pub use top_entities::TopEntities;
mod subscription_info;
pub use subscription_info::SubscriptionInfo;
+mod remote_panel;
+use remote_panel::RemotePanel;
+
#[derive(Properties, PartialEq)]
pub struct Dashboard {
#[prop_or(60)]
@@ -260,19 +263,7 @@ impl Component for PdmDashboard {
}
}
- fn view(&self, _ctx: &yew::Context<Self>) -> yew::Html {
- let (remote_icon, remote_text) = match (self.status.failed_remotes, self.status.remotes) {
- (0, 0) => (Status::Warning.to_fa_icon(), tr!("No remotes configured.")),
- (0, _) => (
- Status::Success.to_fa_icon(),
- tr!("Could reach all remotes."),
- ),
- (failed, _) => (
- Status::Error.to_fa_icon(),
- tr!("{0} remotes failed to reach.", failed),
- ),
- };
-
+ fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
let content = Column::new()
.class(FlexFit)
.with_child(
@@ -290,22 +281,11 @@ impl Component for PdmDashboard {
.with_tool(
Button::new(tr!("Add"))
.icon_class("fa fa-plus-circle")
- .onclick(_ctx.link().callback(|_| Msg::CreateWizard(true))),
+ .onclick(ctx.link().callback(|_| Msg::CreateWizard(true))),
)
- .with_child(
- Column::new()
- .padding(4)
- .class(FlexFit)
- .class(AlignItems::Center)
- .class(JustifyContent::Center)
- .gap(2)
- .with_child(if self.loading {
- html! {<i class={"pwt-loading-icon"} />}
- } else {
- remote_icon.large_4x().into()
- })
- .with_optional_child((!self.loading).then_some(remote_text)),
- ),
+ .with_child(RemotePanel::new(
+ (!self.loading).then_some(self.status.clone()),
+ )),
)
.with_child(self.create_node_panel(
"building",
@@ -423,7 +403,7 @@ impl Component for PdmDashboard {
.with_optional_child(
self.show_wizard.then_some(
AddWizard::new(pdm_api_types::remotes::RemoteType::Pve)
- .on_close(_ctx.link().callback(|_| Msg::CreateWizard(false)))
+ .on_close(ctx.link().callback(|_| Msg::CreateWizard(false)))
.on_submit(move |ctx| {
crate::remotes::create_remote(
ctx,
diff --git a/ui/src/dashboard/remote_panel.rs b/ui/src/dashboard/remote_panel.rs
new file mode 100644
index 0000000..2c1dd75
--- /dev/null
+++ b/ui/src/dashboard/remote_panel.rs
@@ -0,0 +1,90 @@
+use std::rc::Rc;
+
+use proxmox_yew_comp::Status;
+use pwt::{
+ css,
+ prelude::*,
+ props::{ContainerBuilder, WidgetBuilder},
+ widget::{Column, Container, Fa},
+};
+use yew::{
+ virtual_dom::{VComp, VNode},
+ Component, Properties,
+};
+
+use pdm_api_types::resource::ResourcesStatus;
+
+#[derive(Properties, PartialEq)]
+/// A panel for showing the overall remotes status
+pub struct RemotePanel {
+ /// The status loaded from the API
+ pub status: Option<ResourcesStatus>,
+}
+
+impl RemotePanel {
+ /// Takes the status of the API, or None (which indicates loading)
+ pub fn new(status: Option<ResourcesStatus>) -> Self {
+ yew::props!(Self { status })
+ }
+}
+
+impl From<RemotePanel> for VNode {
+ fn from(val: RemotePanel) -> Self {
+ let comp = VComp::new::<PdmRemotePanel>(Rc::new(val), None);
+ VNode::from(comp)
+ }
+}
+
+struct PdmRemotePanel {}
+
+impl Component for PdmRemotePanel {
+ type Message = &'static str;
+ type Properties = RemotePanel;
+
+ fn create(_ctx: &yew::Context<Self>) -> Self {
+ Self {}
+ }
+
+ fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
+ let props = ctx.props();
+ if props.status.is_none() {
+ return Column::new()
+ .padding(4)
+ .class(css::FlexFit)
+ .class(css::AlignItems::Center)
+ .class(css::JustifyContent::Center)
+ .with_child(Fa::new("").class("pwt-loading-icon"))
+ .into();
+ }
+ let status = props.status.clone().unwrap();
+
+ let (remote_icon, remote_text, failure) = match (status.failed_remotes, status.remotes) {
+ (0, 0) => (
+ Status::Warning.to_fa_icon(),
+ tr!("No remotes configured."),
+ false,
+ ),
+ (0, _) => (
+ Status::Success.to_fa_icon(),
+ tr!("Could reach all remotes."),
+ false,
+ ),
+ (failed, _) => (
+ Status::Error.to_fa_icon(),
+ tr!("{0} remotes failed to reach.", failed),
+ true,
+ ),
+ };
+ Column::new()
+ .tabindex(if failure { 0 } else { -1 })
+ .padding(4)
+ .class(css::FlexFit)
+ .class(css::AlignItems::Center)
+ .class(css::JustifyContent::Center)
+ .style("cursor", failure.then_some("pointer"))
+ .gap(2)
+ .with_child(remote_icon.large_4x())
+ .with_child(Container::new().with_child(remote_text))
+ .into()
+ }
+}
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 3/3] ui: dashboard: refactor guest panel
2025-04-11 14:05 [pdm-devel] [PATCH yew-comp/datacenter-manager] some ui improvements Dominik Csapak
` (2 preceding siblings ...)
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard: refactor remotes panel Dominik Csapak
@ 2025-04-11 14:05 ` Dominik Csapak
2025-04-16 9:01 ` [pdm-devel] applied-series: [PATCH yew-comp/datacenter-manager] some ui improvements Wolfgang Bumiller
4 siblings, 0 replies; 9+ messages in thread
From: Dominik Csapak @ 2025-04-11 14:05 UTC (permalink / raw)
To: pdm-devel
so we can keep the dashboard code smaller when adding new features here.
Also implement showing unknown guests and templates
To have a more structured output, re-implement it with a DataTable
instead of a custom flex layout. This has the advantage of being
a proper grid.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
ui/src/dashboard/guest_panel.rs | 143 ++++++++++++++++++++++++++++++++
ui/src/dashboard/mod.rs | 65 ++++-----------
ui/src/pve/mod.rs | 11 ++-
3 files changed, 169 insertions(+), 50 deletions(-)
create mode 100644 ui/src/dashboard/guest_panel.rs
diff --git a/ui/src/dashboard/guest_panel.rs b/ui/src/dashboard/guest_panel.rs
new file mode 100644
index 0000000..d885056
--- /dev/null
+++ b/ui/src/dashboard/guest_panel.rs
@@ -0,0 +1,143 @@
+use std::rc::Rc;
+
+use pdm_api_types::resource::GuestStatusCount;
+use proxmox_yew_comp::GuestState;
+use pwt::{
+ prelude::*,
+ props::ExtractPrimaryKey,
+ state::Store,
+ widget::{
+ data_table::{DataTable, DataTableColumn, DataTableHeader},
+ Fa,
+ },
+};
+use yew::virtual_dom::{VComp, VNode};
+
+use crate::pve::GuestType;
+
+use super::loading_column;
+
+#[derive(PartialEq, Clone, Properties)]
+pub struct GuestPanel {
+ guest_type: GuestType,
+ status: Option<GuestStatusCount>,
+}
+
+impl GuestPanel {
+ pub fn new(guest_type: GuestType, status: Option<GuestStatusCount>) -> Self {
+ yew::props!(Self { guest_type, status })
+ }
+}
+
+impl From<GuestPanel> for VNode {
+ fn from(value: GuestPanel) -> Self {
+ let comp = VComp::new::<PdmGuestPanel>(Rc::new(value), None);
+ VNode::from(comp)
+ }
+}
+
+#[derive(PartialEq, Clone)]
+pub enum StatusRow {
+ State(GuestState, u64),
+ All(u64),
+}
+
+impl ExtractPrimaryKey for StatusRow {
+ fn extract_key(&self) -> yew::virtual_dom::Key {
+ yew::virtual_dom::Key::from(match self {
+ StatusRow::State(state, _) => match state {
+ GuestState::Running => "running",
+ GuestState::Paused => "paused",
+ GuestState::Stopped => "stopped",
+ GuestState::Template => "template",
+ GuestState::Unknown => "unknown",
+ },
+ StatusRow::All(_) => "all",
+ })
+ }
+}
+
+fn columns(guest_type: GuestType) -> Rc<Vec<DataTableHeader<StatusRow>>> {
+ Rc::new(vec![
+ DataTableColumn::new("icon")
+ .width("3em")
+ .render(move |item: &StatusRow| {
+ match item {
+ StatusRow::State(state, _) => state.to_fa_icon(),
+ StatusRow::All(_) => match guest_type {
+ GuestType::Qemu => Fa::new("desktop"),
+ GuestType::Lxc => Fa::new("cubes"),
+ },
+ }
+ .fixed_width()
+ .into()
+ })
+ .into(),
+ DataTableColumn::new("text")
+ .flex(5)
+ .render(|item: &StatusRow| {
+ match item {
+ StatusRow::State(GuestState::Running, _) => tr!("running"),
+ StatusRow::State(GuestState::Stopped, _) => tr!("stopped"),
+ StatusRow::State(GuestState::Paused, _) => tr!("paused"),
+ StatusRow::State(GuestState::Template, _) => tr!("Template"),
+ StatusRow::State(GuestState::Unknown, _) => tr!("Unknown"),
+ StatusRow::All(_) => tr!("All"),
+ }
+ .into()
+ })
+ .into(),
+ DataTableColumn::new("count")
+ .flex(1)
+ .justify("right")
+ .render(|item: &StatusRow| match item {
+ StatusRow::State(_, count) => count.into(),
+ StatusRow::All(count) => count.into(),
+ })
+ .into(),
+ ])
+}
+
+pub struct PdmGuestPanel {}
+
+impl yew::Component for PdmGuestPanel {
+ type Message = String;
+ type Properties = GuestPanel;
+
+ fn create(_ctx: &yew::Context<Self>) -> Self {
+ Self {}
+ }
+
+ fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
+ let props = ctx.props();
+ if props.status.is_none() {
+ return loading_column().into();
+ }
+ let guest_type = props.guest_type;
+ let status = ctx.props().status.clone().unwrap();
+
+ let store = Store::new();
+ store.set_data(vec![
+ StatusRow::State(GuestState::Running, status.running),
+ StatusRow::State(GuestState::Stopped, status.stopped),
+ StatusRow::State(GuestState::Template, status.template),
+ StatusRow::State(GuestState::Unknown, status.unknown),
+ StatusRow::All(status.running + status.stopped + status.template + status.unknown),
+ ]);
+
+ store.set_filter(|rec: &StatusRow| match rec {
+ StatusRow::State(_, count) if *count > 0 => true,
+ StatusRow::State(GuestState::Running | GuestState::Stopped, _) => true,
+ StatusRow::All(_) => true,
+ _ => false,
+ });
+
+ DataTable::new(columns(guest_type), store.clone())
+ .padding(4)
+ .striped(false)
+ .borderless(true)
+ .bordered(false)
+ .show_header(false)
+ .into()
+ }
+}
diff --git a/ui/src/dashboard/mod.rs b/ui/src/dashboard/mod.rs
index 016fccb..7b7ec81 100644
--- a/ui/src/dashboard/mod.rs
+++ b/ui/src/dashboard/mod.rs
@@ -7,7 +7,7 @@ use yew::{
Component,
};
-use proxmox_yew_comp::{http_get, GuestState, Status};
+use proxmox_yew_comp::{http_get, Status};
use pwt::{
css::{AlignItems, FlexFit, FlexWrap, JustifyContent},
prelude::*,
@@ -18,7 +18,7 @@ use pwt::{
use pdm_api_types::resource::{GuestStatusCount, NodeStatusCount, ResourcesStatus};
use pdm_client::types::TopEntity;
-use crate::{remotes::AddWizard, RemoteList};
+use crate::{pve::GuestType, remotes::AddWizard, RemoteList};
mod top_entities;
pub use top_entities::TopEntities;
@@ -29,6 +29,9 @@ pub use subscription_info::SubscriptionInfo;
mod remote_panel;
use remote_panel::RemotePanel;
+mod guest_panel;
+use guest_panel::GuestPanel;
+
#[derive(Properties, PartialEq)]
pub struct Dashboard {
#[prop_or(60)]
@@ -120,48 +123,20 @@ impl PdmDashboard {
)
}
- fn create_guest_panel(&self, icon: &str, title: String, status: &GuestStatusCount) -> Panel {
+ fn create_guest_panel(&self, guest_type: GuestType, status: &GuestStatusCount) -> Panel {
+ let (icon, title) = match guest_type {
+ GuestType::Qemu => ("desktop", tr!("Virtual Machines")),
+ GuestType::Lxc => ("cubses", tr!("Linux Container")),
+ };
Panel::new()
.flex(1.0)
.width(300)
.title(self.create_title_with_icon(icon, title))
.border(true)
- .with_child(if self.loading {
- loading_column()
- } else {
- Column::new()
- .padding(4)
- .gap(2)
- .class(FlexFit)
- .class(JustifyContent::Center)
- .with_child(
- Row::new()
- .gap(2)
- .with_child(GuestState::Running.to_fa_icon().fixed_width())
- .with_child(tr!("running"))
- .with_flex_spacer()
- .with_child(Container::from_tag("span").with_child(status.running)),
- )
- .with_child(
- Row::new()
- .gap(2)
- .with_child(GuestState::Stopped.to_fa_icon().fixed_width())
- .with_child(tr!("stopped"))
- .with_flex_spacer()
- .with_child(Container::from_tag("span").with_child(status.stopped)),
- )
- // FIXME: show templates?
- .with_optional_child(
- (self.status.qemu.unknown > 0).then_some(
- Row::new()
- .gap(2)
- .with_child(GuestState::Unknown.to_fa_icon().fixed_width())
- .with_child(tr!("unknown"))
- .with_flex_spacer()
- .with_child(Container::from_tag("span").with_child(status.unknown)),
- ),
- )
- })
+ .with_child(GuestPanel::new(
+ guest_type,
+ (!self.loading).then_some(status.clone()),
+ ))
}
fn create_top_entities_panel(
@@ -292,16 +267,8 @@ impl Component for PdmDashboard {
tr!("Virtual Environment Nodes"),
&self.status.pve_nodes,
))
- .with_child(self.create_guest_panel(
- "desktop",
- tr!("Virtual Machines"),
- &self.status.qemu,
- ))
- .with_child(self.create_guest_panel(
- "cubes",
- tr!("Linux Container"),
- &self.status.lxc,
- ))
+ .with_child(self.create_guest_panel(GuestType::Qemu, &self.status.qemu))
+ .with_child(self.create_guest_panel(GuestType::Lxc, &self.status.lxc))
// FIXME: add PBS support
//.with_child(self.create_node_panel(
// "building-o",
diff --git a/ui/src/pve/mod.rs b/ui/src/pve/mod.rs
index ed0ee04..c5a83cf 100644
--- a/ui/src/pve/mod.rs
+++ b/ui/src/pve/mod.rs
@@ -1,4 +1,4 @@
-use std::rc::Rc;
+use std::{fmt::Display, rc::Rc};
use gloo_utils::window;
use proxmox_client::Error;
@@ -72,6 +72,15 @@ pub enum GuestType {
Lxc,
}
+impl Display for GuestType {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ GuestType::Qemu => f.write_str("qemu"),
+ GuestType::Lxc => f.write_str("lxc"),
+ }
+ }
+}
+
#[derive(PartialEq, Clone, Copy)]
pub struct GuestInfo {
pub guest_type: GuestType,
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status
2025-04-11 14:05 ` [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status Dominik Csapak
@ 2025-04-14 14:50 ` Wolfgang Bumiller
2025-04-15 11:52 ` Dominik Csapak
0 siblings, 1 reply; 9+ messages in thread
From: Wolfgang Bumiller @ 2025-04-14 14:50 UTC (permalink / raw)
To: Dominik Csapak; +Cc: pdm-devel
On Fri, Apr 11, 2025 at 04:05:17PM +0200, Dominik Csapak wrote:
> this is sensible to have, e.g. when we want to have the status structs
> as parto of a type for a store
I'd argue these should all be:
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
>
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> src/status.rs | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/src/status.rs b/src/status.rs
> index 9d951c5..ab77a15 100644
> --- a/src/status.rs
> +++ b/src/status.rs
> @@ -7,6 +7,7 @@ use pwt::{
>
> /// Used to represent a Status of some resource or component, e.g.
> /// if a PVE node is online or not.
> +#[derive(PartialEq, Clone)]
> pub enum Status {
> Success,
> Warning,
> @@ -27,6 +28,7 @@ impl Status {
> }
>
> /// Used to represent the state of a Node, being PVE or PBS
> +#[derive(PartialEq, Clone)]
> pub enum NodeState {
> Online,
> Offline,
> @@ -45,6 +47,7 @@ impl NodeState {
> }
>
> /// Used to represent the state of a PVE guest, such as a VM
> +#[derive(PartialEq, Clone)]
> pub enum GuestState {
> Running,
> Paused,
> @@ -67,6 +70,7 @@ impl GuestState {
> }
>
> /// Used to represent the state of a Storage or Datastore
> +#[derive(PartialEq, Clone)]
> pub enum StorageState {
> Available,
> Unavailable,
> --
> 2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status
2025-04-14 14:50 ` Wolfgang Bumiller
@ 2025-04-15 11:52 ` Dominik Csapak
2025-04-15 12:57 ` Wolfgang Bumiller
0 siblings, 1 reply; 9+ messages in thread
From: Dominik Csapak @ 2025-04-15 11:52 UTC (permalink / raw)
To: Wolfgang Bumiller; +Cc: pdm-devel
On 4/14/25 16:50, Wolfgang Bumiller wrote:
> On Fri, Apr 11, 2025 at 04:05:17PM +0200, Dominik Csapak wrote:
>> this is sensible to have, e.g. when we want to have the status structs
>> as parto of a type for a store
>
> I'd argue these should all be:
>
> #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
>
sure, makes sense.
is a follow up enough or should I resend the patch ( or whole series?)
>>
>> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
>> ---
>> src/status.rs | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/src/status.rs b/src/status.rs
>> index 9d951c5..ab77a15 100644
>> --- a/src/status.rs
>> +++ b/src/status.rs
>> @@ -7,6 +7,7 @@ use pwt::{
>>
>> /// Used to represent a Status of some resource or component, e.g.
>> /// if a PVE node is online or not.
>> +#[derive(PartialEq, Clone)]
>> pub enum Status {
>> Success,
>> Warning,
>> @@ -27,6 +28,7 @@ impl Status {
>> }
>>
>> /// Used to represent the state of a Node, being PVE or PBS
>> +#[derive(PartialEq, Clone)]
>> pub enum NodeState {
>> Online,
>> Offline,
>> @@ -45,6 +47,7 @@ impl NodeState {
>> }
>>
>> /// Used to represent the state of a PVE guest, such as a VM
>> +#[derive(PartialEq, Clone)]
>> pub enum GuestState {
>> Running,
>> Paused,
>> @@ -67,6 +70,7 @@ impl GuestState {
>> }
>>
>> /// Used to represent the state of a Storage or Datastore
>> +#[derive(PartialEq, Clone)]
>> pub enum StorageState {
>> Available,
>> Unavailable,
>> --
>> 2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status
2025-04-15 11:52 ` Dominik Csapak
@ 2025-04-15 12:57 ` Wolfgang Bumiller
0 siblings, 0 replies; 9+ messages in thread
From: Wolfgang Bumiller @ 2025-04-15 12:57 UTC (permalink / raw)
To: Dominik Csapak; +Cc: pdm-devel
On Tue, Apr 15, 2025 at 01:52:22PM +0200, Dominik Csapak wrote:
> On 4/14/25 16:50, Wolfgang Bumiller wrote:
> > On Fri, Apr 11, 2025 at 04:05:17PM +0200, Dominik Csapak wrote:
> > > this is sensible to have, e.g. when we want to have the status structs
> > > as parto of a type for a store
> >
> > I'd argue these should all be:
> >
> > #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
> >
>
> sure, makes sense.
>
> is a follow up enough or should I resend the patch ( or whole series?)
Either way is fine. I'd hold off on the pdm patches until after the bump
of yew-comp, to avoid it being in a non-buildable state too long.
We could derive more standard traits in a few more places probably, eg:
src/status.rs: Status, NodeState, GuestState, StorageState
src/common_api_types.rs: TaskStatusClass (misses Debug+Eq+Hash)
src/proxmox_product.rs: ExistingProduct (only misses Eq+Hash)
src/journal_view.rs: Position (only misses Eq+Hash)
>
> > >
> > > Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> > > ---
> > > src/status.rs | 4 ++++
> > > 1 file changed, 4 insertions(+)
> > >
> > > diff --git a/src/status.rs b/src/status.rs
> > > index 9d951c5..ab77a15 100644
> > > --- a/src/status.rs
> > > +++ b/src/status.rs
> > > @@ -7,6 +7,7 @@ use pwt::{
> > > /// Used to represent a Status of some resource or component, e.g.
> > > /// if a PVE node is online or not.
> > > +#[derive(PartialEq, Clone)]
> > > pub enum Status {
> > > Success,
> > > Warning,
> > > @@ -27,6 +28,7 @@ impl Status {
> > > }
> > > /// Used to represent the state of a Node, being PVE or PBS
> > > +#[derive(PartialEq, Clone)]
> > > pub enum NodeState {
> > > Online,
> > > Offline,
> > > @@ -45,6 +47,7 @@ impl NodeState {
> > > }
> > > /// Used to represent the state of a PVE guest, such as a VM
> > > +#[derive(PartialEq, Clone)]
> > > pub enum GuestState {
> > > Running,
> > > Paused,
> > > @@ -67,6 +70,7 @@ impl GuestState {
> > > }
> > > /// Used to represent the state of a Storage or Datastore
> > > +#[derive(PartialEq, Clone)]
> > > pub enum StorageState {
> > > Available,
> > > Unavailable,
> > > --
> > > 2.39.5
>
>
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* [pdm-devel] applied-series: [PATCH yew-comp/datacenter-manager] some ui improvements
2025-04-11 14:05 [pdm-devel] [PATCH yew-comp/datacenter-manager] some ui improvements Dominik Csapak
` (3 preceding siblings ...)
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: dashboard: refactor guest panel Dominik Csapak
@ 2025-04-16 9:01 ` Wolfgang Bumiller
4 siblings, 0 replies; 9+ messages in thread
From: Wolfgang Bumiller @ 2025-04-16 9:01 UTC (permalink / raw)
To: Dominik Csapak; +Cc: pdm-devel
applied series, thanks
On Fri, Apr 11, 2025 at 04:05:16PM +0200, Dominik Csapak wrote:
> Some smaller improvements for the ui, mostly refactor and preparation
> for an upcoming series that improves the search box.
>
> pdm patch 3/3 depends on the proxmox-yew-comp patch.
>
> proxmox-yew-comp:
>
> Dominik Csapak (1):
> status: implement PartialEq and Clone for Status
>
> src/status.rs | 4 ++++
> 1 file changed, 4 insertions(+)
>
> proxmox-datacenter-manager:
>
> Dominik Csapak (3):
> ui: improve keyboard navigation for search box
> ui: dashboard: refactor remotes panel
> ui: dashboard: refactor guest panel
>
> ui/src/dashboard/guest_panel.rs | 143 +++++++++++++++++++++++++++++++
> ui/src/dashboard/mod.rs | 103 ++++++----------------
> ui/src/dashboard/remote_panel.rs | 90 +++++++++++++++++++
> ui/src/pve/mod.rs | 11 ++-
> ui/src/widget/resource_tree.rs | 76 ++++++++++------
> 5 files changed, 318 insertions(+), 105 deletions(-)
> create mode 100644 ui/src/dashboard/guest_panel.rs
> create mode 100644 ui/src/dashboard/remote_panel.rs
>
> --
> 2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-04-16 9:02 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-11 14:05 [pdm-devel] [PATCH yew-comp/datacenter-manager] some ui improvements Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH yew-comp 1/1] status: implement PartialEq and Clone for Status Dominik Csapak
2025-04-14 14:50 ` Wolfgang Bumiller
2025-04-15 11:52 ` Dominik Csapak
2025-04-15 12:57 ` Wolfgang Bumiller
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 1/3] ui: improve keyboard navigation for search box Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard: refactor remotes panel Dominik Csapak
2025-04-11 14:05 ` [pdm-devel] [PATCH datacenter-manager 3/3] ui: dashboard: refactor guest panel Dominik Csapak
2025-04-16 9:01 ` [pdm-devel] applied-series: [PATCH yew-comp/datacenter-manager] some ui improvements Wolfgang Bumiller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal