perspective_viewer/components/column_selector/
sort_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::*;
14use perspective_client::utils::PerspectiveResultExt;
15use web_sys::*;
16use yew::prelude::*;
17
18use crate::components::containers::dragdrop_list::*;
19use crate::components::type_icon::TypeIcon;
20use crate::dragdrop::*;
21use crate::model::*;
22use crate::renderer::*;
23use crate::session::*;
24use crate::*;
25
26/// A `SortColumn` includes the column name and `SortDir` arrow, a clickable
27/// button which cycles through the available `SortDir` states.
28pub struct SortColumn {}
29
30#[derive(Properties)]
31pub struct SortColumnProps {
32    pub sort: Sort,
33    pub idx: usize,
34    pub session: Session,
35    pub renderer: Renderer,
36    pub dragdrop: DragDrop,
37}
38
39impl PartialEq for SortColumnProps {
40    fn eq(&self, other: &Self) -> bool {
41        self.sort == other.sort && self.idx == other.idx
42    }
43}
44
45derive_model!(Renderer, Session for SortColumnProps);
46
47impl DragDropListItemProps for SortColumnProps {
48    type Item = Sort;
49
50    fn get_item(&self) -> Sort {
51        self.sort.clone()
52    }
53}
54
55pub enum SortColumnMsg {
56    SortDirClick(bool),
57}
58
59impl Component for SortColumn {
60    type Message = SortColumnMsg;
61    type Properties = SortColumnProps;
62
63    fn create(_ctx: &Context<Self>) -> Self {
64        Self {}
65    }
66
67    fn update(&mut self, ctx: &Context<Self>, msg: SortColumnMsg) -> bool {
68        match msg {
69            SortColumnMsg::SortDirClick(shift_key) => {
70                let is_split = ctx.props().session.get_view_config().split_by.is_empty();
71                let mut sort = ctx.props().session.get_view_config().sort.clone();
72                let sort_column = &mut sort.get_mut(ctx.props().idx).expect("Sort on no column");
73                sort_column.1 = sort_column.1.cycle(!is_split, shift_key);
74                let update = ViewConfigUpdate {
75                    sort: Some(sort),
76                    ..ViewConfigUpdate::default()
77                };
78
79                ctx.props()
80                    .update_and_render(update)
81                    .map(ApiFuture::spawn)
82                    .unwrap_or_log();
83
84                false
85            },
86        }
87    }
88
89    fn view(&self, ctx: &Context<Self>) -> Html {
90        let onclick = ctx
91            .link()
92            .callback(|event: MouseEvent| SortColumnMsg::SortDirClick(event.shift_key()));
93
94        let dragstart = Callback::from({
95            let event_name = ctx.props().sort.0.to_owned();
96            let dragdrop = ctx.props().dragdrop.clone();
97            move |event: DragEvent| {
98                dragdrop.set_drag_image(&event).unwrap();
99                dragdrop
100                    .notify_drag_start(event_name.to_string(), DragEffect::Move(DragTarget::Sort))
101            }
102        });
103
104        let dragend = Callback::from({
105            let dragdrop = ctx.props().dragdrop.clone();
106            move |_event| dragdrop.notify_drag_end()
107        });
108
109        let col_type = ctx
110            .props()
111            .session
112            .metadata()
113            .get_column_table_type(&ctx.props().sort.0.to_owned())
114            .unwrap_or(ColumnType::Integer);
115
116        html! {
117            <div
118                class="pivot-column-draggable"
119                draggable="true"
120                ondragstart={dragstart}
121                ondragend={dragend}
122            >
123                <div class="pivot-column-border">
124                    <TypeIcon ty={col_type} />
125                    // <TypeIcon ty={ColumnType::String} />
126                    <span class="column_name">{ ctx.props().sort.0.to_owned() }</span>
127                    <span
128                        class={format!("sort-icon {}", ctx.props().sort.1)}
129                        onmousedown={onclick}
130                    />
131                </div>
132            </div>
133        }
134    }
135}