Skip to main content

perspective_viewer/components/
export_dropdown.rs

1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
3// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
4// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
5// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
6// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
8// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9// ┃ This file is part of the Perspective library, distributed under the terms ┃
10// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13use std::rc::Rc;
14
15use yew::prelude::*;
16
17use super::containers::dropdown_menu::*;
18use crate::config::*;
19use crate::renderer::*;
20use crate::session::Session;
21
22pub type ExportDropDownMenuItem = DropDownMenuItem<ExportFile>;
23
24#[derive(Properties, PartialEq)]
25pub struct ExportDropDownMenuProps {
26    pub renderer: Renderer,
27    pub session: Session,
28    pub callback: Callback<ExportFile>,
29}
30
31pub enum ExportDropDownMenuMsg {
32    TitleChange,
33}
34
35#[derive(Default)]
36pub struct ExportDropDownMenu {
37    title: String,
38    input_ref: NodeRef,
39    invalid: bool,
40}
41
42impl Component for ExportDropDownMenu {
43    type Message = ExportDropDownMenuMsg;
44    type Properties = ExportDropDownMenuProps;
45
46    fn view(&self, ctx: &Context<Self>) -> yew::virtual_dom::VNode {
47        let callback = ctx.link().callback(|_| ExportDropDownMenuMsg::TitleChange);
48        let is_chart = ctx.props().renderer.is_chart();
49        html! {
50            <>
51                <span class="dropdown-group-label">{ "Save as" }</span>
52                <input
53                    class={if self.invalid { "invalid" } else { "" }}
54                    oninput={callback}
55                    ref={&self.input_ref}
56                    value={self.title.to_owned()}
57                />
58                <DropDownMenu<ExportFile>
59                    values={Rc::new(get_menu_items(&self.title, is_chart))}
60                    callback={&ctx.props().callback}
61                />
62            </>
63        }
64    }
65
66    fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
67        match msg {
68            ExportDropDownMenuMsg::TitleChange => {
69                self.title = self
70                    .input_ref
71                    .cast::<web_sys::HtmlInputElement>()
72                    .unwrap()
73                    .value();
74
75                self.invalid = self.title.is_empty();
76                true
77            },
78        }
79    }
80
81    fn create(ctx: &Context<Self>) -> Self {
82        Self {
83            title: ctx
84                .props()
85                .session
86                .get_title()
87                .unwrap_or_else(|| "untitled".to_owned()),
88            ..Default::default()
89        }
90    }
91}
92
93fn get_menu_items(name: &str, is_chart: bool) -> Vec<ExportDropDownMenuItem> {
94    vec![
95        ExportDropDownMenuItem::OptGroup(
96            "Current View".into(),
97            if is_chart {
98                vec![
99                    ExportMethod::Csv.new_file(name, is_chart),
100                    ExportMethod::Json.new_file(name, is_chart),
101                    ExportMethod::Ndjson.new_file(name, is_chart),
102                    ExportMethod::Arrow.new_file(name, is_chart),
103                    ExportMethod::Html.new_file(name, is_chart),
104                    ExportMethod::Plugin.new_file(name, is_chart),
105                ]
106            } else {
107                vec![
108                    ExportMethod::Csv.new_file(name, is_chart),
109                    ExportMethod::Json.new_file(name, is_chart),
110                    ExportMethod::Ndjson.new_file(name, is_chart),
111                    ExportMethod::Arrow.new_file(name, is_chart),
112                    ExportMethod::Html.new_file(name, is_chart),
113                ]
114            },
115        ),
116        ExportDropDownMenuItem::OptGroup("All".into(), vec![
117            ExportMethod::CsvAll.new_file(name, is_chart),
118            ExportMethod::JsonAll.new_file(name, is_chart),
119            ExportMethod::NdjsonAll.new_file(name, is_chart),
120            ExportMethod::ArrowAll.new_file(name, is_chart),
121        ]),
122        ExportDropDownMenuItem::OptGroup("Config".into(), vec![
123            ExportMethod::JsonConfig.new_file(name, is_chart),
124        ]),
125    ]
126}