public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pdm-devel] [RFC pdm v2] ui: make layout more consistent using new ContentSpacer widget
@ 2025-01-10 12:50 Dietmar Maurer
  2025-01-15 15:48 ` Thomas Lamprecht
  0 siblings, 1 reply; 3+ messages in thread
From: Dietmar Maurer @ 2025-01-10 12:50 UTC (permalink / raw)
  To: pdm-devel

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---

 Changhes in v2:
 - use box shadows instead of border
 - use ContentSpacer for dashboard
 - use ContentSpacer for PveRemote

 ui/css/crisp-yew-style.scss            | 12 ++++
 ui/css/desktop-yew-style.scss          | 11 +++
 ui/css/pdm.scss                        | 26 ++++++-
 ui/src/administration/mod.rs           | 28 ++++++--
 ui/src/certificates.rs                 | 30 ++++++--
 ui/src/configuration/mod.rs            | 25 ++++---
 ui/src/configuration/other/mod.rs      |  9 ++-
 ui/src/configuration/other/webauthn.rs |  1 -
 ui/src/dashboard/mod.rs                | 17 +++--
 ui/src/main_menu.rs                    | 22 +++---
 ui/src/pve/mod.rs                      |  7 +-
 ui/src/widget/content_spacer.rs        | 99 ++++++++++++++++++++++++++
 ui/src/widget/mod.rs                   |  3 +
 13 files changed, 242 insertions(+), 48 deletions(-)
 create mode 100644 ui/src/widget/content_spacer.rs

diff --git a/ui/css/crisp-yew-style.scss b/ui/css/crisp-yew-style.scss
index d254b53..df8bb9c 100644
--- a/ui/css/crisp-yew-style.scss
+++ b/ui/css/crisp-yew-style.scss
@@ -1,2 +1,14 @@
 @import "../pwt-assets/scss/crisp-yew-style";
 @import "pdm";
+
+.proxmox-content-spacer {
+    @include color-scheme-vars("neutral");
+
+    &.proxmox-content-spacer-with-one-child {
+        padding: 0;
+    }
+
+    &.proxmox-content-spacer-with-one-child > * {
+        border: 0;
+    }
+}
diff --git a/ui/css/desktop-yew-style.scss b/ui/css/desktop-yew-style.scss
index 3d1ac0a..2fb1832 100644
--- a/ui/css/desktop-yew-style.scss
+++ b/ui/css/desktop-yew-style.scss
@@ -1,2 +1,13 @@
 @import "../pwt-assets/scss/desktop-yew-style";
 @import "pdm";
+
+.proxmox-content-spacer {
+    padding: var(--pwt-spacer-4);
+    gap: var(--pwt-spacer-4);
+
+    & > * {
+        border: 0px !important;
+        border-top: 1px solid var(--pwt-color-surface) !important;
+        @include elevation-box-shadow(1);
+    }
+}
diff --git a/ui/css/pdm.scss b/ui/css/pdm.scss
index 4ef22e2..6597f31 100644
--- a/ui/css/pdm.scss
+++ b/ui/css/pdm.scss
@@ -60,7 +60,27 @@
 }
 
 :root.pwt-dark-mode {
-  .fa-memory, .fa-cpu {
-    filter: invert(90%);
-  }
+    .fa-memory,
+    .fa-cpu {
+        filter: invert(90%);
+    }
+}
+
+.proxmox-content-spacer {
+    @include color-scheme-vars("surface");
+    color: var(--pwt-color);
+    background-color: var(--pwt-color-background);
+
+    padding: var(--pwt-spacer-2);
+    gap: var(--pwt-spacer-2);
+
+    display: flex;
+    flex-direction: column;
+
+    & > * {
+        @include color-scheme-vars("neutral");
+        border: 1px solid var(--pwt-color-border);
+        color: var(--pwt-color);
+        background-color: var(--pwt-color-background);
+    }
 }
diff --git a/ui/src/administration/mod.rs b/ui/src/administration/mod.rs
index 15d04ae..eeb9efa 100644
--- a/ui/src/administration/mod.rs
+++ b/ui/src/administration/mod.rs
@@ -18,6 +18,8 @@ use pwt_macros::builder;
 
 use proxmox_yew_comp::{AptPackageManager, AptRepositories, ExistingProduct, Syslog, Tasks};
 
+use crate::widget::ContentSpacer;
+
 #[derive(Clone, PartialEq, Properties)]
 #[builder]
 pub struct ServerAdministration {
@@ -73,8 +75,9 @@ impl Component for PdmServerAdministration {
                     .label("Updates")
                     .icon_class("fa fa-refresh"),
                 move |_| {
-                    AptPackageManager::new()
-                        .enable_upgrade(enable_upgrade)
+                    ContentSpacer::new()
+                        .class("pwt-flex-fill")
+                        .with_child(AptPackageManager::new().enable_upgrade(enable_upgrade))
                         .into()
                 },
             )
@@ -83,21 +86,36 @@ impl Component for PdmServerAdministration {
                     .key("repositories")
                     .label("Repositories")
                     .icon_class("fa fa-files-o"),
-                |_| AptRepositories::new().product(ExistingProduct::PDM).into(),
+                |_| {
+                    ContentSpacer::new()
+                        .class("pwt-flex-fit")
+                        .with_child(AptRepositories::new().product(ExistingProduct::PDM))
+                        .into()
+                },
             )
             .with_item_builder(
                 TabBarItem::new()
                     .key("syslog")
                     .label("Syslog")
                     .icon_class("fa fa-list"),
-                |_| Syslog::new().into(), // fixme: use JournalView instead?
+                |_| {
+                    ContentSpacer::new()
+                        .class("pwt-flex-fit")
+                        .with_child(Syslog::new())
+                        .into() // fixme: use JournalView instead?
+                },
             )
             .with_item_builder(
                 TabBarItem::new()
                     .key("tasks")
                     .label("Tasks")
                     .icon_class("fa fa-list-alt"),
-                |_| Tasks::new().into(),
+                |_| {
+                    ContentSpacer::new()
+                        .class("pwt-flex-fit")
+                        .with_child(Tasks::new())
+                        .into()
+                },
             );
 
         NavigationContainer::new().with_child(panel).into()
diff --git a/ui/src/certificates.rs b/ui/src/certificates.rs
index 39929b4..d348785 100644
--- a/ui/src/certificates.rs
+++ b/ui/src/certificates.rs
@@ -7,6 +7,8 @@ use proxmox_yew_comp::acme::{
     AcmeAccountsPanel, AcmeDomainsPanel, AcmePluginsPanel, CertificateList,
 };
 
+use crate::widget::ContentSpacer;
+
 #[function_component(CertificatesPanel)]
 pub fn certificates_panel() -> Html {
     let panel = TabPanel::new()
@@ -19,23 +21,43 @@ pub fn certificates_panel() -> Html {
             TabBarItem::new()
                 .key("certificate_List")
                 .label("Certificates"),
-            |_| CertificateList::new().into(),
+            |_| {
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(CertificateList::new())
+                    .into()
+            },
         )
         .with_item_builder(
             TabBarItem::new().key("acme_domains").label("ACME Domains"),
-            |_| AcmeDomainsPanel::new().url("/config/certificate").into(),
+            |_| {
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(AcmeDomainsPanel::new().url("/config/certificate"))
+                    .into()
+            },
         )
         .with_item_builder(
             TabBarItem::new()
                 .key("acme_accounts")
                 .label("ACME Accounts"),
-            |_| AcmeAccountsPanel::new().into(),
+            |_| {
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(AcmeAccountsPanel::new())
+                    .into()
+            },
         )
         .with_item_builder(
             TabBarItem::new()
                 .key("acme_plugins")
                 .label("Challenge Plugins"),
-            |_| AcmePluginsPanel::new().into(),
+            |_| {
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(AcmePluginsPanel::new())
+                    .into()
+            },
         );
 
     NavigationContainer::new().with_child(panel).into()
diff --git a/ui/src/configuration/mod.rs b/ui/src/configuration/mod.rs
index 15421a4..63e741e 100644
--- a/ui/src/configuration/mod.rs
+++ b/ui/src/configuration/mod.rs
@@ -1,7 +1,7 @@
 use pwt::prelude::*;
 use pwt::props::StorageLocation;
 use pwt::state::NavigationContainer;
-use pwt::widget::{Column, MiniScrollMode, Panel, TabBarItem, TabPanel};
+use pwt::widget::{Column, Container, MiniScrollMode, Panel, TabBarItem, TabPanel};
 
 use proxmox_yew_comp::configuration::TimePanel;
 use proxmox_yew_comp::configuration::{DnsPanel, NetworkView};
@@ -11,6 +11,8 @@ use proxmox_yew_comp::UserPanel;
 mod other;
 pub use other::OtherPanel;
 
+use crate::widget::ContentSpacer;
+
 #[function_component(SystemConfiguration)]
 pub fn system_configuration() -> Html {
     let panel = TabPanel::new()
@@ -50,14 +52,24 @@ pub fn access_control() -> Html {
                 .key("user-management")
                 .icon_class("fa fa-user")
                 .label(tr!("User Management")),
-            |_| UserPanel::new().into(),
+            |_| {
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(UserPanel::new())
+                    .into()
+            },
         )
         .with_item_builder(
             TabBarItem::new()
                 .key("two-factor")
                 .icon_class("fa fa-key")
                 .label(tr!("Two Factor Authentication")),
-            |_| TfaView::new().into(),
+            |_| {
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(TfaView::new())
+                    .into()
+            },
         );
 
     NavigationContainer::new().with_child(panel).into()
@@ -65,19 +77,15 @@ pub fn access_control() -> Html {
 
 #[function_component(NetworkTimePanel)]
 pub fn create_network_time_panel() -> Html {
-    Column::new()
+    ContentSpacer::new()
         .class("pwt-flex-fit")
-        .padding(2)
-        .gap(4)
         .with_child(
             Panel::new()
-                .border(true)
                 .title(tr!("Time"))
                 .with_child(html! { <TimePanel/> }),
         )
         .with_child(
             Panel::new()
-                .border(true)
                 .title(tr!("DNS"))
                 .with_child(html! { <DnsPanel/> }),
         )
@@ -85,7 +93,6 @@ pub fn create_network_time_panel() -> Html {
             Panel::new()
                 .min_height(200)
                 .class("pwt-flex-fit")
-                .border(true)
                 .title(tr!("Network Interfaces"))
                 .with_child(NetworkView::new()),
         )
diff --git a/ui/src/configuration/other/mod.rs b/ui/src/configuration/other/mod.rs
index f2435ac..cdd8e98 100644
--- a/ui/src/configuration/other/mod.rs
+++ b/ui/src/configuration/other/mod.rs
@@ -1,14 +1,13 @@
 use pwt::prelude::*;
-use pwt::widget::Column;
+
+use crate::widget::ContentSpacer;
 
 mod webauthn;
 
 #[function_component(OtherPanel)]
 pub fn create_other_panel() -> Html {
-    Column::new()
-        .class("pwt-flex-fill")
-        .padding(2)
-        .gap(4)
+    ContentSpacer::new()
+        .class("pwt-flex-fit")
         .with_child(html! { <webauthn::WebauthnPanel/> })
         .into()
 }
diff --git a/ui/src/configuration/other/webauthn.rs b/ui/src/configuration/other/webauthn.rs
index 08bc09a..9748e3c 100644
--- a/ui/src/configuration/other/webauthn.rs
+++ b/ui/src/configuration/other/webauthn.rs
@@ -19,7 +19,6 @@ use proxmox_yew_comp::{ObjectGrid, ObjectGridRow};
 #[function_component(WebauthnPanel)]
 pub fn webauthn_panel() -> Html {
     Panel::new()
-        .border(true)
         .title(tr!("WebAuthn TFA"))
         .with_child(object_grid())
         .into()
diff --git a/ui/src/dashboard/mod.rs b/ui/src/dashboard/mod.rs
index fe7ac1b..49239b2 100644
--- a/ui/src/dashboard/mod.rs
+++ b/ui/src/dashboard/mod.rs
@@ -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::{remotes::AddWizard, widget::ContentSpacer, RemoteList};
 
 mod top_entities;
 pub use top_entities::TopEntities;
@@ -275,17 +275,15 @@ impl Component for PdmDashboard {
 
         let content = Column::new()
             .class(FlexFit)
-            .padding(4)
-            .gap(4)
             .with_child(
-                Row::new()
-                    .gap(4)
+                ContentSpacer::new()
+                    .class("pwt-flex-direction-row")
                     .class(FlexWrap::Wrap)
                     .with_child(
                         Panel::new()
                             .title(self.create_title_with_icon("server", tr!("Remotes")))
                             .flex(1.0)
-                            .border(true)
+                            //.border(true)
                             .width(300)
                             .min_height(175)
                             .with_tool(
@@ -389,10 +387,11 @@ impl Component for PdmDashboard {
                     .with_child(SubscriptionInfo::new()),
             )
             .with_child(
-                Row::new()
-                    .gap(4)
+                ContentSpacer::new()
+                    .class("pwt-flex-direction-row")
+                    .style("padding-top", "0")
                     .class(FlexWrap::Wrap)
-                    .min_height(175)
+                    //.min_height(175)
                     .with_child(self.create_top_entities_panel(
                         "desktop",
                         tr!("Guests With the Highest CPU Usage"),
diff --git a/ui/src/main_menu.rs b/ui/src/main_menu.rs
index e75eb90..3d2b5a0 100644
--- a/ui/src/main_menu.rs
+++ b/ui/src/main_menu.rs
@@ -16,6 +16,7 @@ use proxmox_yew_comp::{NotesView, XTermJs};
 
 use pdm_api_types::remotes::RemoteType;
 
+use crate::widget::ContentSpacer;
 use crate::{
     AccessControl, CertificatesPanel, Dashboard, RemoteConfigPanel, RemoteList,
     ServerAdministration, SystemConfiguration,
@@ -177,14 +178,14 @@ impl Component for PdmMainMenu {
             "notes",
             Some("fa fa-sticky-note-o"),
             move |_| {
-                NotesView::new("/config/notes")
-                    .on_submit(|notes| async move {
-                        proxmox_yew_comp::http_put(
-                            "/config/notes",
-                            Some(serde_json::to_value(&notes)?),
-                        )
+                let notes = NotesView::new("/config/notes").on_submit(|notes| async move {
+                    proxmox_yew_comp::http_put("/config/notes", Some(serde_json::to_value(&notes)?))
                         .await
-                    })
+                });
+
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(notes)
                     .into()
             },
         );
@@ -274,7 +275,12 @@ impl Component for PdmMainMenu {
             } else {
                 "fa fa-server"
             }),
-            |_| RemoteConfigPanel::new().into(),
+            |_| {
+                ContentSpacer::new()
+                    .class("pwt-flex-fit")
+                    .with_child(RemoteConfigPanel::new())
+                    .into()
+            },
             remote_submenu,
         );
 
diff --git a/ui/src/pve/mod.rs b/ui/src/pve/mod.rs
index 7925bbf..bde89b5 100644
--- a/ui/src/pve/mod.rs
+++ b/ui/src/pve/mod.rs
@@ -31,7 +31,7 @@ pub mod utils;
 mod tree;
 use tree::PveTreeNode;
 
-use crate::get_deep_url;
+use crate::{get_deep_url, widget::ContentSpacer};
 
 #[derive(Debug, Eq, PartialEq, Properties)]
 pub struct PveRemote {
@@ -163,10 +163,9 @@ impl LoadableComponent for PveRemoteComp {
             .with_child(tr! {"Remote '{0}'", ctx.props().remote})
             .into();
 
-        let content = Row::new()
+        let content = ContentSpacer::new()
             .class(FlexFit)
-            .padding(4)
-            .gap(4)
+            .class("pwt-flex-direction-row")
             .with_child(
                 Panel::new()
                     .min_width(500)
diff --git a/ui/src/widget/content_spacer.rs b/ui/src/widget/content_spacer.rs
new file mode 100644
index 0000000..575e332
--- /dev/null
+++ b/ui/src/widget/content_spacer.rs
@@ -0,0 +1,99 @@
+use std::rc::Rc;
+
+use pwt::props::{AsClassesMut, AsCssStylesMut, CssStyles};
+use pwt::widget::Container;
+use yew::prelude::*;
+use yew::virtual_dom::{Key, VComp, VNode};
+
+use pwt::prelude::*;
+
+#[derive(Clone, PartialEq, Properties)]
+pub struct ContentSpacer {
+    /// The yew component key.
+    #[prop_or_default]
+    pub key: Option<Key>,
+
+    #[prop_or_default]
+    pub children: Vec<VNode>,
+
+    /// CSS class of the container.
+    #[prop_or_default]
+    pub class: Classes,
+
+    /// CSS style for the dialog window
+    #[prop_or_default]
+    pub styles: CssStyles,
+}
+
+impl ContentSpacer {
+    pub fn new() -> Self {
+        yew::props!(Self {})
+    }
+
+    /// Builder style method to set the yew `key` property.
+    pub fn key(mut self, key: impl IntoOptionalKey) -> Self {
+        self.key = key.into_optional_key();
+        self
+    }
+
+    /// Builder style method to add a html class.
+    pub fn class(mut self, class: impl Into<Classes>) -> Self {
+        self.add_class(class);
+        self
+    }
+
+    /// Method to add a html class.
+    pub fn add_class(&mut self, class: impl Into<Classes>) {
+        self.class.push(class);
+    }
+}
+
+impl ContainerBuilder for ContentSpacer {
+    fn as_children_mut(&mut self) -> &mut Vec<VNode> {
+        &mut self.children
+    }
+}
+
+impl AsClassesMut for ContentSpacer {
+    fn as_classes_mut(&mut self) -> &mut yew::Classes {
+        &mut self.class
+    }
+}
+
+impl AsCssStylesMut for ContentSpacer {
+    fn as_css_styles_mut(&mut self) -> &mut CssStyles {
+        &mut self.styles
+    }
+}
+
+impl WidgetStyleBuilder for ContentSpacer {}
+
+pub struct ProxmoxContentSpacer {}
+
+impl Component for ProxmoxContentSpacer {
+    type Message = ();
+    type Properties = ContentSpacer;
+
+    fn create(_ctx: &Context<Self>) -> Self {
+        Self {}
+    }
+
+    fn view(&self, ctx: &Context<Self>) -> Html {
+        let props = ctx.props();
+        Container::new()
+            .class("proxmox-content-spacer")
+            .class((props.children.len() < 2).then(|| "proxmox-content-spacer-with-one-child"))
+            .class(props.class.clone())
+            .styles(props.styles.clone())
+            .children(props.children.clone())
+            .into()
+    }
+}
+
+impl From<ContentSpacer> for VNode {
+    fn from(val: ContentSpacer) -> Self {
+        let key = val.key.clone();
+        let comp = VComp::new::<ProxmoxContentSpacer>(Rc::new(val), key);
+        VNode::from(comp)
+    }
+}
diff --git a/ui/src/widget/mod.rs b/ui/src/widget/mod.rs
index b885d1b..1104b01 100644
--- a/ui/src/widget/mod.rs
+++ b/ui/src/widget/mod.rs
@@ -1,3 +1,6 @@
+mod content_spacer;
+pub use content_spacer::ContentSpacer;
+
 mod migrate_window;
 pub use migrate_window::MigrateWindow;
 
-- 
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] 3+ messages in thread

* Re: [pdm-devel] [RFC pdm v2] ui: make layout more consistent using new ContentSpacer widget
  2025-01-10 12:50 [pdm-devel] [RFC pdm v2] ui: make layout more consistent using new ContentSpacer widget Dietmar Maurer
@ 2025-01-15 15:48 ` Thomas Lamprecht
  2025-01-15 17:38   ` Dietmar Maurer
  0 siblings, 1 reply; 3+ messages in thread
From: Thomas Lamprecht @ 2025-01-15 15:48 UTC (permalink / raw)
  To: Proxmox Datacenter Manager development discussion, Dietmar Maurer

Am 10.01.25 um 13:50 schrieb Dietmar Maurer:
> Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
> ---
> 
>  Changhes in v2:
>  - use box shadows instead of border
>  - use ContentSpacer for dashboard
>  - use ContentSpacer for PveRemote
> 
>  ui/css/crisp-yew-style.scss            | 12 ++++
>  ui/css/desktop-yew-style.scss          | 11 +++
>  ui/css/pdm.scss                        | 26 ++++++-
>  ui/src/administration/mod.rs           | 28 ++++++--
>  ui/src/certificates.rs                 | 30 ++++++--
>  ui/src/configuration/mod.rs            | 25 ++++---
>  ui/src/configuration/other/mod.rs      |  9 ++-
>  ui/src/configuration/other/webauthn.rs |  1 -
>  ui/src/dashboard/mod.rs                | 17 +++--
>  ui/src/main_menu.rs                    | 22 +++---
>  ui/src/pve/mod.rs                      |  7 +-
>  ui/src/widget/content_spacer.rs        | 99 ++++++++++++++++++++++++++
>  ui/src/widget/mod.rs                   |  3 +
>  13 files changed, 242 insertions(+), 48 deletions(-)
>  create mode 100644 ui/src/widget/content_spacer.rs

This was seemingly applied now by yourself? I saw no review on the list, did I
miss it?

The configuration, syslog, ... panels look quite odd now, it's a bit hard to
tell if that is wanted as there is no commit message describing the whats and
whys..

So I'd revert this again?


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


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

* Re: [pdm-devel] [RFC pdm v2] ui: make layout more consistent using new ContentSpacer widget
  2025-01-15 15:48 ` Thomas Lamprecht
@ 2025-01-15 17:38   ` Dietmar Maurer
  0 siblings, 0 replies; 3+ messages in thread
From: Dietmar Maurer @ 2025-01-15 17:38 UTC (permalink / raw)
  To: Thomas Lamprecht, Proxmox Datacenter Manager development discussion

> This was seemingly applied now by yourself? I saw no review on the list, did I
> miss it?

Applied by accident, sorry.

> The configuration, syslog, ... panels look quite odd now, it's a bit hard to
> tell if that is wanted as there is no commit message describing the whats and whys..

IMHO layout it is better than before, because it has more consistent spacing (as written in the commit message). All major pages use the same style now.

Also, IT only affects the new "Desktop" style. ("Crisp" theme should be mainly unaffected).

Lets talk tomorrow in the office. Maybe we can find a improvement for syslog like panels. If not, we can still revert.


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


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

end of thread, other threads:[~2025-01-15 17:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-10 12:50 [pdm-devel] [RFC pdm v2] ui: make layout more consistent using new ContentSpacer widget Dietmar Maurer
2025-01-15 15:48 ` Thomas Lamprecht
2025-01-15 17:38   ` Dietmar Maurer

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