perspective_viewer/components/
new_panel_menu.rs1use std::rc::Rc;
14
15use yew::prelude::*;
16
17#[derive(Clone, PartialEq)]
20pub enum NewPanelPick {
21 FromTable { client: String, table: String },
22 FromPanel(String),
23}
24
25pub type HostedTables = Rc<Vec<(String, Vec<String>)>>;
28
29pub type PanelLabels = Rc<Vec<(String, Option<String>)>>;
31
32#[derive(Properties, PartialEq)]
33pub struct NewPanelMenuProps {
34 pub tables: Option<HostedTables>,
36 pub panels: PanelLabels,
37 pub callback: Callback<NewPanelPick>,
38}
39
40#[function_component]
43pub fn NewPanelMenu(props: &NewPanelMenuProps) -> Html {
44 let pick = |value: NewPanelPick| props.callback.reform(move |_: MouseEvent| value.clone());
45
46 let tables = match &props.tables {
47 None => html! { <span class="no-results">{ "Loading..." }</span> },
48 Some(clients) if clients.iter().all(|(_, tables)| tables.is_empty()) => {
49 html! { <span class="no-results">{ "No tables" }</span> }
50 },
51 Some(clients) => {
52 let multi = clients.len() > 1;
53 clients
54 .iter()
55 .map(|(client, tables)| {
56 let rows = tables.iter().map(|table| {
57 let onmousedown = pick(NewPanelPick::FromTable {
58 client: client.clone(),
59 table: table.clone(),
60 });
61 html! { <span class="dropdown-menu-item" {onmousedown}>{ table }</span> }
62 });
63
64 html! {
65 <>
66 if multi { <span class="dropdown-group-sublabel">{ client }</span> }
67 { for rows }
68 </>
69 }
70 })
71 .collect::<Html>()
72 },
73 };
74
75 let panels = if props.panels.is_empty() {
76 html! { <span class="no-results">{ "No panels" }</span> }
77 } else {
78 props
79 .panels
80 .iter()
81 .map(|(id, title)| {
82 let onmousedown = pick(NewPanelPick::FromPanel(id.clone()));
83 let label = title.clone().unwrap_or_else(|| id.clone());
84 html! { <span class="dropdown-menu-item" {onmousedown}>{ label }</span> }
85 })
86 .collect::<Html>()
87 };
88
89 html! {
90 <div class="new-panel-menu">
91 <span class="dropdown-group-label" data-label="new-from-table" />
92 <div class="dropdown-group-container">{ tables }</div>
93 <span class="dropdown-group-label" data-label="new-from-panel" />
94 <div class="dropdown-group-container">{ panels }</div>
95 </div>
96 }
97}