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 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}