perspective_viewer/components/column_selector/
sort_column.rs1use 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
26pub 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 <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}