* [yew-devel] [PATCH yew-comp] rrd time frame selector: seperate time frame from mode
@ 2025-08-29 12:21 Dominik Csapak
0 siblings, 0 replies; only message in thread
From: Dominik Csapak @ 2025-08-29 12:21 UTC (permalink / raw)
To: yew-devel
by splitting the one combobox with many entries into a combobox for the
timeframe (hour, day, etc.) and a segmented button for maximum/average.
This makes the combobox less cluttered and sill retains all the
information.
While at it, use the `tr` macro to prepare the values for translation.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
i tried using radio buttons for the mode, but this looked weird when
using inline in pdm gui.
Using a similar mechanism as the task modes seemed better to me.
I thought about implementing the timeframe as a slider, but this
make the UX worse IMHO, since one does not know what values exist
before selecting (we don't have a range/slider component yet where
the values are labeled)
src/rrd_timeframe_selector.rs | 125 +++++++++++++++++-----------------
1 file changed, 61 insertions(+), 64 deletions(-)
diff --git a/src/rrd_timeframe_selector.rs b/src/rrd_timeframe_selector.rs
index 5758a04..36ded09 100644
--- a/src/rrd_timeframe_selector.rs
+++ b/src/rrd_timeframe_selector.rs
@@ -6,10 +6,12 @@ use yew::html::IntoEventCallback;
use yew::prelude::*;
use yew::virtual_dom::{VComp, VNode};
-use proxmox_rrd_api_types as rrd_types;
+use proxmox_rrd_api_types::{self as rrd_types, RrdMode, RrdTimeframe};
+use pwt::css::{AlignItems, ColorScheme};
use pwt::prelude::*;
use pwt::state::local_storage;
use pwt::widget::form::Combobox;
+use pwt::widget::{Button, Row, SegmentedButton};
use pwt_macros::builder;
/// Combobox for selecting the theme density.
@@ -145,24 +147,20 @@ pub struct PwtRRDTimeframeSelector {
pub enum Msg {
SetRRDTimeframe(String),
+ SetRRDMode(RrdMode),
}
-fn display_value(v: &AttrValue) -> &str {
+fn display_value(v: &AttrValue) -> Html {
match v.as_str() {
- "hour-AVERAGE" => "Hour (average)",
- "hour-MAX" => "Hour (maximum)",
- "day-AVERAGE" => "Day (average)",
- "day-MAX" => "Day (maximum)",
- "week-AVERAGE" => "Week (average)",
- "week-MAX" => "Week (maximum)",
- "month-AVERAGE" => "Month (average)",
- "month-MAX" => "Month (maximum)",
- "year-AVERAGE" => "Year (average)",
- "year-MAX" => "Year (maximum)",
- "decade-AVERAGE" => "Decade (average)",
- "decade-MAX" => "Decade (maximum)",
- _ => v,
- }
+ "hour" => tr!("Hour"),
+ "day" => tr!("Day"),
+ "week" => tr!("Week"),
+ "month" => tr!("Month"),
+ "year" => tr!("Year"),
+ "decade" => tr!("Decade"),
+ _ => v.to_string(),
+ }
+ .into()
}
impl Component for PwtRRDTimeframeSelector {
@@ -170,31 +168,13 @@ impl Component for PwtRRDTimeframeSelector {
type Properties = RRDTimeframeSelector;
fn create(_ctx: &Context<Self>) -> Self {
- use rrd_types::RrdMode::*;
- use rrd_types::RrdTimeframe::*;
-
- let timeframe = RRDTimeframe::load();
-
- let values = [
- RRDTimeframe::new(Hour, Average),
- RRDTimeframe::new(Hour, Max),
- RRDTimeframe::new(Day, Average),
- RRDTimeframe::new(Day, Max),
- RRDTimeframe::new(Week, Average),
- RRDTimeframe::new(Week, Max),
- RRDTimeframe::new(Month, Average),
- RRDTimeframe::new(Month, Max),
- RRDTimeframe::new(Year, Average),
- RRDTimeframe::new(Year, Max),
- RRDTimeframe::new(Decade, Average),
- RRDTimeframe::new(Decade, Max),
- ]
- .iter()
- .map(|v| AttrValue::from(v.serialize()))
- .collect();
+ let values = ["hour", "day", "week", "month", "year", "decade"]
+ .into_iter()
+ .map(|v| v.into())
+ .collect();
Self {
- timeframe,
+ timeframe: RRDTimeframe::load(),
items: Rc::new(values),
}
}
@@ -203,38 +183,55 @@ impl Component for PwtRRDTimeframeSelector {
let props = ctx.props();
match msg {
Msg::SetRRDTimeframe(timeframe_str) => {
- if let Ok(timeframe) = timeframe_str.as_str().parse::<RRDTimeframe>() {
- timeframe.store();
- self.timeframe = timeframe;
- if let Some(on_change) = &props.on_change {
- on_change.emit(timeframe);
- }
+ if let Ok(timeframe) = timeframe_str.as_str().parse::<RrdTimeframe>() {
+ self.timeframe.timeframe = timeframe;
+ self.timeframe.store();
}
- true
}
+ Msg::SetRRDMode(mode) => {
+ self.timeframe.mode = mode;
+ self.timeframe.store();
+ }
+ }
+ if let Some(on_change) = &props.on_change {
+ on_change.emit(self.timeframe);
}
+ true
}
fn view(&self, ctx: &Context<Self>) -> Html {
let props = ctx.props();
-
- Combobox::new()
- .required(true)
- .min_width(150)
- .class(props.class.clone())
- .default(self.timeframe.serialize())
- .items(self.items.clone())
- .on_change(ctx.link().callback(Msg::SetRRDTimeframe))
- .render_value(|v: &AttrValue| {
- html! {display_value(v)}
- })
- .show_filter(false)
- // Note: This is just for completeness. Not used because we do not show the filter...
- .filter(|item: &AttrValue, query: &str| {
- display_value(item)
- .to_lowercase()
- .contains(&query.to_lowercase())
- })
+ let average = self.timeframe.mode == RrdMode::Average;
+ let max = self.timeframe.mode == RrdMode::Max;
+
+ Row::new()
+ .class(AlignItems::Center)
+ .gap(2)
+ .with_child(
+ Combobox::new()
+ .required(true)
+ .min_width(100)
+ .class(props.class.clone())
+ .default(self.timeframe.timeframe.to_string())
+ .items(self.items.clone())
+ .on_change(ctx.link().callback(Msg::SetRRDTimeframe))
+ .render_value(display_value),
+ )
+ .with_child(
+ SegmentedButton::new()
+ .with_button(
+ Button::new(tr!("Maximum"))
+ .on_activate(ctx.link().callback(|_| Msg::SetRRDMode(RrdMode::Max)))
+ .class(max.then_some(ColorScheme::Primary))
+ .pressed(max),
+ )
+ .with_button(
+ Button::new(tr!("Average"))
+ .on_activate(ctx.link().callback(|_| Msg::SetRRDMode(RrdMode::Average)))
+ .class(average.then_some(ColorScheme::Primary))
+ .pressed(average),
+ ),
+ )
.into()
}
}
--
2.47.2
_______________________________________________
yew-devel mailing list
yew-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/yew-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-08-29 12:23 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-29 12:21 [yew-devel] [PATCH yew-comp] rrd time frame selector: seperate time frame from mode Dominik Csapak
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.