Skip to main content

perspective_viewer/components/column_selector/
pivot_column.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 perspective_client::config::ColumnType;
14use web_sys::*;
15use yew::prelude::*;
16
17use super::expr_edit_button::*;
18use crate::components::dragdrop_list::*;
19use crate::components::type_icon::TypeIcon;
20use crate::presentation::{ColumnSettingsTarget, Presentation};
21use crate::session::*;
22use crate::utils::*;
23
24#[derive(Properties)]
25pub struct PivotColumnProps {
26    /// Column name.
27    pub column: String,
28
29    #[prop_or_default]
30    pub column_type: Option<ColumnType>,
31
32    /// The drag starte of this column, if applicable.
33    pub action: DragTarget,
34
35    /// Session metadata snapshot — threaded from `SessionProps`.
36    #[prop_or_default]
37    pub metadata: Option<SessionMetadataRc>,
38
39    /// Opens this column's settings, when the host offers them.
40    #[prop_or_default]
41    pub on_open_expr_panel: Option<Callback<ColumnSettingsTarget>>,
42
43    /// Is this column's settings panel open?
44    #[prop_or_default]
45    pub is_editing: bool,
46
47    // State
48    #[prop_or_default]
49    pub opt_session: Option<Session>,
50    pub presentation: Presentation,
51}
52
53impl PartialEq for PivotColumnProps {
54    fn eq(&self, other: &Self) -> bool {
55        self.column == other.column
56            && self.action == other.action
57            && self.metadata == other.metadata
58            && self.is_editing == other.is_editing
59            && self.on_open_expr_panel.is_some() == other.on_open_expr_panel.is_some()
60    }
61}
62
63impl DragDropListItemProps for PivotColumnProps {
64    type Item = String;
65
66    fn get_item(&self) -> String {
67        self.column.clone()
68    }
69}
70
71pub struct PivotColumn;
72
73impl Component for PivotColumn {
74    type Message = ();
75    type Properties = PivotColumnProps;
76
77    fn create(_ctx: &Context<Self>) -> Self {
78        Self
79    }
80
81    fn view(&self, ctx: &Context<Self>) -> Html {
82        let dragstart = Callback::from({
83            let event_name = ctx.props().column.to_owned();
84            let presentation = ctx.props().presentation.clone();
85            let action = ctx.props().action;
86            move |event: DragEvent| {
87                if presentation.set_drag_image(&event) {
88                    presentation.notify_drag_start(event_name.to_string(), DragEffect::Move(action))
89                }
90            }
91        });
92
93        let dragend = Callback::from({
94            let presentation = ctx.props().presentation.clone();
95            move |_event| presentation.notify_drag_end()
96        });
97
98        let col_type = ctx.props().column_type.unwrap_or_else(|| {
99            ctx.props()
100                .metadata
101                .as_ref()
102                .and_then(|x| x.get_column_table_type(&ctx.props().column))
103                .unwrap_or(ColumnType::Integer)
104        });
105
106        html! {
107            <div
108                class="pivot-column-draggable"
109                draggable="true"
110                ondragstart={dragstart}
111                ondragend={dragend}
112            >
113                <div class="pivot-column-border">
114                    <span class="drag-handle icon" />
115                    <TypeIcon ty={col_type} />
116                    <span class="column_name">{ ctx.props().column.clone() }</span>
117                    if let Some(on_open_expr_panel) = &ctx.props().on_open_expr_panel {
118                        <ExprEditButton
119                            name={ctx.props().column.clone()}
120                            {on_open_expr_panel}
121                            is_expression=false
122                            is_disabled=false
123                            is_editing={ctx.props().is_editing}
124                        />
125                    }
126                </div>
127            </div>
128        }
129    }
130}