use web_sys::*;
use yew::prelude::*;
use crate::config::ViewConfigUpdate;
use crate::custom_elements::expression_editor::ExpressionEditorElement;
use crate::model::*;
use crate::renderer::Renderer;
use crate::session::Session;
use crate::utils::*;
use crate::*;
#[derive(Clone, PartialEq, Properties)]
pub struct AddExpressionButtonProps {
pub session: Session,
pub renderer: Renderer,
}
derive_model!(Renderer, Session for AddExpressionButtonProps);
pub enum AddExpressionButtonMsg {
SaveExpression(JsValue),
OpenExpressionEditor(bool),
CloseExpression,
MouseEnter(bool),
MouseLeave,
}
use AddExpressionButtonMsg::*;
#[derive(Default)]
pub struct AddExpressionButton {
noderef: NodeRef,
expression_editor: Option<ExpressionEditorElement>,
mouseover: bool,
mode_open: bool,
}
impl Component for AddExpressionButton {
type Message = AddExpressionButtonMsg;
type Properties = AddExpressionButtonProps;
fn create(_ctx: &Context<Self>) -> Self {
Self::default()
}
fn update(&mut self, ctx: &Context<Self>, msg: AddExpressionButtonMsg) -> bool {
match msg {
SaveExpression(expression) => {
self.mode_open = false;
let task = {
let expression = expression.as_string().unwrap();
let mut expressions = ctx.props().session.get_view_config().expressions.clone();
expressions.retain(|x| x != &expression);
expressions.push(expression);
ctx.props().update_and_render(ViewConfigUpdate {
expressions: Some(expressions),
..Default::default()
})
};
let expr = self.expression_editor.clone();
ApiFuture::spawn(async move {
task.await?;
if let Some(editor) = expr.as_ref() {
editor.hide().unwrap_or_default();
editor.reset_empty_expr();
}
Ok(())
});
true
}
OpenExpressionEditor(reset) => {
self.mode_open = true;
if reset {
self.expression_editor = None;
}
let target = self.noderef.cast::<HtmlElement>().unwrap();
let expression_editor = self.expression_editor.get_or_insert_with(|| {
let on_save = ctx.link().callback(SaveExpression);
let on_blur = ctx.link().callback(|_| CloseExpression);
ExpressionEditorElement::new(
ctx.props().session.clone(),
on_save,
None,
on_blur,
None,
)
});
expression_editor.open(target);
true
}
CloseExpression => {
self.mode_open = false;
true
}
MouseEnter(is_render) => {
self.mouseover = is_render;
is_render
}
MouseLeave => {
self.mouseover = false;
true
}
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
let onmouseout = ctx.link().callback(|_| MouseLeave);
let onmouseover = ctx
.link()
.callback(|event: MouseEvent| MouseEnter(event.which() == 0));
let onmousedown = ctx.link().callback(|event: MouseEvent| {
AddExpressionButtonMsg::OpenExpressionEditor(event.shift_key())
});
let mut class = classes!();
if self.mouseover || self.mode_open {
class.push("dragdrop-hover");
}
html! {
<div
id="add-expression"
data-index="-1"
ref={ &self.noderef }
{ class }
{ onmouseover }
{ onmouseout }
{ onmousedown }>
<span id="add-expression-title">{ "New Column" }</span>
</div>
}
}
}