Skip to main content

rate_app/
app.rs

1use crate::cases::state::{GlobalScene, SceneState, SCENE};
2use crate::{alerts, cases, explorer, welcome};
3use anyhow::Error;
4use rate_ui::agents::live::LiveAgent;
5use rate_ui::shared_object::{DataChanged, SharedObject};
6use rate_ui::widget::{Context, NotificationHandler, OnWireEvent, Widget, WidgetRuntime};
7use yew::{html, Html};
8
9pub type App = WidgetRuntime<AppWidget>;
10
11pub struct AppWidget {
12    scene: SharedObject<SceneState>,
13}
14
15impl Default for AppWidget {
16    fn default() -> Self {
17        Self {
18            scene: SCENE.with(SharedObject::clone),
19        }
20    }
21}
22
23impl Widget for AppWidget {
24    type Event = ();
25    type Tag = ();
26    type Properties = ();
27    type Meta = ();
28
29    fn init(&mut self, ctx: &mut Context<Self>) {
30        // Just to keep the connection alive all the time.
31        ctx.live();
32        self.scene.subscribe(ctx);
33    }
34
35    fn view(&self, _ctx: &Context<Self>) -> Html {
36        let state = self.scene.read();
37        let menu;
38        let body;
39        match &state.global_scene {
40            GlobalScene::Home => {
41                menu = html! {};
42                body = html! {
43                    <welcome::Shield />
44                };
45            }
46            GlobalScene::Cases => {
47                menu = html! {
48                    <cases::DashboardMenu />
49                };
50                body = html! {
51                    <cases::Dashboard />
52                };
53            }
54            GlobalScene::Explorer => {
55                menu = html! {
56                    <explorer::DashboardMenu />
57                };
58                body = html! {
59                    <explorer::Dashboard />
60                };
61            }
62        }
63        html! {
64            <div class="d-flex flex-column bg-white" style="min-height: 100vh;">
65                <nav class="navbar z-1000 border shadow-sm bg-light">
66                    <div class="container-fluid">
67                        <div class="navbar-brand me-3">
68                            <div class="fw-bold">{ "RillRate" }</div>
69                        </div>
70                        <div class="mx-2">
71                            <welcome::SceneSelector />
72                        </div>
73                        <div class="flex-grow-1 d-flex flex-row justify-content-between">
74                            { menu }
75                        </div>
76                    </div>
77                </nav>
78                <div class="flex-grow-1 p-3" style="width: 100%; height: 100%;">
79                    { body }
80                </div>
81                <nav class="navbar bg-light" style="height: 50px;">
82                    <div class="container-fluid">
83                        <div class="text-secondary">{ "© 2021 RillRate OÜ" }</div>
84                        <div>{ "v" }{ crate::meta::VERSION }</div>
85                        <img style="height: 1.8rem;" src="./images/logo.svg" />
86                    </div>
87                </nav>
88                <alerts::AlertToast />
89                <cases::Loader />
90                <explorer::Loader />
91            </div>
92        }
93    }
94}
95
96impl OnWireEvent<LiveAgent> for AppWidget {}
97
98impl NotificationHandler<DataChanged<SceneState>> for AppWidget {
99    fn handle(
100        &mut self,
101        _event: DataChanged<SceneState>,
102        ctx: &mut Context<Self>,
103    ) -> Result<(), Error> {
104        ctx.redraw();
105        Ok(())
106    }
107}