@perspective-dev/viewer 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/dist/cdn/perspective-viewer.js +2 -2
  2. package/dist/cdn/perspective-viewer.js.map +4 -4
  3. package/dist/css/dracula.css +1 -1
  4. package/dist/css/gruvbox-dark.css +1 -1
  5. package/dist/css/gruvbox.css +1 -1
  6. package/dist/css/icons.css +1 -1
  7. package/dist/css/monokai.css +1 -1
  8. package/dist/css/pro-dark.css +1 -1
  9. package/dist/css/pro.css +1 -1
  10. package/dist/css/solarized-dark.css +1 -1
  11. package/dist/css/solarized.css +1 -1
  12. package/dist/css/themes.css +1 -1
  13. package/dist/css/vaporwave.css +1 -1
  14. package/dist/esm/extensions.d.ts +23 -2
  15. package/dist/esm/perspective-viewer.d.ts +2 -7
  16. package/dist/esm/perspective-viewer.inline.js +2 -2
  17. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  18. package/dist/esm/perspective-viewer.js +2 -2
  19. package/dist/esm/perspective-viewer.js.map +4 -4
  20. package/dist/esm/plugin.d.ts +1 -1
  21. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +1 -0
  22. package/dist/wasm/perspective-viewer.d.ts +218 -46
  23. package/dist/wasm/perspective-viewer.js +1251 -762
  24. package/dist/wasm/perspective-viewer.wasm +0 -0
  25. package/dist/wasm/perspective-viewer.wasm.d.ts +38 -19
  26. package/package.json +1 -1
  27. package/src/less/containers/scroll-panel.less +0 -1
  28. package/src/less/plugin-selector.less +15 -5
  29. package/src/less/status-bar.less +75 -27
  30. package/src/less/viewer.less +140 -58
  31. package/src/rust/components/column_dropdown.rs +21 -21
  32. package/src/rust/components/column_selector/active_column.rs +131 -120
  33. package/src/rust/components/column_selector/add_expression_button.rs +5 -0
  34. package/src/rust/components/column_selector/aggregate_selector.rs +8 -4
  35. package/src/rust/components/column_selector/config_selector.rs +170 -161
  36. package/src/rust/components/column_selector/empty_column.rs +16 -11
  37. package/src/rust/components/column_selector/{expression_toolbar.rs → expr_edit_button.rs} +7 -0
  38. package/src/rust/components/column_selector/filter_column.rs +195 -194
  39. package/src/rust/components/column_selector/inactive_column.rs +82 -67
  40. package/src/rust/components/column_selector/pivot_column.rs +16 -11
  41. package/src/rust/components/column_selector/sort_column.rs +9 -7
  42. package/src/rust/components/column_selector.rs +42 -37
  43. package/src/rust/components/column_settings_sidebar/save_settings.rs +3 -1
  44. package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +58 -0
  45. package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +6 -6
  46. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +2 -94
  47. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +111 -0
  48. package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +3 -3
  49. package/src/rust/components/column_settings_sidebar/style_tab.rs +23 -83
  50. package/src/rust/components/{column_settings_sidebar/sidebar.rs → column_settings_sidebar.rs} +198 -171
  51. package/src/rust/components/containers/dragdrop_list.rs +20 -20
  52. package/src/rust/components/containers/dropdown_menu.rs +4 -6
  53. package/src/rust/components/containers/mod.rs +1 -4
  54. package/src/rust/components/containers/scroll_panel.rs +80 -80
  55. package/src/rust/components/containers/scroll_panel_item.rs +36 -36
  56. package/src/rust/components/containers/select.rs +46 -44
  57. package/src/rust/components/containers/sidebar.rs +3 -19
  58. package/src/rust/components/{column_settings_sidebar/style_tab/symbol/symbol_config.rs → containers/sidebar_close_button.rs} +15 -9
  59. package/src/rust/components/containers/split_panel.rs +212 -200
  60. package/src/rust/components/containers/tab_list.rs +11 -11
  61. package/src/rust/components/copy_dropdown.rs +22 -25
  62. package/src/rust/components/datetime_column_style/custom.rs +19 -19
  63. package/src/rust/components/datetime_column_style/simple.rs +13 -14
  64. package/src/rust/components/datetime_column_style.rs +75 -76
  65. package/src/rust/components/editable_header.rs +18 -14
  66. package/src/rust/components/empty_row.rs +5 -5
  67. package/src/rust/components/export_dropdown.rs +42 -42
  68. package/src/rust/components/expression_editor.rs +25 -19
  69. package/src/rust/components/filter_dropdown.rs +22 -22
  70. package/src/rust/components/font_loader.rs +11 -9
  71. package/src/rust/components/form/code_editor.rs +106 -105
  72. package/src/rust/components/form/color_range_selector.rs +14 -12
  73. package/src/rust/components/form/color_selector.rs +3 -1
  74. package/src/rust/components/form/debug.rs +95 -94
  75. package/src/rust/components/form/highlight.rs +5 -3
  76. package/src/rust/components/form/mod.rs +3 -2
  77. package/src/rust/components/form/optional_field.rs +2 -2
  78. package/src/rust/components/form/{select_field.rs → select_enum_field.rs} +1 -46
  79. package/src/rust/components/form/select_value_field.rs +64 -0
  80. package/src/rust/components/function_dropdown.rs +21 -21
  81. package/src/rust/components/main_panel.rs +219 -0
  82. package/src/rust/components/mod.rs +6 -6
  83. package/src/rust/components/modal.rs +42 -42
  84. package/src/rust/components/number_column_style.rs +34 -88
  85. package/src/rust/components/plugin_selector.rs +22 -25
  86. package/src/rust/components/render_warning.rs +9 -6
  87. package/src/rust/components/settings_panel.rs +82 -0
  88. package/src/rust/components/status_bar.rs +250 -146
  89. package/src/rust/components/status_bar_counter.rs +26 -119
  90. package/src/rust/components/status_indicator.rs +95 -79
  91. package/src/rust/components/string_column_style.rs +45 -45
  92. package/src/rust/components/style/style_provider.rs +1 -15
  93. package/src/rust/components/style_controls/number_string_format/digits_section.rs +1 -1
  94. package/src/rust/components/style_controls/number_string_format/misc_section.rs +1 -1
  95. package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -1
  96. package/src/rust/components/style_controls/number_string_format.rs +45 -46
  97. package/src/rust/components/type_icon.rs +14 -11
  98. package/src/rust/components/viewer.rs +241 -384
  99. package/src/rust/config/columns_config.rs +2 -2
  100. package/src/rust/config/datetime_column_style.rs +1 -6
  101. package/src/rust/config/mod.rs +1 -0
  102. package/src/rust/config/number_column_style.rs +0 -6
  103. package/src/rust/config/number_string_format.rs +27 -4
  104. package/src/rust/config/viewer_config.rs +27 -167
  105. package/src/rust/custom_elements/copy_dropdown.rs +14 -6
  106. package/src/rust/custom_elements/export_dropdown.rs +15 -7
  107. package/src/rust/custom_elements/filter_dropdown.rs +4 -4
  108. package/src/rust/custom_elements/mod.rs +3 -0
  109. package/src/rust/custom_elements/viewer.rs +353 -161
  110. package/src/rust/custom_events.rs +55 -32
  111. package/src/rust/dragdrop.rs +4 -24
  112. package/src/rust/exprtk/cursor.rs +10 -1
  113. package/src/rust/exprtk/mod.rs +2 -0
  114. package/src/rust/exprtk/tokenize.rs +20 -3
  115. package/src/rust/js/clipboard.rs +2 -2
  116. package/src/rust/js/mimetype.rs +2 -7
  117. package/src/rust/js/mod.rs +0 -1
  118. package/src/rust/js/plugin.rs +7 -0
  119. package/src/rust/lib.rs +18 -5
  120. package/src/rust/model/column_locator.rs +82 -0
  121. package/src/rust/model/columns_iter_set.rs +1 -0
  122. package/src/rust/model/copy_export.rs +50 -14
  123. package/src/rust/model/edit_expression.rs +2 -5
  124. package/src/rust/model/eject.rs +41 -0
  125. package/src/rust/model/export_app.rs +3 -2
  126. package/src/rust/model/get_viewer_config.rs +4 -28
  127. package/src/rust/model/intersection_observer.rs +20 -8
  128. package/src/rust/model/mod.rs +11 -4
  129. package/src/rust/model/plugin_column_styles.rs +0 -31
  130. package/src/rust/model/reset_all.rs +38 -0
  131. package/src/rust/model/resize_observer.rs +34 -7
  132. package/src/rust/model/restore_and_render.rs +12 -7
  133. package/src/rust/{utils/scope.rs → model/send_plugin_config.rs} +32 -35
  134. package/src/rust/model/structural.rs +194 -23
  135. package/src/rust/model/update_and_render.rs +14 -4
  136. package/src/rust/{model/create_col.rs → presentation/column_locator.rs} +73 -42
  137. package/src/rust/{utils/wasm_abi.rs → presentation/sheets.rs} +54 -40
  138. package/src/rust/presentation.rs +60 -119
  139. package/src/rust/renderer/activate.rs +20 -5
  140. package/src/rust/renderer/limits.rs +0 -149
  141. package/src/rust/renderer/render_timer.rs +1 -1
  142. package/src/rust/renderer.rs +34 -18
  143. package/src/rust/root.rs +50 -0
  144. package/src/rust/session/column_defaults_update.rs +4 -4
  145. package/src/rust/session/drag_drop_update.rs +1 -1
  146. package/src/rust/session/metadata.rs +3 -17
  147. package/src/rust/session/replace_expression_update.rs +1 -2
  148. package/src/rust/session.rs +162 -82
  149. package/src/rust/utils/browser/blob.rs +16 -2
  150. package/src/rust/utils/browser/download.rs +1 -0
  151. package/src/rust/{components/column_settings_sidebar/mod.rs → utils/browser/dragdrop.rs} +14 -5
  152. package/src/rust/utils/browser/mod.rs +8 -4
  153. package/src/rust/utils/browser/selection.rs +5 -0
  154. package/src/rust/utils/custom_element.rs +28 -13
  155. package/src/rust/utils/datetime.rs +5 -0
  156. package/src/rust/utils/debounce.rs +7 -1
  157. package/src/rust/utils/hooks/use_async_callback.rs +7 -17
  158. package/src/rust/utils/mod.rs +28 -40
  159. package/src/rust/utils/number_format.rs +6 -5
  160. package/src/rust/utils/pubsub.rs +15 -10
  161. package/src/rust/utils/weak_scope.rs +11 -1
  162. package/src/svg/bookmark-icon.svg +4 -0
  163. package/src/svg/drag-handle copy.svg +10 -0
  164. package/src/svg/drawer-tab-hover.svg +5 -7
  165. package/src/svg/drawer-tab-invert-hover.svg +4 -8
  166. package/src/svg/drawer-tab-invert.svg +4 -7
  167. package/src/svg/drawer-tab.svg +4 -6
  168. package/src/svg/status_ok.svg +24 -24
  169. package/src/ts/extensions.ts +51 -3
  170. package/src/ts/perspective-viewer.ts +2 -14
  171. package/src/ts/plugin.ts +1 -1
  172. package/src/ts/ts-rs/ViewerConfigUpdate.ts +1 -1
  173. package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +0 -177
  174. package/src/rust/components/containers/tests/mod.rs +0 -11
  175. package/src/rust/components/containers/tests/split_panel.rs +0 -91
  176. package/src/rust/js/testing.rs +0 -149
  177. package/src/rust/utils/tee.rs +0 -88
  178. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline0.js +0 -0
  179. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline1.js +0 -0
  180. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline2.js +0 -0
  181. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline3.js +0 -0
  182. /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline4.js +0 -0
  183. /package/src/rust/components/{style_controls.rs → style_controls/mod.rs} +0 -0
  184. /package/src/rust/{components/containers → config}/kvpair.rs +0 -0
@@ -11,7 +11,6 @@
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
13
  use perspective_client::config::ColumnType;
14
- // use perspective_client::ColumnType;
15
14
  use web_sys::*;
16
15
  use yew::prelude::*;
17
16
 
@@ -19,15 +18,20 @@ use crate::components::containers::dragdrop_list::*;
19
18
  use crate::components::type_icon::TypeIcon;
20
19
  use crate::dragdrop::*;
21
20
  use crate::session::*;
21
+ use crate::utils::*;
22
+ use crate::*;
22
23
 
23
- pub struct PivotColumn {}
24
-
25
- #[derive(Properties)]
24
+ #[derive(Properties, PerspectiveProperties!)]
26
25
  pub struct PivotColumnProps {
27
- pub session: Session,
26
+ /// Column name.
28
27
  pub column: String,
29
- pub dragdrop: DragDrop,
28
+
29
+ /// The drag starte of this column, if applicable.
30
30
  pub action: DragTarget,
31
+
32
+ // State
33
+ pub session: Session,
34
+ pub dragdrop: DragDrop,
31
35
  }
32
36
 
33
37
  impl PartialEq for PivotColumnProps {
@@ -44,10 +48,16 @@ impl DragDropListItemProps for PivotColumnProps {
44
48
  }
45
49
  }
46
50
 
51
+ pub struct PivotColumn;
52
+
47
53
  impl Component for PivotColumn {
48
54
  type Message = ();
49
55
  type Properties = PivotColumnProps;
50
56
 
57
+ fn create(_ctx: &Context<Self>) -> Self {
58
+ Self
59
+ }
60
+
51
61
  fn view(&self, ctx: &Context<Self>) -> Html {
52
62
  let dragstart = Callback::from({
53
63
  let event_name = ctx.props().column.to_owned();
@@ -80,14 +90,9 @@ impl Component for PivotColumn {
80
90
  >
81
91
  <div class="pivot-column-border">
82
92
  <TypeIcon ty={col_type} />
83
- // <TypeIcon ty={ColumnType::String} />
84
93
  <span class="column_name">{ ctx.props().column.clone() }</span>
85
94
  </div>
86
95
  </div>
87
96
  }
88
97
  }
89
-
90
- fn create(_ctx: &Context<Self>) -> Self {
91
- Self {}
92
- }
93
98
  }
@@ -12,6 +12,7 @@
12
12
 
13
13
  use perspective_client::config::*;
14
14
  use perspective_client::utils::PerspectiveResultExt;
15
+ use perspective_js::utils::ApiFuture;
15
16
  use web_sys::*;
16
17
  use yew::prelude::*;
17
18
 
@@ -21,16 +22,15 @@ use crate::dragdrop::*;
21
22
  use crate::model::*;
22
23
  use crate::renderer::*;
23
24
  use crate::session::*;
25
+ use crate::utils::*;
24
26
  use crate::*;
25
27
 
26
- /// A `SortColumn` includes the column name and `SortDir` arrow, a clickable
27
- /// button which cycles through the available `SortDir` states.
28
- pub struct SortColumn {}
29
-
30
- #[derive(Properties)]
28
+ #[derive(Properties, PerspectiveProperties!)]
31
29
  pub struct SortColumnProps {
32
30
  pub sort: Sort,
33
31
  pub idx: usize,
32
+
33
+ // State
34
34
  pub session: Session,
35
35
  pub renderer: Renderer,
36
36
  pub dragdrop: DragDrop,
@@ -42,8 +42,6 @@ impl PartialEq for SortColumnProps {
42
42
  }
43
43
  }
44
44
 
45
- derive_model!(Renderer, Session for SortColumnProps);
46
-
47
45
  impl DragDropListItemProps for SortColumnProps {
48
46
  type Item = Sort;
49
47
 
@@ -56,6 +54,10 @@ pub enum SortColumnMsg {
56
54
  SortDirClick(bool),
57
55
  }
58
56
 
57
+ /// A `SortColumn` includes the column name and `SortDir` arrow, a clickable
58
+ /// button which cycles through the available `SortDir` states.
59
+ pub struct SortColumn {}
60
+
59
61
  impl Component for SortColumn {
60
62
  type Message = SortColumnMsg;
61
63
  type Properties = SortColumnProps;
@@ -15,7 +15,7 @@ mod add_expression_button;
15
15
  mod aggregate_selector;
16
16
  mod config_selector;
17
17
  mod empty_column;
18
- mod expression_toolbar;
18
+ mod expr_edit_button;
19
19
  mod filter_column;
20
20
  mod inactive_column;
21
21
  mod invalid_column;
@@ -27,6 +27,7 @@ use std::rc::Rc;
27
27
 
28
28
  pub use empty_column::*;
29
29
  pub use invalid_column::*;
30
+ use perspective_js::utils::ApiFuture;
30
31
  use web_sys::*;
31
32
  use yew::prelude::*;
32
33
 
@@ -37,38 +38,34 @@ use self::inactive_column::*;
37
38
  use super::containers::scroll_panel::*;
38
39
  use super::containers::split_panel::{Orientation, SplitPanel};
39
40
  use super::style::LocalStyle;
40
- use super::viewer::ColumnLocator;
41
41
  use crate::components::containers::scroll_panel_item::ScrollPanelItem;
42
42
  use crate::custom_elements::ColumnDropDownElement;
43
43
  use crate::dragdrop::*;
44
44
  use crate::model::*;
45
- use crate::presentation::Presentation;
45
+ use crate::presentation::ColumnLocator;
46
46
  use crate::renderer::*;
47
47
  use crate::session::*;
48
48
  use crate::utils::*;
49
49
  use crate::*;
50
50
 
51
- #[derive(Properties)]
51
+ #[derive(Properties, PerspectiveProperties!)]
52
52
  pub struct ColumnSelectorProps {
53
- pub session: Session,
54
- pub renderer: Renderer,
55
- pub dragdrop: DragDrop,
56
- pub presentation: Presentation,
57
-
53
+ /// Fires when the expression/config column is open.
58
54
  pub on_open_expr_panel: Callback<ColumnLocator>,
59
55
 
60
56
  /// This is passed to the add_expression_button for styling.
61
57
  pub selected_column: Option<ColumnLocator>,
62
58
 
59
+ /// Fires when this component is resized via the UI.
63
60
  #[prop_or_default]
64
61
  pub on_resize: Option<Rc<PubSub<()>>>,
65
62
 
66
- #[prop_or_default]
67
- pub on_dimensions_reset: Option<Rc<PubSub<()>>>,
63
+ // State
64
+ pub session: Session,
65
+ pub renderer: Renderer,
66
+ pub dragdrop: DragDrop,
68
67
  }
69
68
 
70
- derive_model!(DragDrop, Renderer, Session for ColumnSelectorProps);
71
-
72
69
  impl PartialEq for ColumnSelectorProps {
73
70
  fn eq(&self, rhs: &Self) -> bool {
74
71
  self.selected_column == rhs.selected_column
@@ -102,34 +99,40 @@ impl Component for ColumnSelector {
102
99
  type Properties = ColumnSelectorProps;
103
100
 
104
101
  fn create(ctx: &Context<Self>) -> Self {
102
+ let ColumnSelectorProps {
103
+ dragdrop,
104
+ renderer,
105
+ session,
106
+ ..
107
+ } = ctx.props();
105
108
  let table_sub = {
106
109
  let cb = ctx.link().callback(|_| ColumnSelectorMsg::TableLoaded);
107
- ctx.props().session.table_loaded.add_listener(cb)
110
+ session.table_loaded.add_listener(cb)
108
111
  };
109
112
 
110
113
  let view_sub = {
111
114
  let cb = ctx.link().callback(|_| ColumnSelectorMsg::ViewCreated);
112
- ctx.props().session.view_created.add_listener(cb)
115
+ session.view_created.add_listener(cb)
113
116
  };
114
117
 
115
118
  let drop_sub = {
116
119
  let cb = ctx.link().callback(ColumnSelectorMsg::Drop);
117
- ctx.props().dragdrop.drop_received.add_listener(cb)
120
+ dragdrop.drop_received.add_listener(cb)
118
121
  };
119
122
 
120
123
  let drag_sub = {
121
124
  let cb = ctx.link().callback(ColumnSelectorMsg::Drag);
122
- ctx.props().dragdrop.dragstart_received.add_listener(cb)
125
+ dragdrop.dragstart_received.add_listener(cb)
123
126
  };
124
127
 
125
128
  let dragend_sub = {
126
129
  let cb = ctx.link().callback(|_| ColumnSelectorMsg::DragEnd);
127
- ctx.props().dragdrop.dragend_received.add_listener(cb)
130
+ dragdrop.dragend_received.add_listener(cb)
128
131
  };
129
132
 
130
133
  let named = maybe! {
131
134
  let plugin =
132
- ctx.props().renderer.get_active_plugin().ok()?;
135
+ renderer.get_active_plugin().ok()?;
133
136
 
134
137
  Some(plugin.config_column_names()?.length() as usize)
135
138
  };
@@ -140,7 +143,7 @@ impl Component for ColumnSelector {
140
143
  move || link.send_message(ColumnSelectorMsg::HoverActiveIndex(None))
141
144
  });
142
145
 
143
- let column_dropdown = ColumnDropDownElement::new(ctx.props().session.clone());
146
+ let column_dropdown = ColumnDropDownElement::new(session.clone());
144
147
  Self {
145
148
  _subscriptions: [table_sub, view_sub, drop_sub, drag_sub, dragend_sub],
146
149
  named_row_count,
@@ -211,20 +214,25 @@ impl Component for ColumnSelector {
211
214
  }
212
215
 
213
216
  fn view(&self, ctx: &Context<Self>) -> Html {
214
- let config = ctx.props().session.get_view_config();
215
-
217
+ let ColumnSelectorProps {
218
+ session,
219
+ renderer,
220
+ dragdrop,
221
+ ..
222
+ } = ctx.props();
223
+ let config = session.get_view_config();
216
224
  let is_aggregated = config.is_aggregated();
217
225
  let columns_iter = ctx.props().column_selector_iter_set(&config);
218
226
  let onselect = ctx.link().callback(|()| ViewCreated);
219
227
  let ondragenter = ctx.link().callback(HoverActiveIndex);
220
228
  let ondragover = Callback::from(|_event: DragEvent| _event.prevent_default());
221
229
  let ondrop = Callback::from({
222
- let dragdrop = ctx.props().dragdrop.clone();
230
+ clone!(dragdrop);
223
231
  move |event| dragdrop.notify_drop(&event)
224
232
  });
225
233
 
226
234
  let ondragend = Callback::from({
227
- let dragdrop = ctx.props().dragdrop.clone();
235
+ clone!(dragdrop);
228
236
  move |_| dragdrop.notify_drag_end()
229
237
  });
230
238
 
@@ -242,8 +250,7 @@ impl Component for ColumnSelector {
242
250
  + config.split_by.len()
243
251
  + config.filter.len()
244
252
  + config.sort.len()) as f64,
245
- ctx.props()
246
- .session
253
+ session
247
254
  .metadata()
248
255
  .get_features()
249
256
  .map(|x| {
@@ -272,11 +279,11 @@ impl Component for ColumnSelector {
272
279
  let config_selector = html_nested! {
273
280
  <ScrollPanelItem key="config_selector" {size_hint}>
274
281
  <ConfigSelector
275
- dragdrop={&ctx.props().dragdrop}
276
- session={&ctx.props().session}
277
- renderer={&ctx.props().renderer}
278
282
  onselect={onselect.clone()}
279
283
  ondragenter={ctx.link().callback(|()| ViewCreated)}
284
+ {dragdrop}
285
+ {renderer}
286
+ {session}
280
287
  />
281
288
  </ScrollPanelItem>
282
289
  };
@@ -310,13 +317,12 @@ impl Component for ColumnSelector {
310
317
  {is_editing}
311
318
  {name}
312
319
  {on_open_expr_panel}
313
- dragdrop={&ctx.props().dragdrop}
314
- session={&ctx.props().session}
315
- renderer={&ctx.props().renderer}
316
- presentation={&ctx.props().presentation}
317
320
  {ondragenter}
318
321
  ondragend={&ondragend}
319
322
  onselect={&onselect}
323
+ {dragdrop}
324
+ {renderer}
325
+ {session}
320
326
  />
321
327
  </ScrollPanelItem>
322
328
  }
@@ -336,14 +342,13 @@ impl Component for ColumnSelector {
336
342
  {idx}
337
343
  visible={vc.is_visible}
338
344
  name={vc.name.to_owned()}
339
- dragdrop={&ctx.props().dragdrop}
340
- session={&ctx.props().session}
341
- renderer={&ctx.props().renderer}
342
- presentation={&ctx.props().presentation}
343
345
  {is_editing}
344
346
  onselect={&onselect}
345
347
  ondragend={&ondragend}
346
348
  on_open_expr_panel={&ctx.props().on_open_expr_panel}
349
+ {dragdrop}
350
+ {renderer}
351
+ {session}
347
352
  />
348
353
  </ScrollPanelItem>
349
354
  }
@@ -43,7 +43,9 @@ pub fn save_settings(props: &SaveSettingsProps) -> Html {
43
43
  </button>
44
44
  </div>
45
45
  }
46
- <div id="save-settings">
46
+ <div
47
+ id="save-settings"
48
+ >
47
49
  if props.is_save {
48
50
  <button
49
51
  id="psp-expression-editor-button-reset"
@@ -0,0 +1,58 @@
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
+
13
+ use perspective_client::clone;
14
+ use yew::{Callback, Html, Properties, function_component, html};
15
+
16
+ use crate::components::form::number_field::NumberField;
17
+ use crate::config::ColumnConfigValueUpdate;
18
+
19
+ // ░░░█▀█░█▀▄░█▀█░█▀█░█▀▀░█▀▄░▀█▀░▀█▀░█▀▀░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
20
+ // ░░░█▀▀░█▀▄░█░█░█▀▀░█▀▀░█▀▄░░█░░░█░░█▀▀░▀▀█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
21
+ // ░░░▀░░░▀░▀░▀▀▀░▀░░░▀▀▀░▀░▀░░▀░░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
22
+ #[derive(Properties, PartialEq)]
23
+ pub struct AggregateDepthSelectorProps {
24
+ pub on_change: Callback<ColumnConfigValueUpdate>,
25
+ pub value: u32,
26
+ pub group_by_depth: u32,
27
+ pub column_name: String,
28
+ }
29
+
30
+ #[function_component]
31
+ pub fn AggregateDepthSelector(props: &AggregateDepthSelectorProps) -> Html {
32
+ let state = yew::use_state_eq(|| 0);
33
+ yew::use_effect_with((props.column_name.to_owned(), props.group_by_depth), {
34
+ clone!(state, props.value);
35
+ move |deps| state.set(std::cmp::min(deps.1, value))
36
+ });
37
+
38
+ let on_change = yew::use_callback(
39
+ (state.setter(), props.on_change.clone()),
40
+ |x: Option<f64>, deps| {
41
+ deps.0.set(x.unwrap_or_default() as u32);
42
+ deps.1.emit(ColumnConfigValueUpdate::AggregateDepth(
43
+ x.unwrap_or_default() as u32,
44
+ ))
45
+ },
46
+ );
47
+
48
+ html! {
49
+ <NumberField
50
+ label="aggregate-depth"
51
+ {on_change}
52
+ min=0.0
53
+ max={props.group_by_depth as f64}
54
+ default=0.0
55
+ current_value={*state as f64}
56
+ />
57
+ }
58
+ }
@@ -17,8 +17,8 @@ use itertools::Itertools;
17
17
  use perspective_client::clone;
18
18
  use yew::{Html, Properties, function_component, html};
19
19
 
20
- use super::symbol_config::SymbolKVPair;
21
20
  use crate::components::empty_row::EmptyRow;
21
+ use crate::config::SymbolKVPair;
22
22
  use crate::custom_elements::FilterDropDownElement;
23
23
 
24
24
  #[derive(Properties, PartialEq)]
@@ -55,15 +55,15 @@ pub fn row_selector(props: &RowSelectorProps) -> Html {
55
55
 
56
56
  let inner = if props.selected_row.is_none() || props.focused {
57
57
  let mut pairs = props.pairs.clone();
58
- if let Some(ref rowval) = props.selected_row
59
- && let Some((i, _)) = pairs.iter().find_position(|pair| {
58
+ if let Some(ref rowval) = props.selected_row {
59
+ if let Some((i, _)) = pairs.iter().find_position(|pair| {
60
60
  pair.key
61
61
  .as_ref()
62
62
  .map(|keyval| keyval == rowval)
63
63
  .unwrap_or_default()
64
- })
65
- {
66
- pairs.remove(i);
64
+ }) {
65
+ pairs.remove(i);
66
+ }
67
67
  }
68
68
 
69
69
  let exclude: HashSet<_> = pairs
@@ -15,10 +15,9 @@ use std::rc::Rc;
15
15
  use itertools::Itertools;
16
16
  use yew::{Callback, Html, Properties, html};
17
17
 
18
- use super::symbol_config::SymbolKVPair;
19
- use crate::components::column_settings_sidebar::style_tab::symbol::row_selector::RowSelector;
20
- use crate::components::column_settings_sidebar::style_tab::symbol::symbol_selector::SymbolSelector;
18
+ use crate::components::column_settings_sidebar::style_tab::symbol::symbol_pairs_item::PairsListItem;
21
19
  use crate::components::style::LocalStyle;
20
+ use crate::config::SymbolKVPair;
22
21
  use crate::css;
23
22
  use crate::custom_elements::FilterDropDownElement;
24
23
 
@@ -92,94 +91,3 @@ impl yew::Component for PairsList {
92
91
  }
93
92
  }
94
93
  }
95
-
96
- #[derive(Properties, PartialEq)]
97
- pub struct PairsListItemProps {
98
- pub pair: SymbolKVPair,
99
- pub index: usize,
100
- pub pairs: Vec<SymbolKVPair>,
101
- pub update_pairs: Callback<Vec<SymbolKVPair>>,
102
- pub row_dropdown: Rc<FilterDropDownElement>,
103
- pub values: Rc<Vec<String>>,
104
- pub focused: bool,
105
- pub set_focused_index: Callback<Option<usize>>,
106
- pub column_name: String,
107
- }
108
-
109
- pub enum PairListItemMsg {
110
- Remove,
111
- UpdateKey(Option<String>),
112
- UpdateValue(String),
113
- }
114
-
115
- pub struct PairsListItem {}
116
- impl yew::Component for PairsListItem {
117
- type Message = PairListItemMsg;
118
- type Properties = PairsListItemProps;
119
-
120
- fn create(_ctx: &yew::Context<Self>) -> Self {
121
- Self {}
122
- }
123
-
124
- fn update(&mut self, ctx: &yew::Context<Self>, msg: Self::Message) -> bool {
125
- let p = ctx.props();
126
- match msg {
127
- PairListItemMsg::Remove => {
128
- let mut new_pairs = p.pairs.clone();
129
- new_pairs.remove(p.index);
130
- p.update_pairs.emit(new_pairs);
131
- true
132
- },
133
- PairListItemMsg::UpdateKey(key) => {
134
- let next = p.pair.update_key(key);
135
- let mut new_pairs = p.pairs.clone();
136
- new_pairs[p.index] = next;
137
- p.update_pairs.emit(new_pairs);
138
- true
139
- },
140
- PairListItemMsg::UpdateValue(val) => {
141
- let next = p.pair.update_value(val);
142
- let mut new_pairs = p.pairs.clone();
143
- new_pairs[p.index] = next;
144
- p.update_pairs.emit(new_pairs);
145
- true
146
- },
147
- }
148
- }
149
-
150
- fn view(&self, ctx: &yew::Context<Self>) -> Html {
151
- let props = ctx.props();
152
- let on_remove = ctx.link().callback(|_| PairListItemMsg::Remove);
153
- let on_key_update = ctx.link().callback(|s| PairListItemMsg::UpdateKey(Some(s)));
154
- let on_value_update = ctx.link().callback(PairListItemMsg::UpdateValue);
155
-
156
- let remove_style =
157
- (ctx.props().index == ctx.props().pairs.len() - 1).then_some("visibility: hidden");
158
-
159
- html! {
160
- <li class="pairs-list-item">
161
- <RowSelector
162
- selected_row={props.pair.key.clone()}
163
- on_select={on_key_update.clone()}
164
- dropdown={props.row_dropdown.clone()}
165
- pairs={props.pairs.clone()}
166
- index={props.index}
167
- focused={props.focused}
168
- set_focused_index={props.set_focused_index.clone()}
169
- column_name={props.column_name.clone()}
170
- />
171
- <SymbolSelector
172
- index={props.index}
173
- callback={on_value_update}
174
- values={props.values.clone()}
175
- selected_value={props.pair.value.clone()}
176
- />
177
- <span
178
- class="toggle-mode is_column_active"
179
- style={remove_style}
180
- onclick={on_remove.clone()}
181
- />
182
- </li>
183
- }
184
- }
185
- }
@@ -0,0 +1,111 @@
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
+
13
+ use std::rc::Rc;
14
+
15
+ use yew::{Callback, Html, Properties, html};
16
+
17
+ use crate::components::column_settings_sidebar::style_tab::symbol::row_selector::RowSelector;
18
+ use crate::components::column_settings_sidebar::style_tab::symbol::symbol_selector::SymbolSelector;
19
+ use crate::config::SymbolKVPair;
20
+ use crate::custom_elements::FilterDropDownElement;
21
+
22
+ #[derive(Properties, PartialEq)]
23
+ pub struct PairsListItemProps {
24
+ pub pair: SymbolKVPair,
25
+ pub index: usize,
26
+ pub pairs: Vec<SymbolKVPair>,
27
+ pub update_pairs: Callback<Vec<SymbolKVPair>>,
28
+ pub row_dropdown: Rc<FilterDropDownElement>,
29
+ pub values: Rc<Vec<String>>,
30
+ pub focused: bool,
31
+ pub set_focused_index: Callback<Option<usize>>,
32
+ pub column_name: String,
33
+ }
34
+
35
+ pub enum PairListItemMsg {
36
+ Remove,
37
+ UpdateKey(Option<String>),
38
+ UpdateValue(String),
39
+ }
40
+
41
+ pub struct PairsListItem {}
42
+ impl yew::Component for PairsListItem {
43
+ type Message = PairListItemMsg;
44
+ type Properties = PairsListItemProps;
45
+
46
+ fn create(_ctx: &yew::Context<Self>) -> Self {
47
+ Self {}
48
+ }
49
+
50
+ fn update(&mut self, ctx: &yew::Context<Self>, msg: Self::Message) -> bool {
51
+ let p = ctx.props();
52
+ match msg {
53
+ PairListItemMsg::Remove => {
54
+ let mut new_pairs = p.pairs.clone();
55
+ new_pairs.remove(p.index);
56
+ p.update_pairs.emit(new_pairs);
57
+ true
58
+ },
59
+ PairListItemMsg::UpdateKey(key) => {
60
+ let next = p.pair.update_key(key);
61
+ let mut new_pairs = p.pairs.clone();
62
+ new_pairs[p.index] = next;
63
+ p.update_pairs.emit(new_pairs);
64
+ true
65
+ },
66
+ PairListItemMsg::UpdateValue(val) => {
67
+ let next = p.pair.update_value(val);
68
+ let mut new_pairs = p.pairs.clone();
69
+ new_pairs[p.index] = next;
70
+ p.update_pairs.emit(new_pairs);
71
+ true
72
+ },
73
+ }
74
+ }
75
+
76
+ fn view(&self, ctx: &yew::Context<Self>) -> Html {
77
+ let props = ctx.props();
78
+ let on_remove = ctx.link().callback(|_| PairListItemMsg::Remove);
79
+ let on_key_update = ctx.link().callback(|s| PairListItemMsg::UpdateKey(Some(s)));
80
+ let on_value_update = ctx.link().callback(PairListItemMsg::UpdateValue);
81
+
82
+ let remove_style =
83
+ (ctx.props().index == ctx.props().pairs.len() - 1).then_some("visibility: hidden");
84
+
85
+ html! {
86
+ <li class="pairs-list-item">
87
+ <RowSelector
88
+ selected_row={props.pair.key.clone()}
89
+ on_select={on_key_update.clone()}
90
+ dropdown={props.row_dropdown.clone()}
91
+ pairs={props.pairs.clone()}
92
+ index={props.index}
93
+ focused={props.focused}
94
+ set_focused_index={props.set_focused_index.clone()}
95
+ column_name={props.column_name.clone()}
96
+ />
97
+ <SymbolSelector
98
+ index={props.index}
99
+ callback={on_value_update}
100
+ values={props.values.clone()}
101
+ selected_value={props.pair.value.clone()}
102
+ />
103
+ <span
104
+ class="toggle-mode is_column_active"
105
+ style={remove_style}
106
+ onclick={on_remove.clone()}
107
+ />
108
+ </li>
109
+ }
110
+ }
111
+ }
@@ -11,8 +11,9 @@
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
13
  mod row_selector;
14
- mod symbol_config;
14
+
15
15
  mod symbol_pairs;
16
+ mod symbol_pairs_item;
16
17
  mod symbol_selector;
17
18
 
18
19
  use std::collections::HashMap;
@@ -21,10 +22,9 @@ use std::rc::Rc;
21
22
  use itertools::Itertools;
22
23
  use yew::{Callback, Html, Properties, html};
23
24
 
24
- use self::symbol_config::SymbolKVPair;
25
25
  use crate::components::column_settings_sidebar::style_tab::symbol::symbol_pairs::PairsList;
26
26
  use crate::components::style::LocalStyle;
27
- use crate::config::{ColumnConfigValueUpdate, KeyValueOpts};
27
+ use crate::config::{ColumnConfigValueUpdate, KeyValueOpts, SymbolKVPair};
28
28
  use crate::css;
29
29
  use crate::custom_elements::FilterDropDownElement;
30
30
  use crate::session::Session;