perspective_viewer/custom_elements/
copy_dropdown.rs1use std::cell::RefCell;
14use std::rc::Rc;
15
16use ::perspective_js::utils::{global, *};
17use wasm_bindgen::prelude::*;
18use wasm_bindgen_futures::spawn_local;
19use web_sys::*;
20use yew::*;
21
22use super::modal::*;
23use super::viewer::PerspectiveViewerElement;
24use crate::components::copy_dropdown::{CopyDropDownMenu, CopyDropDownMenuProps};
25use crate::js::*;
26use crate::model::*;
27use crate::utils::*;
28
29#[wasm_bindgen]
30#[derive(Clone)]
31pub struct CopyDropDownMenuElement {
32    elem: HtmlElement,
33    modal: Rc<RefCell<Option<ModalElement<CopyDropDownMenu>>>>,
34}
35
36impl CustomElementMetadata for CopyDropDownMenuElement {
37    const CUSTOM_ELEMENT_NAME: &'static str = "perspective-copy-menu";
38}
39
40#[wasm_bindgen]
41impl CopyDropDownMenuElement {
42    #[wasm_bindgen(constructor)]
43    pub fn new(elem: HtmlElement) -> Self {
44        Self {
45            elem,
46            modal: Default::default(),
47        }
48    }
49
50    pub fn open(&self, target: HtmlElement) {
51        if let Some(x) = &*self.modal.borrow() {
52            ApiFuture::spawn(x.clone().open(target, None));
53        }
54    }
55
56    pub fn hide(&self) -> ApiResult<()> {
57        let borrowed = self.modal.borrow();
58        borrowed.as_ref().into_apierror()?.hide()
59    }
60
61    pub fn set_model(&self, parent: &PerspectiveViewerElement) {
65        self.set_config_model(parent)
66    }
67
68    pub fn connected_callback(&self) {}
69}
70
71impl CopyDropDownMenuElement {
72    pub fn new_from_model<A: GetViewerConfigModel>(model: &A) -> Self {
73        let dropdown = global::document()
74            .create_element("perspective-copy-menu")
75            .unwrap()
76            .unchecked_into::<HtmlElement>();
77
78        let elem = Self::new(dropdown);
79        elem.set_config_model(model);
80        elem
81    }
82
83    pub fn set_config_model<A: GetViewerConfigModel>(&self, model: &A) {
84        let callback = Callback::from({
85            let model = model.cloned();
86            let modal_rc = self.modal.clone();
87            move |x: ExportFile| {
88                let model = model.clone();
89                let modal = modal_rc.borrow().clone().unwrap();
90                spawn_local(async move {
91                    let mime = x.method.mimetype(x.is_chart);
92                    let task = model.export_method_to_jsvalue(x.method);
93                    let result = copy_to_clipboard(task, mime).await;
94                    crate::js_log_maybe!({
95                        result?;
96                        modal.hide()?;
97                    })
98                })
99            }
100        });
101
102        let renderer = model.renderer().clone();
103        let props = props!(CopyDropDownMenuProps {
104            renderer,
105            callback,
106            root: self.elem.clone()
107        });
108
109        let modal = ModalElement::new(self.elem.clone(), props, true, None);
110        *self.modal.borrow_mut() = Some(modal);
111    }
112}