rate_app/cards/prime/visual/
gauge.rs

1use crate::blocks;
2use rate_ui::widget::wired_widget::{SingleFlowMeta, SingleFlowProps, WiredWidget};
3use rate_ui::widget::{Context, Widget, WidgetRuntime};
4use rill_protocol::io::provider::Path;
5use rill_protocol::range::{Pct, Range};
6use rrpack_prime::visual::gauge::GaugeState;
7use yew::{html, Html};
8
9pub type GaugeCard = WidgetRuntime<GaugeCardWidget>;
10
11#[derive(Default)]
12pub struct GaugeCardWidget {}
13
14impl Widget for GaugeCardWidget {
15    type Event = ();
16    type Tag = Option<Path>;
17    type Properties = SingleFlowProps;
18    type Meta = SingleFlowMeta<Self>;
19
20    fn init(&mut self, ctx: &mut Context<Self>) {
21        self.on_props(ctx);
22    }
23
24    fn on_props(&mut self, ctx: &mut Context<Self>) {
25        let path = ctx.properties().path.clone().of_server();
26        ctx.rewire(path);
27    }
28
29    fn view(&self, ctx: &Context<Self>) -> Html {
30        let body = {
31            if let Some(state) = ctx.meta().state() {
32                /*
33                    <div class="w-100 p-4 text-end row mt-5">
34                        <h2>{ state.stat.value }</h2>
35                    </div>
36                */
37                if let Some(value) = state.value {
38                    let min = state.spec.range.min.min(state.abs_min);
39                    let max = state.spec.range.max.max(state.abs_max);
40                    let range = Range::new(min, max);
41                    let pct = Pct::from_range(value, &range);
42                    let width = format!("width: {}%;", pct.to_cent());
43                    html! {
44                        <>
45                            <div class="progress">
46                                <div class="progress-bar" style=width></div>
47                            </div>
48                            <div class="d-flex flex-row justify-content-between">
49                                <div>{ min }</div>
50                                <div>{ value }</div>
51                                <div>{ max }</div>
52                            </div>
53                        </>
54                    }
55                } else {
56                    let width = "width: 100%;";
57                    html! {
58                        <>
59                            <div class="progress">
60                                <div class="progress-bar progress-bar-striped progress-bar-animated bg-secondary" style=width></div>
61                            </div>
62                            <div class="text-secondary text-center">{ "No data yet..." }</div>
63                        </>
64                    }
65                }
66            } else {
67                blocks::spinner("Connecting...")
68            }
69        };
70        html! {
71            <div yew=module_path!() class="flex-grow-1 p-3 d-flex flex-column justify-content-center align-items-stretch">
72                { body }
73            </div>
74        }
75    }
76}
77
78impl WiredWidget<SingleFlowMeta<Self>> for GaugeCardWidget {
79    type Flow = GaugeState;
80
81    fn state_changed(&mut self, _reloaded: bool, ctx: &mut Context<Self>) {
82        ctx.redraw();
83    }
84}