@perspective-dev/viewer 4.0.1 → 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 (183) 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 +1250 -761
  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/get_viewer_config.rs +4 -28
  126. package/src/rust/model/intersection_observer.rs +20 -8
  127. package/src/rust/model/mod.rs +11 -4
  128. package/src/rust/model/plugin_column_styles.rs +0 -31
  129. package/src/rust/model/reset_all.rs +38 -0
  130. package/src/rust/model/resize_observer.rs +34 -7
  131. package/src/rust/model/restore_and_render.rs +12 -7
  132. package/src/rust/{utils/scope.rs → model/send_plugin_config.rs} +32 -35
  133. package/src/rust/model/structural.rs +194 -23
  134. package/src/rust/model/update_and_render.rs +14 -4
  135. package/src/rust/{model/create_col.rs → presentation/column_locator.rs} +73 -42
  136. package/src/rust/{utils/wasm_abi.rs → presentation/sheets.rs} +54 -40
  137. package/src/rust/presentation.rs +60 -119
  138. package/src/rust/renderer/activate.rs +20 -5
  139. package/src/rust/renderer/limits.rs +0 -149
  140. package/src/rust/renderer/render_timer.rs +1 -1
  141. package/src/rust/renderer.rs +34 -18
  142. package/src/rust/root.rs +50 -0
  143. package/src/rust/session/column_defaults_update.rs +4 -4
  144. package/src/rust/session/drag_drop_update.rs +1 -1
  145. package/src/rust/session/metadata.rs +3 -17
  146. package/src/rust/session/replace_expression_update.rs +1 -2
  147. package/src/rust/session.rs +162 -82
  148. package/src/rust/utils/browser/blob.rs +16 -2
  149. package/src/rust/utils/browser/download.rs +1 -0
  150. package/src/rust/{components/column_settings_sidebar/mod.rs → utils/browser/dragdrop.rs} +14 -5
  151. package/src/rust/utils/browser/mod.rs +8 -4
  152. package/src/rust/utils/browser/selection.rs +5 -0
  153. package/src/rust/utils/custom_element.rs +28 -13
  154. package/src/rust/utils/datetime.rs +5 -0
  155. package/src/rust/utils/debounce.rs +7 -1
  156. package/src/rust/utils/hooks/use_async_callback.rs +7 -17
  157. package/src/rust/utils/mod.rs +28 -40
  158. package/src/rust/utils/number_format.rs +6 -5
  159. package/src/rust/utils/pubsub.rs +15 -10
  160. package/src/rust/utils/weak_scope.rs +11 -1
  161. package/src/svg/bookmark-icon.svg +4 -0
  162. package/src/svg/drag-handle copy.svg +10 -0
  163. package/src/svg/drawer-tab-hover.svg +5 -7
  164. package/src/svg/drawer-tab-invert-hover.svg +4 -8
  165. package/src/svg/drawer-tab-invert.svg +4 -7
  166. package/src/svg/drawer-tab.svg +4 -6
  167. package/src/svg/status_ok.svg +24 -24
  168. package/src/ts/extensions.ts +51 -3
  169. package/src/ts/perspective-viewer.ts +2 -14
  170. package/src/ts/plugin.ts +1 -1
  171. package/src/ts/ts-rs/ViewerConfigUpdate.ts +1 -1
  172. package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +0 -177
  173. package/src/rust/components/containers/tests/mod.rs +0 -11
  174. package/src/rust/components/containers/tests/split_panel.rs +0 -91
  175. package/src/rust/js/testing.rs +0 -149
  176. package/src/rust/utils/tee.rs +0 -88
  177. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline0.js +0 -0
  178. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline1.js +0 -0
  179. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline2.js +0 -0
  180. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline3.js +0 -0
  181. /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline4.js +0 -0
  182. /package/src/rust/components/{style_controls.rs → style_controls/mod.rs} +0 -0
  183. /package/src/rust/{components/containers → config}/kvpair.rs +0 -0
@@ -15,59 +15,230 @@
15
15
  //! `struct`s only if the define accessors for the necessary applications state
16
16
  //! objects (which are conviently derivable with the `derive_model!` macro).
17
17
 
18
+ use yew::Component;
19
+
20
+ use crate::custom_events::*;
18
21
  use crate::dragdrop::*;
19
22
  use crate::presentation::*;
20
23
  use crate::renderer::*;
24
+ use crate::root::*;
21
25
  use crate::session::*;
22
26
 
23
- pub trait HasSession {
24
- fn session(&self) -> &'_ Session;
27
+ pub trait HasCustomEvents {
28
+ fn custom_events(&self) -> &'_ CustomEvents;
25
29
  }
26
30
 
27
- pub trait HasRenderer {
28
- fn renderer(&self) -> &'_ Renderer;
31
+ pub trait HasDragDrop {
32
+ fn dragdrop(&self) -> &'_ DragDrop;
29
33
  }
30
34
 
31
35
  pub trait HasPresentation {
32
36
  fn presentation(&self) -> &'_ Presentation;
33
37
  }
34
38
 
35
- pub trait HasDragDrop {
36
- fn dragdrop(&self) -> &'_ DragDrop;
39
+ pub trait HasRoot {
40
+ /// Use an assoociated type to prevent a (circular) dependency on
41
+ /// [`crate::components`].
42
+ type RootComponent: Component;
43
+ fn root(&self) -> &'_ Root<Self::RootComponent>;
44
+ }
45
+
46
+ pub trait HasRenderer {
47
+ fn renderer(&self) -> &'_ Renderer;
48
+ }
49
+
50
+ pub trait HasSession {
51
+ fn session(&self) -> &'_ Session;
52
+ }
53
+
54
+ impl HasSession for Session {
55
+ fn session(&self) -> &'_ Session {
56
+ self
57
+ }
37
58
  }
38
59
 
39
60
  #[macro_export]
40
- macro_rules! derive_model {
41
- (DragDrop for $key:ty) => {
42
- impl $crate::model::HasDragDrop for $key {
43
- fn dragdrop(&self) -> &'_ DragDrop {
61
+ macro_rules! PerspectiveProperties {
62
+ // (impl @tuple $name:ident CustomEvents $x:tt) => {
63
+ // impl $crate::model::HasCustomEvents for $name {
64
+ // fn custom_events(&self) -> &'_ CustomEvents {
65
+ // &self.$x
66
+ // }
67
+ // }
68
+ // };
69
+
70
+ // (impl @tuple $name:ident DragDrop $x:tt) => {
71
+ // impl $crate::model::HasDragDrop for $name {
72
+ // fn dragdrop(&self) -> &'_ DragDrop {
73
+ // &self.$x
74
+ // }
75
+ // }
76
+ // };
77
+
78
+ // (impl @tuple $name:ident Presentatio $x:tt) => {
79
+ // impl $crate::model::HasPresentation for $name {
80
+ // fn presentation(&self) -> &'_ Presentation {
81
+ // &self.$x
82
+ // }
83
+ // }
84
+ // };
85
+
86
+ // (impl @tuple $name:ident Renderer $x:tt) => {
87
+ // impl $crate::model::HasRenderer for $name {
88
+ // fn renderer(&self) -> &'_ Renderer {
89
+ // &self.$x
90
+ // }
91
+ // }
92
+ // };
93
+
94
+ // (impl @tuple $name:ident Root $x:tt) => {
95
+ // impl $crate::model::HasRoot for $name {
96
+ // type RootComponent = $crate::components::viewer::PerspectiveViewer;
97
+ // fn root(&self) -> &'_ Root<Self::RootComponent> {
98
+ // &self.$x
99
+ // }
100
+ // }
101
+ // };
102
+
103
+ // (impl @tuple $name:ident Session $x:tt) => {
104
+ // impl $crate::model::HasSession for $name {
105
+ // fn session(&self) -> &'_ Session {
106
+ // &self.$x
107
+ // }
108
+ // }
109
+ // };
110
+
111
+ // (impl @tuple $name:ident *_x:tt $x:tt) => {};
112
+
113
+ (impl @field $name:ident custom_events $value:ty) => {
114
+ impl $crate::model::HasCustomEvents for $name {
115
+ fn custom_events(&self) -> &'_ $value {
116
+ &self.custom_events
117
+ }
118
+ }
119
+ };
120
+
121
+ (impl @field $name:ident dragdrop $value:ty) => {
122
+ impl $crate::model::HasDragDrop for $name {
123
+ fn dragdrop(&self) -> &'_ $value {
44
124
  &self.dragdrop
45
125
  }
46
126
  }
47
127
  };
48
- (Renderer for $key:ty) => {
49
- impl $crate::model::HasRenderer for $key {
50
- fn renderer(&self) -> &'_ Renderer {
128
+
129
+ (impl @field $name:ident presentation $value:ty) => {
130
+ impl $crate::model::HasPresentation for $name {
131
+ fn presentation(&self) -> &'_ $value {
132
+ &self.presentation
133
+ }
134
+ }
135
+ };
136
+
137
+ (impl @field $name:ident renderer $value:ty) => {
138
+ impl $crate::model::HasRenderer for $name {
139
+ fn renderer(&self) -> &'_ $value {
51
140
  &self.renderer
52
141
  }
53
142
  }
54
143
  };
55
- (Session for $key:ty) => {
56
- impl $crate::model::HasSession for $key {
57
- fn session(&self) -> &'_ Session {
144
+
145
+ (impl @field $name:ident root $value:ty) => {
146
+ impl $crate::model::HasRoot for $name {
147
+ type RootComponent = $crate::components::viewer::PerspectiveViewer;
148
+ fn root(&self) -> &'_ $value {
149
+ &self.root
150
+ }
151
+ }
152
+ };
153
+
154
+ (impl @field $name:ident session $value:ty) => {
155
+ impl $crate::model::HasSession for $name {
156
+ fn session(&self) -> &'_ $value {
58
157
  &self.session
59
158
  }
60
159
  }
61
160
  };
62
- (Presentation for $key:ty) => {
63
- impl $crate::model::HasPresentation for $key {
64
- fn presentation(&self) -> &'_ Presentation {
65
- &self.presentation
161
+
162
+ (impl @field $name:ident $x:ident $value:ty) => {};
163
+
164
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*} custom_events, $($field:ident,)*) => {
165
+ PerspectiveProperties!(impl @fields_provider $name { custom_events : CustomEvents, $($x : $y,)*} $($field,)*);
166
+ };
167
+
168
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*} dragdrop, $($field:ident,)*) => {
169
+ PerspectiveProperties!(impl @fields_provider $name { dragdrop : DragDrop, $($x : $y,)*} $($field,)*);
170
+ };
171
+
172
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*} presentation, $($field:ident,)*) => {
173
+ PerspectiveProperties!(impl @fields_provider $name { presentation : Presentation, $($x : $y,)*} $($field,)*);
174
+ };
175
+
176
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*} renderer, $($field:ident,)*) => {
177
+ PerspectiveProperties!(impl @fields_provider $name { renderer : Renderer, $($x : $y,)*} $($field,)*);
178
+ };
179
+
180
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*} root, $($field:ident,)*) => {
181
+ PerspectiveProperties!(impl @fields_provider $name { root : Root<$crate::components::viewer::PerspectiveViewer>, $($x : $y,)*} $($field,)*);
182
+ };
183
+
184
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*} session, $($field:ident,)*) => {
185
+ PerspectiveProperties!(impl @fields_provider $name { session : Session, $($x : $y,)*} $($field,)*);
186
+ };
187
+
188
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*} $_x:ident, $($field:ident,)*) => {
189
+ PerspectiveProperties!(impl @fields_provider $name {$($x : $y,)*} $($field,)*);
190
+ };
191
+
192
+ (impl @fields_provider $name:ident {}) => {};
193
+
194
+ (impl @fields_provider $name:ident {$($x:tt : $y:ty,)*}) => {
195
+ perspective_client::vendor::paste::paste! {
196
+ #[derive(PartialEq, Clone)]
197
+ pub struct [< $name State >] {
198
+ $($x: $y,)*
66
199
  }
200
+
201
+ impl $crate::model::StateProvider for $name {
202
+ type State = [< $name State >];
203
+ fn clone_state(&self) -> Self::State {
204
+ Self::State {
205
+ $($x : self.$x.clone(),)*
206
+ }
207
+ }
208
+ }
209
+
210
+ PerspectiveProperties!(impl @fields [< $name State >] $($x : $y,)*);
67
211
  }
68
212
  };
69
- ($i:ident, $($is:ident),+ for $key:ty) => {
70
- derive_model!($i for $key);
71
- derive_model!($($is),+ for $key);
213
+
214
+ (impl @fields $name:ident $field:ident : $value:ty, $($field_tail:ident : $value_tail:ty,)*) => {
215
+ PerspectiveProperties!(impl @field $name $field $value);
216
+ PerspectiveProperties!(impl @fields $name $($field_tail : $value_tail,)*);
217
+ };
218
+
219
+ (impl @fields $name:ident) => {};
220
+
221
+ // (impl @tuples $name:ident $value:tt : $acc:tt, $($value_tail:tt : $acc_tail:tt,)*) => {
222
+ // PerspectiveProperties!(impl @tuple $name $value $acc);
223
+ // PerspectiveProperties!(impl @tuples $name $($value_tail : $acc_tail,)*);
224
+ // };
225
+
226
+ // (impl @tuples $name:ident) => {};
227
+
228
+ ($(#[$m:meta])* $pub:vis struct $name:ident { $($(#[$_m:meta])* $_p:vis $field:ident : $value:ty),* $(,)? }) => {
229
+ PerspectiveProperties!(impl @fields $name $($field : $value,)*);
230
+ PerspectiveProperties!(impl @fields_provider $name {} $($field,)*);
72
231
  };
232
+
233
+ // ($(#[$m:meta])* $pub:vis struct $name:ident ( $($(#[$_m:meta])* $value:tt $(< $_ttt:ty >)?),* $(,)? );) => {
234
+ // PerspectiveProperties!(impl @tuples $name $($value : ${index()} ,)*);
235
+ // };
236
+ }
237
+
238
+ pub trait StateProvider {
239
+ type State: Clone + 'static;
240
+
241
+ /// Clones _just_ the state objects fields into a new dedicated state
242
+ /// struct (generated by [`PerspectiveProperties`]).
243
+ fn clone_state(&self) -> Self::State;
73
244
  }
@@ -33,7 +33,7 @@ pub trait UpdateAndRender: HasRenderer + HasSession {
33
33
  Callback::from(move |_| {
34
34
  clone!(session, renderer);
35
35
  ApiFuture::spawn(async move {
36
- renderer.draw(async { Ok(&session) }).await?;
36
+ renderer.draw(async { Ok(session.get_view()) }).await?;
37
37
  Ok(())
38
38
  })
39
39
  })
@@ -41,11 +41,16 @@ pub trait UpdateAndRender: HasRenderer + HasSession {
41
41
 
42
42
  /// Create a `Callback` that resizes from the current `View` and `Plugin`.
43
43
  fn resize_callback(&self) -> Callback<()> {
44
- clone!(self.renderer());
44
+ clone!(self.renderer(), self.session());
45
45
  Callback::from(move |_| {
46
- clone!(renderer);
46
+ clone!(renderer, session);
47
47
  ApiFuture::spawn(async move {
48
- renderer.resize().await?;
48
+ if !renderer.is_plugin_activated()? {
49
+ update_and_render(session, renderer).await?
50
+ } else {
51
+ renderer.resize().await?;
52
+ }
53
+
49
54
  Ok(())
50
55
  })
51
56
  })
@@ -57,6 +62,11 @@ pub trait UpdateAndRender: HasRenderer + HasSession {
57
62
  clone!(self.session(), self.renderer());
58
63
  Ok(ApiFuture::new(update_and_render(session, renderer)))
59
64
  }
65
+
66
+ fn just_render(&self) -> ApiResult<ApiFuture<()>> {
67
+ clone!(self.session(), self.renderer());
68
+ Ok(ApiFuture::new(update_and_render(session, renderer)))
69
+ }
60
70
  }
61
71
 
62
72
  #[tracing::instrument(level = "debug", skip(session, renderer))]
@@ -10,50 +10,81 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- use itertools::Itertools;
14
-
15
- use super::{HasPresentation, HasRenderer, HasSession, UpdateAndRender};
16
- use crate::config::{Expression, ViewConfigUpdate};
17
- use crate::utils::ApiFuture;
18
-
19
- pub trait CreateColumn: HasSession + HasPresentation + HasRenderer + UpdateAndRender {
20
- fn clone_column(&self, name: &str, in_place: bool, open_settings: bool) -> ApiFuture<()> {
21
- // 1. Create a new expression.
22
- let expr_name = self.session().metadata().make_new_column_name(Some(name));
23
- let expr = Expression::new(Some(&expr_name), &format!("\"{name}\""));
24
- let view_config = self.session().get_view_config();
25
- let mut serde_exprs = view_config.expressions.clone();
26
- serde_exprs.retain(|name, _expr| name != &expr_name);
27
- serde_exprs.insert(&expr);
28
-
29
- // 2. Replace this column in the view configuration.
30
- let mut cols = view_config.columns.clone();
31
- if in_place {
32
- let (idx, _val) = cols
33
- .iter()
34
- .find_position(|c| c.as_ref().map(|s| s == name).unwrap_or_default())
35
- .unwrap_or_else(|| {
36
- web_sys::console::error_1(
37
- &format!("Couldn't find {name} in view config!").into(),
38
- );
39
- panic!();
40
- });
41
- cols[idx] = Some(expr_name.clone());
42
- }
13
+ use std::fmt::Display;
14
+
15
+ /// Locates a view column.
16
+ /// Table columns are those defined on the table, but their types will reflect
17
+ /// the view type, not the table type.
18
+ #[derive(Clone, Debug, PartialEq)]
19
+ pub enum ColumnLocator {
20
+ Table(String),
21
+ Expression(String),
22
+ NewExpression,
23
+ }
43
24
 
44
- // 3. Ensure that the new column is opened
45
- if open_settings {
46
- self.presentation()
47
- .set_open_column_settings(Some(expr_name));
25
+ impl ColumnLocator {
26
+ /// Pulls the column's name from the locator.
27
+ /// If the column is a new expression which has yet to be saved, the
28
+ /// function will return None.
29
+ pub fn name(&self) -> Option<&String> {
30
+ match self {
31
+ Self::Table(s) | Self::Expression(s) => Some(s),
32
+ Self::NewExpression => None,
48
33
  }
34
+ }
35
+
36
+ #[inline(always)]
37
+ pub fn is_saved_expr(&self) -> bool {
38
+ matches!(self, ColumnLocator::Expression(_))
39
+ }
49
40
 
50
- // 4. Update
51
- drop(view_config);
52
- self.update_and_render(ViewConfigUpdate {
53
- expressions: Some(serde_exprs),
54
- columns: Some(cols),
55
- ..Default::default()
56
- })
41
+ #[inline(always)]
42
+ pub fn is_expr(&self) -> bool {
43
+ matches!(
44
+ self,
45
+ ColumnLocator::Expression(_) | ColumnLocator::NewExpression
46
+ )
57
47
  }
48
+
49
+ #[inline(always)]
50
+ pub fn is_new_expr(&self) -> bool {
51
+ matches!(self, ColumnLocator::NewExpression)
52
+ }
53
+ }
54
+
55
+ #[derive(Debug, Default, Clone, Copy, PartialEq)]
56
+
57
+ pub enum ColumnSettingsTab {
58
+ #[default]
59
+ Attributes,
60
+ Style,
58
61
  }
59
- impl<T: HasPresentation + HasSession + HasRenderer> CreateColumn for T {}
62
+
63
+ impl Display for ColumnSettingsTab {
64
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65
+ f.write_fmt(format_args!("{self:?}"))
66
+ }
67
+ }
68
+
69
+ #[derive(Clone, Default, Debug, PartialEq)]
70
+ pub struct OpenColumnSettings {
71
+ pub locator: Option<ColumnLocator>,
72
+ pub tab: Option<ColumnSettingsTab>,
73
+ }
74
+
75
+ impl OpenColumnSettings {
76
+ pub fn name(&self) -> Option<String> {
77
+ self.locator
78
+ .as_ref()
79
+ .and_then(|l| l.name())
80
+ .map(|s| s.to_owned())
81
+ }
82
+ }
83
+
84
+ pub trait ColumnTab: PartialEq + Display + Clone + Default + 'static {}
85
+
86
+ impl ColumnTab for String {}
87
+
88
+ impl ColumnTab for &'static str {}
89
+
90
+ impl ColumnTab for ColumnSettingsTab {}
@@ -10,52 +10,66 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- /// A macro for implementing the `wasm_bindgen` boilerplate for types which
14
- /// implement `serde::{Serialize, Deserialize}`.
15
- ///
16
- /// # Examples
17
- ///
18
- /// ```
19
- /// struct MyStruct { .. }
20
- /// derive_wasm_abi!(MyStruct, FromWasmAbi);
21
- ///
22
- /// #[wasm_bindgen]
23
- /// pub fn process_my_struct(s: MyStruct) {}
24
- /// ```
25
- #[macro_export]
26
- macro_rules! derive_wasm_abi {
27
- ($type:ty) => {
28
- impl wasm_bindgen::describe::WasmDescribe for $type {
29
- fn describe() {
30
- <js_sys::Object as wasm_bindgen::describe::WasmDescribe>::describe()
31
- }
32
- }
13
+ use perspective_js::utils::{ApiResult, ToApiError, global};
14
+ use wasm_bindgen::prelude::*;
15
+ use web_sys::*;
16
+
17
+ macro_rules! iter_index {
18
+ ($x:expr) => {
19
+ (0..$x.length()).map(|x| $x.item(x))
33
20
  };
21
+ }
22
+
23
+ /// Search the document's `styleSheets` for rules which apply to `elem` and
24
+ /// provide the `--theme-name` CSS custom property.
25
+ pub fn get_theme_names(elem: &HtmlElement) -> Result<Vec<String>, JsValue> {
26
+ let sheets = global::document().style_sheets();
27
+ let mut themes: Vec<String> = vec![];
28
+ for sheet in iter_index!(sheets) {
29
+ fill_sheet_theme_names(&mut themes, &sheet, elem)?;
30
+ }
31
+
32
+ Ok(themes)
33
+ }
34
34
 
35
- ($type:ty, FromWasmAbi $(, $symbols:tt)*) => {
36
- impl wasm_bindgen::convert::FromWasmAbi for $type {
37
- type Abi = <js_sys::Object as wasm_bindgen::convert::IntoWasmAbi>::Abi;
38
- #[inline]
39
- unsafe fn from_abi(js: Self::Abi) -> Self {
40
- let obj = unsafe { js_sys::Object::from_abi(js) };
41
- use ::perspective_js::utils::JsValueSerdeExt;
42
- wasm_bindgen::JsValue::from(obj).into_serde_ext().unwrap()
35
+ fn fill_rule_theme_names(
36
+ themes: &mut Vec<String>,
37
+ rule: &Option<CssRule>,
38
+ elem: &HtmlElement,
39
+ ) -> ApiResult<()> {
40
+ if let Some(rule) = rule.as_ref().into_apierror()?.dyn_ref::<CssStyleRule>() {
41
+ let txt = rule.selector_text();
42
+ if elem.matches(&txt)? {
43
+ let style = rule.style();
44
+ let x = (0..style.length()).map(|x| style.item(x));
45
+ for property in x {
46
+ if property == "--theme-name" {
47
+ let name = style.get_property_value("--theme-name")?;
48
+ let trimmed = name.trim();
49
+ themes.push(trimmed[1..trimmed.len() - 1].to_owned());
50
+ }
43
51
  }
44
52
  }
53
+ }
45
54
 
46
- derive_wasm_abi!($type $(, $symbols)*);
47
- };
55
+ Ok(())
56
+ }
48
57
 
49
- ($type:ty, IntoWasmAbi $(, $symbols:tt)*) => {
50
- impl wasm_bindgen::convert::IntoWasmAbi for $type {
51
- type Abi = <js_sys::Object as wasm_bindgen::convert::IntoWasmAbi>::Abi;
52
- #[inline]
53
- fn into_abi(self) -> Self::Abi {
54
- use wasm_bindgen::JsCast;
55
- <wasm_bindgen::JsValue as ::perspective_js::utils::JsValueSerdeExt>::from_serde_ext(&self).unwrap().unchecked_into::<js_sys::Object>().into_abi()
56
- }
58
+ fn fill_sheet_theme_names(
59
+ themes: &mut Vec<String>,
60
+ sheet: &Option<StyleSheet>,
61
+ elem: &HtmlElement,
62
+ ) -> ApiResult<()> {
63
+ let sheet = sheet
64
+ .as_ref()
65
+ .into_apierror()?
66
+ .unchecked_ref::<CssStyleSheet>();
67
+
68
+ if let Ok(rules) = sheet.css_rules() {
69
+ for rule in iter_index!(&rules) {
70
+ fill_rule_theme_names(themes, &rule, elem).unwrap_or_default();
57
71
  }
72
+ }
58
73
 
59
- derive_wasm_abi!($type $(, $symbols)*);
60
- };
74
+ Ok(())
61
75
  }