@perspective-dev/viewer 4.4.1 → 4.5.1

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 (227) hide show
  1. package/dist/cdn/perspective-viewer.js +1 -2
  2. package/dist/cdn/perspective-viewer.js.map +4 -4
  3. package/dist/css/botanical.css +1 -1
  4. package/dist/css/dracula.css +1 -1
  5. package/dist/css/gruvbox-dark.css +1 -1
  6. package/dist/css/gruvbox.css +1 -1
  7. package/dist/css/icons.css +1 -1
  8. package/dist/css/intl/de.css +1 -1
  9. package/dist/css/intl/es.css +1 -1
  10. package/dist/css/intl/fr.css +1 -1
  11. package/dist/css/intl/ja.css +1 -1
  12. package/dist/css/intl/pt.css +1 -1
  13. package/dist/css/intl/zh.css +1 -1
  14. package/dist/css/intl.css +1 -1
  15. package/dist/css/monokai.css +1 -1
  16. package/dist/css/phosphor.css +1 -1
  17. package/dist/css/pro-dark.css +1 -1
  18. package/dist/css/pro.css +1 -1
  19. package/dist/css/solarized-dark.css +1 -1
  20. package/dist/css/solarized.css +1 -1
  21. package/dist/css/themes.css +1 -1
  22. package/dist/css/vaporwave.css +1 -1
  23. package/dist/esm/bootstrap.d.ts +2 -1
  24. package/dist/esm/column-format.d.ts +51 -0
  25. package/dist/esm/extensions.d.ts +2 -0
  26. package/dist/esm/perspective-viewer.d.ts +3 -1
  27. package/dist/esm/perspective-viewer.inline.js +1 -2
  28. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  29. package/dist/esm/perspective-viewer.js +1 -2
  30. package/dist/esm/perspective-viewer.js.map +4 -4
  31. package/dist/esm/perspective-viewer.worker.d.ts +2 -0
  32. package/dist/esm/plugin.d.ts +16 -72
  33. package/dist/esm/ts-rs/ColumnSelectMode.d.ts +1 -0
  34. package/dist/esm/ts-rs/PluginStaticConfig.d.ts +77 -0
  35. package/dist/esm/ts-rs/ViewerConfig.d.ts +6 -3
  36. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +7 -4
  37. package/dist/wasm/perspective-viewer.d.ts +77 -18
  38. package/dist/wasm/perspective-viewer.js +302 -148
  39. package/dist/wasm/perspective-viewer.wasm +0 -0
  40. package/dist/wasm/perspective-viewer.wasm.d.ts +20 -15
  41. package/package.json +24 -2
  42. package/src/css/column-selector.css +3 -2
  43. package/src/css/column-settings-panel.css +44 -9
  44. package/src/css/column-style.css +35 -2
  45. package/src/css/containers/scroll-panel.css +2 -1
  46. package/src/css/containers/tabs.css +8 -52
  47. package/src/css/dom/checkbox.css +2 -6
  48. package/src/css/form/code-editor.css +1 -0
  49. package/src/css/form/debug.css +3 -10
  50. package/src/css/plugin-selector.css +33 -0
  51. package/src/css/plugin-settings-panel.css +99 -0
  52. package/src/css/viewer.css +143 -3
  53. package/src/rust/components/column_dropdown.rs +3 -1
  54. package/src/rust/components/column_selector/active_column.rs +16 -19
  55. package/src/rust/components/column_selector/config_selector.rs +20 -20
  56. package/src/rust/components/column_selector/filter_column.rs +14 -14
  57. package/src/rust/components/column_selector/inactive_column.rs +10 -15
  58. package/src/rust/components/column_selector/pivot_column.rs +7 -7
  59. package/src/rust/components/column_selector/sort_column.rs +7 -7
  60. package/src/rust/components/column_selector.rs +55 -37
  61. package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +15 -7
  62. package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +395 -0
  63. package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +15 -6
  64. package/src/rust/components/column_settings_sidebar/style_tab.rs +267 -136
  65. package/src/rust/components/column_settings_sidebar.rs +44 -49
  66. package/src/rust/components/containers/dragdrop_list.rs +32 -5
  67. package/src/rust/components/containers/mod.rs +0 -1
  68. package/src/rust/components/containers/scroll_panel.rs +21 -7
  69. package/src/rust/components/containers/sidebar.rs +8 -6
  70. package/src/rust/components/containers/split_panel.rs +3 -3
  71. package/src/rust/components/containers/tab_list.rs +3 -9
  72. package/src/rust/components/copy_dropdown.rs +2 -3
  73. package/src/rust/components/datetime_column_style.rs +19 -81
  74. package/src/rust/components/editable_header.rs +17 -3
  75. package/src/rust/components/export_dropdown.rs +2 -3
  76. package/src/rust/components/expression_editor.rs +29 -17
  77. package/src/rust/components/filter_dropdown.rs +2 -1
  78. package/src/rust/components/form/color_range_selector.rs +14 -7
  79. package/src/rust/components/form/debug.rs +47 -37
  80. package/src/rust/components/main_panel.rs +24 -65
  81. package/src/rust/components/mod.rs +2 -1
  82. package/src/rust/components/number_series_style.rs +161 -0
  83. package/src/rust/components/plugin_tab.rs +221 -0
  84. package/src/rust/components/settings_panel.rs +181 -59
  85. package/src/rust/components/status_bar.rs +141 -174
  86. package/src/rust/components/status_indicator.rs +15 -22
  87. package/src/rust/components/string_column_style.rs +20 -82
  88. package/src/rust/components/style_controls/number_string_format.rs +14 -30
  89. package/src/rust/components/viewer.rs +169 -132
  90. package/src/rust/config/column_config_schema.rs +195 -0
  91. package/src/rust/config/columns_config.rs +4 -97
  92. package/src/rust/config/datetime_column_style.rs +0 -5
  93. package/src/rust/config/mod.rs +8 -2
  94. package/src/rust/config/number_series_style.rs +79 -0
  95. package/src/rust/config/plugin_static_config.rs +144 -0
  96. package/src/rust/config/string_column_style.rs +0 -5
  97. package/src/rust/config/viewer_config.rs +5 -6
  98. package/src/rust/custom_elements/copy_dropdown.rs +30 -18
  99. package/src/rust/custom_elements/debug_plugin.rs +1 -3
  100. package/src/rust/custom_elements/export_dropdown.rs +26 -18
  101. package/src/rust/custom_elements/viewer.rs +62 -73
  102. package/src/rust/custom_events.rs +181 -224
  103. package/src/rust/js/plugin.rs +45 -117
  104. package/src/rust/lib.rs +34 -5
  105. package/src/rust/presentation/drag_helpers.rs +206 -0
  106. package/src/rust/presentation/props.rs +8 -0
  107. package/src/rust/presentation.rs +256 -41
  108. package/src/rust/{tasks → queries}/column_locator.rs +17 -73
  109. package/src/rust/queries/column_values.rs +59 -0
  110. package/src/rust/{tasks → queries}/columns_iter_set.rs +11 -18
  111. package/src/rust/queries/exports.rs +96 -0
  112. package/src/rust/queries/fetch_column_stats.rs +94 -0
  113. package/src/rust/queries/get_viewer_config.rs +54 -0
  114. package/src/rust/queries/mod.rs +44 -0
  115. package/src/rust/queries/plugin_column_styles.rs +101 -0
  116. package/src/rust/{engines.rs → queries/validate_expression.rs} +26 -15
  117. package/src/rust/renderer/activate.rs +1 -0
  118. package/src/rust/renderer/limits.rs +9 -4
  119. package/src/rust/renderer/plugin_store.rs +12 -0
  120. package/src/rust/renderer/props.rs +28 -3
  121. package/src/rust/renderer/registry.rs +40 -15
  122. package/src/rust/renderer.rs +703 -60
  123. package/src/rust/session/column_defaults_update.rs +20 -28
  124. package/src/rust/session/drag_drop_update.rs +10 -10
  125. package/src/rust/session/metadata.rs +31 -16
  126. package/src/rust/session/props.rs +15 -6
  127. package/src/rust/session/view_subscription.rs +10 -0
  128. package/src/rust/session.rs +109 -147
  129. package/src/rust/tasks/copy_export.rs +178 -158
  130. package/src/rust/tasks/{structural.rs → dismiss_render_warning.rs} +20 -40
  131. package/src/rust/tasks/edit_expression.rs +68 -88
  132. package/src/rust/tasks/eject.rs +25 -22
  133. package/src/rust/tasks/intersection_observer.rs +8 -21
  134. package/src/rust/tasks/mod.rs +19 -21
  135. package/src/rust/tasks/reset_all.rs +98 -0
  136. package/src/rust/tasks/resize_observer.rs +11 -33
  137. package/src/rust/tasks/restore_and_render.rs +128 -90
  138. package/src/rust/tasks/{get_viewer_config.rs → send_column_config.rs} +39 -35
  139. package/src/rust/tasks/send_plugin_config.rs +33 -33
  140. package/src/rust/tasks/update_and_render.rs +75 -49
  141. package/src/rust/{components/containers/trap_door_panel.rs → tasks/update_theme.rs} +34 -33
  142. package/src/rust/tasks/validate_expression.rs +61 -0
  143. package/src/rust/utils/browser/selection.rs +4 -4
  144. package/src/rust/utils/mod.rs +0 -63
  145. package/src/svg/checkbox-checked-icon.svg +1 -1
  146. package/src/svg/checkbox-unchecked-icon.svg +1 -1
  147. package/src/svg/mega-menu-icons-density.svg +23 -0
  148. package/src/svg/mega-menu-icons-map-density.svg +24 -0
  149. package/src/svg/mega-menu-icons-map-line.svg +19 -0
  150. package/src/themes/botanical.css +27 -53
  151. package/src/themes/defaults.css +24 -36
  152. package/src/themes/dracula.css +36 -54
  153. package/src/themes/gruvbox-dark.css +39 -59
  154. package/src/themes/gruvbox.css +16 -28
  155. package/src/themes/icons.css +5 -0
  156. package/src/themes/intl/de.css +43 -6
  157. package/src/themes/intl/es.css +43 -6
  158. package/src/themes/intl/fr.css +43 -6
  159. package/src/themes/intl/ja.css +43 -6
  160. package/src/themes/intl/pt.css +43 -6
  161. package/src/themes/intl/zh.css +43 -6
  162. package/src/themes/intl.css +38 -4
  163. package/src/themes/monokai.css +45 -61
  164. package/src/themes/phosphor.css +20 -29
  165. package/src/themes/pro-dark.css +25 -34
  166. package/src/themes/solarized-dark.css +21 -36
  167. package/src/themes/solarized.css +13 -23
  168. package/src/themes/vaporwave.css +40 -74
  169. package/src/ts/bootstrap.ts +14 -3
  170. package/src/ts/column-format.ts +162 -0
  171. package/src/ts/extensions.ts +4 -0
  172. package/src/ts/perspective-viewer.ts +9 -1
  173. package/src/{rust/components/column_settings_sidebar/style_tab/stub.rs → ts/perspective-viewer.worker.ts} +2 -22
  174. package/src/ts/plugin.ts +25 -101
  175. package/src/ts/ts-rs/{FormatUnit.ts → ColumnSelectMode.ts} +1 -1
  176. package/src/ts/ts-rs/PluginStaticConfig.ts +78 -0
  177. package/src/ts/ts-rs/ViewerConfig.ts +1 -2
  178. package/src/ts/ts-rs/ViewerConfigUpdate.ts +2 -3
  179. package/dist/esm/ts-rs/ColumnConfigValues.d.ts +0 -31
  180. package/dist/esm/ts-rs/CustomDatetimeFormat.d.ts +0 -1
  181. package/dist/esm/ts-rs/CustomDatetimeStyleConfig.d.ts +0 -15
  182. package/dist/esm/ts-rs/CustomNumberFormatConfig.d.ts +0 -18
  183. package/dist/esm/ts-rs/DatetimeColorMode.d.ts +0 -1
  184. package/dist/esm/ts-rs/DatetimeFormatType.d.ts +0 -6
  185. package/dist/esm/ts-rs/FormatMode.d.ts +0 -1
  186. package/dist/esm/ts-rs/FormatUnit.d.ts +0 -1
  187. package/dist/esm/ts-rs/NumberBackgroundMode.d.ts +0 -1
  188. package/dist/esm/ts-rs/NumberForegroundMode.d.ts +0 -1
  189. package/dist/esm/ts-rs/PluginConfig.d.ts +0 -2
  190. package/dist/esm/ts-rs/RoundingMode.d.ts +0 -1
  191. package/dist/esm/ts-rs/RoundingPriority.d.ts +0 -1
  192. package/dist/esm/ts-rs/SignDisplay.d.ts +0 -1
  193. package/dist/esm/ts-rs/SimpleDatetimeFormat.d.ts +0 -1
  194. package/dist/esm/ts-rs/SimpleDatetimeStyleConfig.d.ts +0 -6
  195. package/dist/esm/ts-rs/StringColorMode.d.ts +0 -1
  196. package/dist/esm/ts-rs/TrailingZeroDisplay.d.ts +0 -1
  197. package/dist/esm/ts-rs/UseGrouping.d.ts +0 -1
  198. package/src/rust/components/number_column_style.rs +0 -491
  199. package/src/rust/config/number_column_style.rs +0 -136
  200. package/src/rust/dragdrop.rs +0 -481
  201. package/src/rust/tasks/plugin_column_styles.rs +0 -98
  202. package/src/ts/ts-rs/ColumnConfigValues.ts +0 -14
  203. package/src/ts/ts-rs/CustomDatetimeFormat.ts +0 -3
  204. package/src/ts/ts-rs/CustomDatetimeStyleConfig.ts +0 -5
  205. package/src/ts/ts-rs/CustomNumberFormatConfig.ts +0 -8
  206. package/src/ts/ts-rs/DatetimeColorMode.ts +0 -3
  207. package/src/ts/ts-rs/DatetimeFormatType.ts +0 -8
  208. package/src/ts/ts-rs/FormatMode.ts +0 -3
  209. package/src/ts/ts-rs/NumberBackgroundMode.ts +0 -3
  210. package/src/ts/ts-rs/NumberForegroundMode.ts +0 -3
  211. package/src/ts/ts-rs/PluginConfig.ts +0 -4
  212. package/src/ts/ts-rs/RoundingMode.ts +0 -3
  213. package/src/ts/ts-rs/RoundingPriority.ts +0 -3
  214. package/src/ts/ts-rs/SignDisplay.ts +0 -3
  215. package/src/ts/ts-rs/SimpleDatetimeFormat.ts +0 -3
  216. package/src/ts/ts-rs/SimpleDatetimeStyleConfig.ts +0 -4
  217. package/src/ts/ts-rs/StringColorMode.ts +0 -3
  218. package/src/ts/ts-rs/TrailingZeroDisplay.ts +0 -3
  219. package/src/ts/ts-rs/UseGrouping.ts +0 -3
  220. /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-3cd58f0374935772}/inline0.js +0 -0
  221. /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-3cd58f0374935772}/inline1.js +0 -0
  222. /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-3cd58f0374935772}/inline2.js +0 -0
  223. /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-3cd58f0374935772}/inline3.js +0 -0
  224. /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-3cd58f0374935772}/inline4.js +0 -0
  225. /package/src/rust/{tasks → config}/export_method.rs +0 -0
  226. /package/src/rust/{tasks → queries}/export_app.rs +0 -0
  227. /package/src/rust/{tasks → queries}/is_invalid_drop.rs +0 -0
@@ -16,10 +16,88 @@
16
16
  --psp--color: #ff0000;
17
17
  }
18
18
 
19
+ /* Shift-key affordance: while the user holds Shift, any mask-image icon
20
+ * tagged `.shift-alt-icon` recolors to advertise that a Shift-modified
21
+ * action is available on the underlying control. `!important` is required
22
+ * to beat per-icon ID-scoped `background-color` rules. */
23
+ :host(.shift-active) .shift-alt-icon {
24
+ background-color: var(
25
+ --shift-active--color,
26
+ var(--psp-datagrid--pos-cell--color, #1078d1)
27
+ ) !important;
28
+ }
29
+
30
+ :host(.shift-active) {
31
+ #sub-columns {
32
+ .is_column_active.toggle-mode {
33
+ -webkit-mask-image: var(--psp-icon--radio-off--mask-image);
34
+ mask-image: var(--psp-icon--radio-off--mask-image);
35
+
36
+ &:before {
37
+ content: var(--psp-icon--radio-off--mask-image);
38
+ }
39
+
40
+ &:hover {
41
+ -webkit-mask-image: var(--psp-icon--radio-hover--mask-image);
42
+ mask-image: var(--psp-icon--radio-hover--mask-image);
43
+ }
44
+ }
45
+
46
+ .is_column_active.select-mode {
47
+ -webkit-mask-image: var(--psp-icon--checkbox-off--mask-image);
48
+ mask-image: var(--psp-icon--checkbox-off--mask-image);
49
+
50
+ &:before {
51
+ content: var(--psp-icon--checkbox-off--mask-image);
52
+ }
53
+
54
+ &:hover {
55
+ -webkit-mask-image: var(--psp-icon--checkbox-hover--mask-image);
56
+ mask-image: var(--psp-icon--checkbox-hover--mask-image);
57
+ }
58
+ }
59
+ }
60
+
61
+ #active-columns {
62
+ .is_column_active.toggle-mode {
63
+ -webkit-mask-image: var(--psp-icon--radio-on--mask-image);
64
+ mask-image: var(--psp-icon--radio-on--mask-image);
65
+
66
+ &:before {
67
+ content: var(--psp-icon--radio-on--mask-image);
68
+ }
69
+
70
+ &:not(.required):hover {
71
+ -webkit-mask-image: var(--psp-icon--radio-hover--mask-image);
72
+ mask-image: var(--psp-icon--radio-hover--mask-image);
73
+ }
74
+ }
75
+
76
+ .is_column_active.select-mode {
77
+ -webkit-mask-image: var(--psp-icon--checkbox-on--mask-image);
78
+ mask-image: var(--psp-icon--checkbox-on--mask-image);
79
+
80
+ &:before {
81
+ content: var(--psp-icon--checkbox-on--mask-image);
82
+ }
83
+
84
+ &:not(.required):hover {
85
+ -webkit-mask-image: var(--psp-icon--checkbox-hover--mask-image);
86
+ mask-image: var(--psp-icon--checkbox-hover--mask-image);
87
+ }
88
+ }
89
+ }
90
+ }
91
+
19
92
  ::slotted(*) {
20
93
  pointer-events: var(--override-content-pointer-events);
21
94
  }
22
95
 
96
+ :host input[type="number"]::-webkit-inner-spin-button {
97
+ transform: scale(1.5); /* Makes the arrows 50% larger */
98
+ filter: invert(1);
99
+ }
100
+
23
101
  :host .sidebar_close_button {
24
102
  position: absolute;
25
103
  top: 0;
@@ -380,15 +458,57 @@
380
458
  }
381
459
  }
382
460
 
461
+ .settings_tab_bar_scroll_offset {
462
+ margin-left: -8px;
463
+ }
464
+
465
+ #settings_tab_bar {
466
+ display: flex;
467
+ &:after {
468
+ content: " ";
469
+ border-bottom: 1px solid var(--psp-inactive--color);
470
+ background-color: #00000020;
471
+ flex: 1 0 auto;
472
+ }
473
+
474
+ .settings_tab {
475
+ border-right: 1px solid var(--psp-inactive--color);
476
+ cursor: pointer;
477
+ padding: 6px 8px;
478
+ font-size: var(--label--font-size, 0.75em);
479
+ text-transform: uppercase;
480
+ flex: 0 1 100px;
481
+ background-color: #00000020;
482
+ border-bottom: 1px solid var(--psp-inactive--color);
483
+ color: var(--psp-inactive--color);
484
+ margin-left: -1px;
485
+ border-left: 1px solid var(--psp-inactive--color);
486
+ &:hover {
487
+ color: inherit;
488
+ }
489
+ }
490
+
491
+ .selected_tab {
492
+ color: inherit;
493
+ background-color: transparent;
494
+ border-bottom: 1px solid transparent;
495
+ box-shadow: 0px 9px 0px -8px var(--psp-inactive--color);
496
+ height: calc(100% - 1px);
497
+ }
498
+ }
499
+
383
500
  .split-panel.orient-reverse
384
501
  > .split-panel-child:not(:last-child):not(.is-width-override) {
385
502
  max-width: 300px;
386
503
  }
387
504
 
388
505
  .sidebar_header {
389
- min-height: var(
390
- --psp-plugin-selector--height,
391
- var(--psp-status-bar--height, 48px)
506
+ min-height: calc(
507
+ var(
508
+ --psp-plugin-selector--height,
509
+ var(--psp-status-bar--height, 48px)
510
+ ) +
511
+ 1px
392
512
  );
393
513
  overflow: hidden;
394
514
  display: flex;
@@ -413,4 +533,24 @@
413
533
  flex-shrink: 0;
414
534
  flex-grow: 0;
415
535
  }
536
+
537
+ #query_tabbar_tab:before {
538
+ content: var(--psp-label--query-tab--content);
539
+ }
540
+
541
+ #plugin_tabbar_tab:before {
542
+ content: var(--psp-label--plugin-tab--content);
543
+ }
544
+
545
+ #debug_tabbar_tab:before {
546
+ content: var(--psp-label--debug-tab--content);
547
+ }
548
+
549
+ label#stack-label:before {
550
+ content: var(--psp-label--stack--content, "Stack");
551
+ }
552
+
553
+ label#alt_axis-label:before {
554
+ content: var(--psp-label--alt-axis--content, "Alt Axis");
555
+ }
416
556
  }
@@ -91,7 +91,9 @@ impl ColumnDropDownElement {
91
91
  let width = target.get_bounding_client_rect().width();
92
92
  ApiFuture::spawn(async move {
93
93
  if !exclude.contains(&input) {
94
- let is_expr = session.validate_expr(&input).await?.is_none();
94
+ let is_expr = crate::queries::validate_expr(&session, &input)
95
+ .await?
96
+ .is_none();
95
97
  if is_expr {
96
98
  values.push(InPlaceColumn::Expression(Expression::new(
97
99
  None,
@@ -23,12 +23,11 @@ use super::expr_edit_button::*;
23
23
  use crate::components::column_dropdown::ColumnDropDownElement;
24
24
  use crate::components::column_selector::{EmptyColumn, InvalidColumn};
25
25
  use crate::components::type_icon::TypeIcon;
26
- use crate::dragdrop::*;
27
- use crate::js::plugin::*;
28
- use crate::presentation::ColumnLocator;
26
+ use crate::config::ColumnSelectMode;
27
+ use crate::presentation::{ColumnLocator, Presentation};
28
+ use crate::queries::*;
29
29
  use crate::renderer::*;
30
30
  use crate::session::*;
31
- use crate::tasks::*;
32
31
  use crate::utils::*;
33
32
 
34
33
  #[derive(Clone, Properties)]
@@ -85,7 +84,7 @@ pub struct ActiveColumnProps {
85
84
 
86
85
  /// State
87
86
  pub session: Session,
88
- pub dragdrop: DragDrop,
87
+ pub presentation: Presentation,
89
88
  pub renderer: Renderer,
90
89
  }
91
90
 
@@ -232,7 +231,7 @@ impl Component for ActiveColumn {
232
231
 
233
232
  (
234
233
  label.clone(),
235
- ColumnState::Named(ctx.props().dragdrop.get_drag_column().unwrap()),
234
+ ColumnState::Named(ctx.props().presentation.get_drag_column().unwrap()),
236
235
  )
237
236
  },
238
237
  ActiveColumnState {
@@ -333,10 +332,10 @@ impl Component for ActiveColumn {
333
332
  let ondragend = &ctx.props().ondragend.reform(|_| ());
334
333
  let ondragstart = ctx.link().callback({
335
334
  let event_name = name.to_owned();
336
- let dragdrop = ctx.props().dragdrop.clone();
335
+ let presentation = ctx.props().presentation.clone();
337
336
  move |event: DragEvent| {
338
- dragdrop.set_drag_image(&event).unwrap();
339
- dragdrop.notify_drag_start(
337
+ presentation.set_drag_image(&event).unwrap();
338
+ presentation.notify_drag_start(
340
339
  event_name.to_string(),
341
340
  DragEffect::Move(DragTarget::Active),
342
341
  );
@@ -352,10 +351,13 @@ impl Component for ActiveColumn {
352
351
 
353
352
  let is_expression = ctx.props().is_expression;
354
353
  let show_edit_btn = ctx.props().show_edit_btn;
355
- let mut class = ctx.props().renderer.metadata().mode.css();
354
+ let mut class = ctx.props().renderer.metadata().select_mode.css();
356
355
  if is_required {
357
356
  class.push("required");
358
357
  };
358
+ if !is_required {
359
+ class.push("shift-alt-icon");
360
+ }
359
361
  html! {
360
362
  <div
361
363
  class={outer_classes}
@@ -435,14 +437,9 @@ impl ActiveColumnProps {
435
437
  /// - `shift` whether to toggle or select this column.
436
438
  fn deactivate_column(&self, name: String, shift: bool) {
437
439
  let mut columns = self.view_config.columns.clone();
438
- let max_cols = self
439
- .renderer
440
- .metadata()
441
- .names
442
- .as_ref()
443
- .map_or(0, |x| x.len());
444
-
445
- match self.renderer.metadata().mode {
440
+ let max_cols = self.renderer.metadata().config_column_names.len();
441
+
442
+ match self.renderer.metadata().select_mode {
446
443
  ColumnSelectMode::Toggle => {
447
444
  let index = columns
448
445
  .iter()
@@ -466,7 +463,7 @@ impl ActiveColumnProps {
466
463
  }
467
464
 
468
465
  fn get_is_required(&self, idx: usize) -> bool {
469
- let min_cols = self.renderer.metadata().min.unwrap_or(0);
466
+ let min_cols = self.renderer.metadata().min_config_columns.unwrap_or(0);
470
467
  idx < min_cols
471
468
  }
472
469
 
@@ -27,7 +27,7 @@ use crate::components::containers::select::{Select, SelectItem};
27
27
  use crate::components::filter_dropdown::{FilterDropDownElement, FilterDropDownPortal};
28
28
  use crate::components::style::LocalStyle;
29
29
  use crate::css;
30
- use crate::dragdrop::*;
30
+ use crate::presentation::Presentation;
31
31
  use crate::renderer::*;
32
32
  use crate::session::drag_drop_update::*;
33
33
  use crate::session::*;
@@ -56,7 +56,7 @@ pub struct ConfigSelectorProps {
56
56
  // State
57
57
  pub session: Session,
58
58
  pub renderer: Renderer,
59
- pub dragdrop: DragDrop,
59
+ pub presentation: Presentation,
60
60
  }
61
61
 
62
62
  impl PartialEq for ConfigSelectorProps {
@@ -97,7 +97,7 @@ impl Component for ConfigSelector {
97
97
  .callback(|x: (String, DragTarget, DragEffect, usize)| {
98
98
  ConfigSelectorMsg::Drop(x.0, x.1, x.2, x.3)
99
99
  });
100
- let drop_sub = Rc::new(ctx.props().dragdrop.drop_received.add_listener(cb));
100
+ let drop_sub = Rc::new(ctx.props().presentation.drop_received.add_listener(cb));
101
101
 
102
102
  let filter_dropdown = FilterDropDownElement::new(ctx.props().session.clone());
103
103
  let column_dropdown = ColumnDropDownElement::new(ctx.props().session.clone());
@@ -112,14 +112,14 @@ impl Component for ConfigSelector {
112
112
  fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
113
113
  match msg {
114
114
  ConfigSelectorMsg::DragOver(index, action) => {
115
- let should_render = ctx.props().dragdrop.notify_drag_enter(action, index);
115
+ let should_render = ctx.props().presentation.notify_drag_enter(action, index);
116
116
  if should_render {
117
117
  ctx.props().ondragenter.emit(());
118
118
  }
119
119
  should_render
120
120
  },
121
121
  ConfigSelectorMsg::DragLeave(action) => {
122
- ctx.props().dragdrop.notify_drag_leave(action);
122
+ ctx.props().presentation.notify_drag_leave(action);
123
123
  true
124
124
  },
125
125
  ConfigSelectorMsg::Close(index, DragTarget::Sort) => {
@@ -569,7 +569,7 @@ impl Component for ConfigSelector {
569
569
 
570
570
  fn view(&self, ctx: &Context<Self>) -> Html {
571
571
  let ConfigSelectorProps {
572
- dragdrop,
572
+ presentation,
573
573
  renderer,
574
574
  session,
575
575
  ..
@@ -588,8 +588,8 @@ impl Component for ConfigSelector {
588
588
  }
589
589
 
590
590
  let dragend = Callback::from({
591
- let dragdrop = dragdrop.clone();
592
- move |_event| dragdrop.notify_drag_end()
591
+ let presentation = presentation.clone();
592
+ move |_event| presentation.notify_drag_end()
593
593
  });
594
594
 
595
595
  let metadata = &ctx.props().metadata;
@@ -642,8 +642,8 @@ impl Component for ConfigSelector {
642
642
  parent={ctx.link().clone()}
643
643
  column_dropdown={column_dropdown.clone()}
644
644
  exclude={config.group_by.iter().cloned().collect::<HashSet<_>>()}
645
- is_dragover={ctx.props().dragdrop.is_dragover(DragTarget::GroupBy)}
646
- {dragdrop}
645
+ is_dragover={ctx.props().presentation.is_dragover(DragTarget::GroupBy)}
646
+ {presentation}
647
647
  >
648
648
  { for config.group_by.iter().map(|group_by| {
649
649
  html_nested! {
@@ -651,7 +651,7 @@ impl Component for ConfigSelector {
651
651
  action={DragTarget::GroupBy}
652
652
  column={group_by.clone()}
653
653
  metadata={metadata.clone()}
654
- {dragdrop}
654
+ {presentation}
655
655
  opt_session={session}
656
656
  >
657
657
  </PivotColumn>
@@ -675,8 +675,8 @@ impl Component for ConfigSelector {
675
675
  parent={ctx.link().clone()}
676
676
  column_dropdown={column_dropdown.clone()}
677
677
  exclude={config.split_by.iter().cloned().collect::<HashSet<_>>()}
678
- is_dragover={dragdrop.is_dragover(DragTarget::SplitBy)}
679
- {dragdrop}
678
+ is_dragover={presentation.is_dragover(DragTarget::SplitBy)}
679
+ {presentation}
680
680
  >
681
681
  { for config.split_by.iter().map(|split_by| {
682
682
  html_nested! {
@@ -684,7 +684,7 @@ impl Component for ConfigSelector {
684
684
  action={ DragTarget::SplitBy }
685
685
  column={ split_by.clone() }
686
686
  metadata={metadata.clone()}
687
- {dragdrop}
687
+ {presentation}
688
688
  opt_session={session}>
689
689
  </PivotColumn>
690
690
  }
@@ -698,10 +698,10 @@ impl Component for ConfigSelector {
698
698
  parent={ctx.link().clone()}
699
699
  column_dropdown={column_dropdown.clone()}
700
700
  exclude={config.sort.iter().map(|x| x.0.clone()).collect::<HashSet<_>>()}
701
- is_dragover={dragdrop.is_dragover(DragTarget::Sort).map(|(index, name)| {
701
+ is_dragover={presentation.is_dragover(DragTarget::Sort).map(|(index, name)| {
702
702
  (index, Sort(name, SortDir::Asc))
703
703
  })}
704
- {dragdrop}
704
+ {presentation}
705
705
  >
706
706
  { for config.sort.iter().enumerate().map(|(idx, sort)| {
707
707
  html_nested! {
@@ -710,7 +710,7 @@ impl Component for ConfigSelector {
710
710
  sort={ sort.clone() }
711
711
  view_config={config.clone()}
712
712
  metadata={metadata.clone()}
713
- {dragdrop}
713
+ {presentation}
714
714
  {renderer}
715
715
  {session}>
716
716
  </SortColumn>
@@ -725,10 +725,10 @@ impl Component for ConfigSelector {
725
725
  parent={ctx.link().clone()}
726
726
  {column_dropdown}
727
727
  exclude={config.filter.iter().map(|x| x.column().to_string()).collect::<HashSet<_>>()}
728
- is_dragover={dragdrop.is_dragover(DragTarget::Filter).map(|(index, name)| {
728
+ is_dragover={presentation.is_dragover(DragTarget::Filter).map(|(index, name)| {
729
729
  (index, Filter::new(&name, "", FilterTerm::Scalar(Scalar::Null)))
730
730
  })}
731
- {dragdrop}
731
+ {presentation}
732
732
  >
733
733
  { for config.filter.iter().enumerate().map(|(idx, filter)| {
734
734
  let filter_keydown = ctx.link()
@@ -742,7 +742,7 @@ impl Component for ConfigSelector {
742
742
  on_keydown={ filter_keydown }
743
743
  view_config={config.clone()}
744
744
  metadata={metadata.clone()}
745
- {dragdrop}
745
+ {presentation}
746
746
  {renderer}
747
747
  {session}>
748
748
  </FilterColumn>
@@ -25,11 +25,11 @@ use crate::components::containers::select::*;
25
25
  use crate::components::filter_dropdown::FilterDropDownElement;
26
26
  use crate::components::style::LocalStyle;
27
27
  use crate::components::type_icon::TypeIcon;
28
- use crate::dragdrop::*;
28
+ use crate::css;
29
+ use crate::presentation::Presentation;
29
30
  use crate::renderer::*;
30
31
  use crate::session::*;
31
32
  use crate::utils::*;
32
- use crate::{css, maybe};
33
33
 
34
34
  #[derive(Clone, Properties)]
35
35
  pub struct FilterColumnProps {
@@ -46,7 +46,7 @@ pub struct FilterColumnProps {
46
46
  // State
47
47
  pub session: Session,
48
48
  pub renderer: Renderer,
49
- pub dragdrop: DragDrop,
49
+ pub presentation: Presentation,
50
50
  }
51
51
 
52
52
  impl PartialEq for FilterColumnProps {
@@ -101,11 +101,11 @@ impl Component for FilterColumn {
101
101
  .unwrap_or_else(|| "".to_owned());
102
102
 
103
103
  this.filter_ops = Rc::new(
104
- maybe! {
105
- Some(get_filter_ops(&ctx.props().metadata, col_type?)?
104
+ try {
105
+ get_filter_ops(&ctx.props().metadata, col_type?)?
106
106
  .into_iter()
107
107
  .map(SelectItem::Option)
108
- .collect::<Vec<_>>())
108
+ .collect::<Vec<_>>()
109
109
  }
110
110
  .unwrap_or_default(),
111
111
  );
@@ -189,11 +189,11 @@ impl Component for FilterColumn {
189
189
  if col_type != old_col_type {
190
190
  changed = true;
191
191
  self.filter_ops = Rc::new(
192
- maybe! {
193
- Some(get_filter_ops(&ctx.props().metadata, col_type?)?
192
+ try {
193
+ get_filter_ops(&ctx.props().metadata, col_type?)?
194
194
  .into_iter()
195
195
  .map(SelectItem::Option)
196
- .collect::<Vec<_>>())
196
+ .collect::<Vec<_>>()
197
197
  }
198
198
  .unwrap_or_default(),
199
199
  );
@@ -240,17 +240,17 @@ impl Component for FilterColumn {
240
240
 
241
241
  let dragstart = Callback::from({
242
242
  let event_name = ctx.props().filter.column().to_owned();
243
- let dragdrop = ctx.props().dragdrop.clone();
243
+ let presentation = ctx.props().presentation.clone();
244
244
  move |event: DragEvent| {
245
- dragdrop.set_drag_image(&event).unwrap();
246
- dragdrop
245
+ presentation.set_drag_image(&event).unwrap();
246
+ presentation
247
247
  .notify_drag_start(event_name.to_string(), DragEffect::Move(DragTarget::Filter))
248
248
  }
249
249
  });
250
250
 
251
251
  let dragend = Callback::from({
252
- let dragdrop = ctx.props().dragdrop.clone();
253
- move |_event| dragdrop.notify_drag_end()
252
+ let presentation = ctx.props().presentation.clone();
253
+ move |_event| presentation.notify_drag_end()
254
254
  });
255
255
 
256
256
  let type_class = match col_type {
@@ -18,9 +18,8 @@ use yew::prelude::*;
18
18
 
19
19
  use super::expr_edit_button::*;
20
20
  use crate::components::type_icon::TypeIcon;
21
- use crate::dragdrop::*;
22
- use crate::js::plugin::*;
23
- use crate::presentation::ColumnLocator;
21
+ use crate::config::ColumnSelectMode;
22
+ use crate::presentation::{ColumnLocator, Presentation};
24
23
  use crate::renderer::*;
25
24
  use crate::session::*;
26
25
  use crate::utils::*;
@@ -61,7 +60,7 @@ pub struct InactiveColumnProps {
61
60
  pub on_open_expr_panel: Callback<ColumnLocator>,
62
61
 
63
62
  // State
64
- pub dragdrop: DragDrop,
63
+ pub presentation: Presentation,
65
64
  pub session: Session,
66
65
  pub renderer: Renderer,
67
66
  }
@@ -135,10 +134,10 @@ impl Component for InactiveColumn {
135
134
  let ondragend = ctx.props().ondragend.reform(|_| {});
136
135
  let ondragstart = ctx.link().callback({
137
136
  let event_name = ctx.props().name.to_owned();
138
- let dragdrop = ctx.props().dragdrop.clone();
137
+ let presentation = ctx.props().presentation.clone();
139
138
  move |event: DragEvent| {
140
- dragdrop.set_drag_image(&event).unwrap();
141
- dragdrop.notify_drag_start(event_name.to_string(), DragEffect::Copy);
139
+ presentation.set_drag_image(&event).unwrap();
140
+ presentation.notify_drag_start(event_name.to_string(), DragEffect::Copy);
142
141
  MouseLeave(true)
143
142
  }
144
143
  });
@@ -150,7 +149,8 @@ impl Component for InactiveColumn {
150
149
 
151
150
  let is_expression = ctx.props().is_expression;
152
151
 
153
- let is_active_class = ctx.props().renderer.metadata().mode.css();
152
+ let mut is_active_class = ctx.props().renderer.metadata().select_mode.css();
153
+ is_active_class.push("shift-alt-icon");
154
154
  let mut class = classes!("column-selector-column");
155
155
  if !ctx.props().visible {
156
156
  class.push("column-selector-column-hidden");
@@ -199,19 +199,14 @@ impl InactiveColumnProps {
199
199
  /// - `shift` whether to toggle or select this column.
200
200
  pub fn activate_column(&self, name: String, shift: bool) {
201
201
  let mut columns = self.view_config.columns.clone();
202
- let max_cols = self
203
- .renderer
204
- .metadata()
205
- .names
206
- .as_ref()
207
- .map_or(0, |x| x.len());
202
+ let max_cols = self.renderer.metadata().config_column_names.len();
208
203
 
209
204
  // Don't treat `None` at the end of the column list as columns, we'll refill
210
205
  // these later
211
206
  if let Some(last_filled) = columns.iter().rposition(|x| !x.is_none()) {
212
207
  columns.truncate(last_filled + 1);
213
208
 
214
- let mode = self.renderer.metadata().mode;
209
+ let mode = self.renderer.metadata().select_mode;
215
210
  if (mode == ColumnSelectMode::Select) ^ shift {
216
211
  columns.clear();
217
212
  } else {
@@ -16,7 +16,7 @@ use yew::prelude::*;
16
16
 
17
17
  use crate::components::containers::dragdrop_list::*;
18
18
  use crate::components::type_icon::TypeIcon;
19
- use crate::dragdrop::*;
19
+ use crate::presentation::Presentation;
20
20
  use crate::session::*;
21
21
  use crate::utils::*;
22
22
 
@@ -38,7 +38,7 @@ pub struct PivotColumnProps {
38
38
  // State
39
39
  #[prop_or_default]
40
40
  pub opt_session: Option<Session>,
41
- pub dragdrop: DragDrop,
41
+ pub presentation: Presentation,
42
42
  }
43
43
 
44
44
  impl PartialEq for PivotColumnProps {
@@ -70,17 +70,17 @@ impl Component for PivotColumn {
70
70
  fn view(&self, ctx: &Context<Self>) -> Html {
71
71
  let dragstart = Callback::from({
72
72
  let event_name = ctx.props().column.to_owned();
73
- let dragdrop = ctx.props().dragdrop.clone();
73
+ let presentation = ctx.props().presentation.clone();
74
74
  let action = ctx.props().action;
75
75
  move |event: DragEvent| {
76
- dragdrop.set_drag_image(&event).unwrap();
77
- dragdrop.notify_drag_start(event_name.to_string(), DragEffect::Move(action))
76
+ presentation.set_drag_image(&event).unwrap();
77
+ presentation.notify_drag_start(event_name.to_string(), DragEffect::Move(action))
78
78
  }
79
79
  });
80
80
 
81
81
  let dragend = Callback::from({
82
- let dragdrop = ctx.props().dragdrop.clone();
83
- move |_event| dragdrop.notify_drag_end()
82
+ let presentation = ctx.props().presentation.clone();
83
+ move |_event| presentation.notify_drag_end()
84
84
  });
85
85
 
86
86
  let col_type = ctx.props().column_type.unwrap_or_else(|| {
@@ -17,7 +17,7 @@ use yew::prelude::*;
17
17
 
18
18
  use crate::components::containers::dragdrop_list::*;
19
19
  use crate::components::type_icon::TypeIcon;
20
- use crate::dragdrop::*;
20
+ use crate::presentation::Presentation;
21
21
  use crate::renderer::*;
22
22
  use crate::session::*;
23
23
  use crate::utils::*;
@@ -36,7 +36,7 @@ pub struct SortColumnProps {
36
36
  // State
37
37
  pub session: Session,
38
38
  pub renderer: Renderer,
39
- pub dragdrop: DragDrop,
39
+ pub presentation: Presentation,
40
40
  }
41
41
 
42
42
  impl PartialEq for SortColumnProps {
@@ -105,17 +105,17 @@ impl Component for SortColumn {
105
105
 
106
106
  let dragstart = Callback::from({
107
107
  let event_name = ctx.props().sort.0.to_owned();
108
- let dragdrop = ctx.props().dragdrop.clone();
108
+ let presentation = ctx.props().presentation.clone();
109
109
  move |event: DragEvent| {
110
- dragdrop.set_drag_image(&event).unwrap();
111
- dragdrop
110
+ presentation.set_drag_image(&event).unwrap();
111
+ presentation
112
112
  .notify_drag_start(event_name.to_string(), DragEffect::Move(DragTarget::Sort))
113
113
  }
114
114
  });
115
115
 
116
116
  let dragend = Callback::from({
117
- let dragdrop = ctx.props().dragdrop.clone();
118
- move |_event| dragdrop.notify_drag_end()
117
+ let presentation = ctx.props().presentation.clone();
118
+ move |_event| presentation.notify_drag_end()
119
119
  });
120
120
 
121
121
  let col_type = ctx