* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox