@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
@@ -13,14 +13,16 @@
13
13
  use perspective_client::*;
14
14
  use yew::prelude::*;
15
15
 
16
+ use crate::PerspectiveProperties;
16
17
  use crate::session::{Session, ViewStats};
17
- use crate::utils::{AddListener, ToFormattedString};
18
+ use crate::utils::{AddListener, u32Ext};
18
19
 
19
- #[derive(Properties, PartialEq)]
20
+ #[derive(PartialEq, Properties, PerspectiveProperties!)]
20
21
  pub struct StatusBarRowsCounterProps {
21
22
  pub session: Session,
22
23
  }
23
24
 
25
+ /// A component to show the current [`Table`]'s dimensions.
24
26
  #[function_component]
25
27
  pub fn StatusBarRowsCounter(props: &StatusBarRowsCounterProps) -> Html {
26
28
  let stats = use_state_eq(|| props.session.get_table_stats());
@@ -57,10 +59,11 @@ pub fn StatusBarRowsCounter(props: &StatusBarRowsCounterProps) -> Html {
57
59
  let ncols = tc.to_formatted_string();
58
60
  html! {
59
61
  <span id="rows">
60
- { vrows }
61
- <span>{ format!(" ({}) x ", nrows) }</span>
62
- { vcols }
63
- <span>{ format!(" ({})", ncols) }</span>
62
+ <span>{ vrows }</span>
63
+ <span class="total">{ format!(" ({})", nrows) }</span>
64
+ <span class="x">{ " x " }</span>
65
+ <span>{ vcols }</span>
66
+ <span class="total">{ format!(" ({})", ncols) }</span>
64
67
  </span>
65
68
  }
66
69
  },
@@ -83,7 +86,12 @@ pub fn StatusBarRowsCounter(props: &StatusBarRowsCounterProps) -> Html {
83
86
  let nrows = tr.to_formatted_string();
84
87
  let vcols = vc.to_formatted_string();
85
88
  html! {
86
- <span id="rows">{ vrows }<span>{ format!(" ({}) x ", nrows) }</span>{ vcols }</span>
89
+ <span id="rows">
90
+ <span>{ vrows }</span>
91
+ <span class="total">{ format!(" ({})", nrows) }</span>
92
+ <span class="x">{ " x " }</span>
93
+ <span>{ vcols }</span>
94
+ </span>
87
95
  }
88
96
  },
89
97
 
@@ -97,10 +105,10 @@ pub fn StatusBarRowsCounter(props: &StatusBarRowsCounterProps) -> Html {
97
105
  let ncols = tc.to_formatted_string();
98
106
  html! {
99
107
  <span id="rows">
100
- { vrows }
101
- <span>{ " x " }</span>
102
- { vcols }
103
- <span>{ format!(" ({})", ncols) }</span>
108
+ <span>{ vrows }</span>
109
+ <span class="x">{ " x " }</span>
110
+ <span>{ vcols }</span>
111
+ <span class="total">{ format!(" ({})", ncols) }</span>
104
112
  </span>
105
113
  }
106
114
  },
@@ -111,7 +119,13 @@ pub fn StatusBarRowsCounter(props: &StatusBarRowsCounterProps) -> Html {
111
119
  }) => {
112
120
  let nrows = tr.to_formatted_string();
113
121
  let ncols = tc.to_formatted_string();
114
- html! { <span id="rows">{ nrows }<span>{ " x " }</span>{ ncols }</span> }
122
+ html! {
123
+ <span id="rows">
124
+ <span>{ nrows }</span>
125
+ <span class="x">{ " x " }</span>
126
+ <span>{ ncols }</span>
127
+ </span>
128
+ }
115
129
  },
116
130
  Some(ViewStats {
117
131
  num_table_cells: None,
@@ -120,110 +134,3 @@ pub fn StatusBarRowsCounter(props: &StatusBarRowsCounterProps) -> Html {
120
134
  None => html! { <span /> },
121
135
  }
122
136
  }
123
-
124
- // /// A label widget which displays a row count and a "projection" count, the
125
- // /// number of rows in the `View` which includes aggregate rows.
126
- // pub struct StatusBarRowsCounter {}
127
-
128
- // impl Component for StatusBarRowsCounter {
129
- // type Message = ();
130
- // type Properties = ();
131
-
132
- // fn create(_ctx: &Context<Self>) -> Self {
133
- // Self {}
134
- // }
135
-
136
- // fn update(&mut self, _ctx: &Context<Self>, _msg: Self::Message) -> bool {
137
- // false
138
- // }
139
-
140
- // fn view(&self, ctx: &Context<Self>) -> Html {
141
- // match &ctx.props().stats {
142
- // Some(
143
- // ViewStats {
144
- // num_table_cells: Some((tr, tc)),
145
- // num_view_cells: Some((vr, vc)),
146
- // is_group_by: true,
147
- // ..
148
- // }
149
- // | ViewStats {
150
- // num_table_cells: Some((tr, tc)),
151
- // num_view_cells: Some((vr, vc)),
152
- // is_filtered: true,
153
- // ..
154
- // },
155
- // ) if vc != tc => {
156
- // let vrows = vr.to_formatted_string();
157
- // let nrows = tr.to_formatted_string();
158
- // let vcols = vc.to_formatted_string();
159
- // let ncols = tc.to_formatted_string();
160
- // html! {
161
- // <span id="rows">
162
- // { vrows }
163
- // <span>{ format!(" ({}) x ", nrows) }</span>
164
- // { vcols }
165
- // <span>{ format!(" ({})", ncols) }</span>
166
- // </span>
167
- // }
168
- // },
169
-
170
- // Some(
171
- // ViewStats {
172
- // num_table_cells: Some((tr, _)),
173
- // num_view_cells: Some((vr, vc)),
174
- // is_group_by: true,
175
- // ..
176
- // }
177
- // | ViewStats {
178
- // num_table_cells: Some((tr, _)),
179
- // num_view_cells: Some((vr, vc)),
180
- // is_filtered: true,
181
- // ..
182
- // },
183
- // ) => {
184
- // let vrows = vr.to_formatted_string();
185
- // let nrows = tr.to_formatted_string();
186
- // let vcols = vc.to_formatted_string();
187
- // html! {
188
- // <span id="rows">
189
- // { vrows }
190
- // <span>{ format!(" ({}) x ", nrows) }</span>
191
- // { vcols }
192
- // </span>
193
- // }
194
- // },
195
-
196
- // Some(ViewStats {
197
- // num_table_cells: Some((_, tc)),
198
- // num_view_cells: Some((vr, vc)),
199
- // ..
200
- // }) if vc != tc => {
201
- // let vrows = vr.to_formatted_string();
202
- // let vcols = vc.to_formatted_string();
203
- // let ncols = tc.to_formatted_string();
204
- // html! {
205
- // <span id="rows">
206
- // { vrows }
207
- // <span>{ " x " }</span>
208
- // { vcols }
209
- // <span>{ format!(" ({})", ncols) }</span>
210
- // </span>
211
- // }
212
- // },
213
-
214
- // Some(ViewStats {
215
- // num_table_cells: Some((tr, tc)),
216
- // ..
217
- // }) => {
218
- // let nrows = tr.to_formatted_string();
219
- // let ncols = tc.to_formatted_string();
220
- // html! { <span id="rows">{ nrows }<span>{ " x " }</span>{
221
- // ncols }</span> } },
222
- // Some(ViewStats {
223
- // num_table_cells: None,
224
- // ..
225
- // }) => html! { <span /> },
226
- // None => html! { <span /> },
227
- // }
228
- // }
229
- // }
@@ -11,83 +11,25 @@
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
13
  use perspective_client::config::ViewConfigUpdate;
14
+ use perspective_js::utils::ApiError;
15
+ use wasm_bindgen::JsValue;
14
16
  use web_sys::*;
15
17
  use yew::prelude::*;
16
18
 
17
- use crate::model::UpdateAndRender;
19
+ use crate::PerspectiveProperties;
20
+ use crate::custom_events::CustomEvents;
21
+ use crate::model::*;
18
22
  use crate::renderer::*;
19
23
  use crate::session::*;
20
24
  use crate::utils::*;
21
- use crate::*;
22
25
 
23
- #[derive(Clone, Default, Debug, PartialEq)]
24
- enum StatusIconState {
25
- Loading,
26
- Updating(u32),
27
- Errored(String, String, &'static str),
28
- Normal,
29
-
30
- #[default]
31
- Unititialized,
32
- }
33
-
34
- #[derive(Clone, Debug)]
35
- enum StatusIconStateAction {
36
- Increment,
37
- Decrement,
38
- Load(Option<ViewStats>),
39
- SetError(ApiError),
40
- }
41
-
42
- impl Reducible for StatusIconState {
43
- type Action = StatusIconStateAction;
44
-
45
- fn reduce(self: std::rc::Rc<Self>, action: Self::Action) -> std::rc::Rc<Self> {
46
- let new_status = match (&*self, action.clone()) {
47
- (StatusIconState::Updating(x), StatusIconStateAction::Increment) => {
48
- Self::Updating(x + 1)
49
- },
50
- (StatusIconState::Updating(x), StatusIconStateAction::Decrement) if *x > 1 => {
51
- Self::Updating(x - 1)
52
- },
53
- (_, StatusIconStateAction::Load(stats)) => {
54
- if stats.and_then(|x| x.num_table_cells).is_some() {
55
- StatusIconState::Normal
56
- } else {
57
- Self::Loading
58
- }
59
- },
60
- (_, StatusIconStateAction::SetError(e)) => {
61
- Self::Errored(e.message(), e.stacktrace(), e.kind())
62
- },
63
- (
64
- StatusIconState::Loading,
65
- StatusIconStateAction::Increment | StatusIconStateAction::Decrement,
66
- ) => StatusIconState::Loading,
67
- (_, StatusIconStateAction::Increment) => Self::Updating(1),
68
- (_, StatusIconStateAction::Decrement) => StatusIconState::Normal,
69
- };
70
-
71
- new_status.into()
72
- }
73
- }
74
-
75
- #[extend::ext]
76
- impl<T: Reducible + 'static> UseReducerDispatcher<T> {
77
- fn callback<U>(&self, action: impl Fn(U) -> T::Action + 'static) -> Callback<U> {
78
- let dispatcher = self.clone();
79
- Callback::from(move |event| dispatcher.dispatch(action(event)))
80
- }
81
- }
82
-
83
- #[derive(Clone, Properties, PartialEq)]
26
+ #[derive(PartialEq, Properties, PerspectiveProperties!)]
84
27
  pub struct StatusIndicatorProps {
85
- pub session: Session,
28
+ pub custom_events: CustomEvents,
86
29
  pub renderer: Renderer,
30
+ pub session: Session,
87
31
  }
88
32
 
89
- derive_model!(Session, Renderer for StatusIndicatorProps);
90
-
91
33
  /// An indicator component which displays the current status of the perspective
92
34
  /// server as an icon. This indicator also functions as a button to invoke the
93
35
  /// reconnect callback when in an error state.
@@ -123,19 +65,6 @@ pub fn StatusIndicator(props: &StatusIndicatorProps) -> Html {
123
65
  },
124
66
  );
125
67
 
126
- let onclick = use_async_callback(
127
- (props.clone(), state.clone()),
128
- async move |_: MouseEvent, (props, state)| {
129
- if let StatusIconState::Errored(..) = &**state {
130
- props.session.reconnect().await?;
131
- let cfg = ViewConfigUpdate::default();
132
- props.update_and_render(cfg)?.await?;
133
- }
134
-
135
- Ok::<_, ApiError>(())
136
- },
137
- );
138
-
139
68
  let class_name = match (&*state, props.session.is_reconnect()) {
140
69
  (StatusIconState::Errored(..), true) => "errored",
141
70
  (StatusIconState::Errored(..), false) => "errored disabled",
@@ -145,6 +74,33 @@ pub fn StatusIndicator(props: &StatusIndicatorProps) -> Html {
145
74
  (StatusIconState::Unititialized, _) => "uninitialized",
146
75
  };
147
76
 
77
+ let onclick = use_async_callback(
78
+ (props.clone_state(), state.clone()),
79
+ async move |_: MouseEvent, (props, state)| {
80
+ match &**state {
81
+ StatusIconState::Errored(..) => {
82
+ props.session.reconnect().await?;
83
+ let cfg = ViewConfigUpdate::default();
84
+ props.update_and_render(cfg)?.await?;
85
+ },
86
+ StatusIconState::Normal => {
87
+ props
88
+ .custom_events
89
+ .dispatch_event("status-indicator-click", JsValue::UNDEFINED)?;
90
+ },
91
+ _ => {},
92
+ };
93
+
94
+ // if let StatusIconState::Errored(..) = &**state {
95
+ // props.session.reconnect().await?;
96
+ // let cfg = ViewConfigUpdate::default();
97
+ // props.update_and_render(cfg)?.await?;
98
+ // }
99
+
100
+ Ok::<_, ApiError>(())
101
+ },
102
+ );
103
+
148
104
  html! {
149
105
  <>
150
106
  <div class="section">
@@ -162,3 +118,63 @@ pub fn StatusIndicator(props: &StatusIndicatorProps) -> Html {
162
118
  </>
163
119
  }
164
120
  }
121
+
122
+ #[derive(Clone, Default, Debug, PartialEq)]
123
+ enum StatusIconState {
124
+ Loading,
125
+ Updating(u32),
126
+ Errored(String, String, &'static str),
127
+ Normal,
128
+
129
+ #[default]
130
+ Unititialized,
131
+ }
132
+
133
+ #[derive(Clone, Debug)]
134
+ enum StatusIconStateAction {
135
+ Increment,
136
+ Decrement,
137
+ Load(Option<ViewStats>),
138
+ SetError(ApiError),
139
+ }
140
+
141
+ impl Reducible for StatusIconState {
142
+ type Action = StatusIconStateAction;
143
+
144
+ fn reduce(self: std::rc::Rc<Self>, action: Self::Action) -> std::rc::Rc<Self> {
145
+ let new_status = match (&*self, action.clone()) {
146
+ (StatusIconState::Updating(x), StatusIconStateAction::Increment) => {
147
+ Self::Updating(x + 1)
148
+ },
149
+ (StatusIconState::Updating(x), StatusIconStateAction::Decrement) if *x > 1 => {
150
+ Self::Updating(x - 1)
151
+ },
152
+ (_, StatusIconStateAction::Load(stats)) => {
153
+ if stats.and_then(|x| x.num_table_cells).is_some() {
154
+ StatusIconState::Normal
155
+ } else {
156
+ Self::Loading
157
+ }
158
+ },
159
+ (_, StatusIconStateAction::SetError(e)) => {
160
+ Self::Errored(e.message(), e.stacktrace(), e.kind())
161
+ },
162
+ (
163
+ StatusIconState::Loading,
164
+ StatusIconStateAction::Increment | StatusIconStateAction::Decrement,
165
+ ) => StatusIconState::Loading,
166
+ (_, StatusIconStateAction::Increment) => Self::Updating(1),
167
+ (_, StatusIconStateAction::Decrement) => StatusIconState::Normal,
168
+ };
169
+
170
+ new_status.into()
171
+ }
172
+ }
173
+
174
+ #[extend::ext]
175
+ impl<T: Reducible + 'static> UseReducerDispatcher<T> {
176
+ fn callback<U>(&self, action: impl Fn(U) -> T::Action + 'static) -> Callback<U> {
177
+ let dispatcher = self.clone();
178
+ Callback::from(move |event| dispatcher.dispatch(action(event)))
179
+ }
180
+ }
@@ -16,18 +16,10 @@ use yew::*;
16
16
  use super::form::color_selector::*;
17
17
  use super::modal::{ModalLink, SetModalLink};
18
18
  use super::style::LocalStyle;
19
- use crate::components::form::select_field::SelectEnumField;
19
+ use crate::components::form::select_enum_field::SelectEnumField;
20
20
  use crate::config::*;
21
+ use crate::css;
21
22
  use crate::utils::WeakScope;
22
- use crate::*;
23
-
24
- pub enum StringColumnStyleMsg {
25
- Reset(StringColumnStyleConfig),
26
- FormatChanged(Option<FormatMode>),
27
- ColorModeChanged(Option<StringColorMode>),
28
- ColorChanged(String),
29
- ColorReset,
30
- }
31
23
 
32
24
  #[derive(Properties)]
33
25
  pub struct StringColumnStyleProps {
@@ -53,47 +45,20 @@ impl PartialEq for StringColumnStyleProps {
53
45
  }
54
46
  }
55
47
 
48
+ pub enum StringColumnStyleMsg {
49
+ Reset(StringColumnStyleConfig),
50
+ FormatChanged(Option<FormatMode>),
51
+ ColorModeChanged(Option<StringColorMode>),
52
+ ColorChanged(String),
53
+ ColorReset,
54
+ }
55
+
56
56
  /// A component for the style form control for [`String`] columns.
57
57
  pub struct StringColumnStyle {
58
58
  config: StringColumnStyleConfig,
59
59
  default_config: StringColumnStyleDefaultConfig,
60
60
  }
61
61
 
62
- impl StringColumnStyle {
63
- /// When this config has changed, we must signal the wrapper element.
64
- fn dispatch_config(&self, ctx: &Context<Self>) {
65
- let update = Some(self.config.clone()).filter(|x| x != &StringColumnStyleConfig::default());
66
- ctx.props()
67
- .on_change
68
- .emit(ColumnConfigValueUpdate::DatagridStringStyle(update));
69
- }
70
-
71
- /// Generate a color selector component for a specific `StringColorMode`
72
- /// variant.
73
- fn color_select_row(&self, ctx: &Context<Self>, mode: &StringColorMode, title: &str) -> Html {
74
- let on_color = ctx.link().callback(StringColumnStyleMsg::ColorChanged);
75
- let color = self
76
- .config
77
- .color
78
- .clone()
79
- .unwrap_or_else(|| self.default_config.color.to_owned());
80
-
81
- let color_props = props!(ColorProps {
82
- title: title.to_owned(),
83
- on_color,
84
- is_modified: color != self.default_config.color,
85
- color,
86
- on_reset: ctx.link().callback(|_| StringColumnStyleMsg::ColorReset)
87
- });
88
-
89
- if &self.config.string_color_mode == mode {
90
- html! { <div class="row"><ColorSelector ..color_props /></div> }
91
- } else {
92
- html! {}
93
- }
94
- }
95
- }
96
-
97
62
  impl Component for StringColumnStyle {
98
63
  type Message = StringColumnStyleMsg;
99
64
  type Properties = StringColumnStyleProps;
@@ -184,3 +149,38 @@ impl Component for StringColumnStyle {
184
149
  }
185
150
  }
186
151
  }
152
+
153
+ impl StringColumnStyle {
154
+ /// When this config has changed, we must signal the wrapper element.
155
+ fn dispatch_config(&self, ctx: &Context<Self>) {
156
+ let update = Some(self.config.clone()).filter(|x| x != &StringColumnStyleConfig::default());
157
+ ctx.props()
158
+ .on_change
159
+ .emit(ColumnConfigValueUpdate::DatagridStringStyle(update));
160
+ }
161
+
162
+ /// Generate a color selector component for a specific `StringColorMode`
163
+ /// variant.
164
+ fn color_select_row(&self, ctx: &Context<Self>, mode: &StringColorMode, title: &str) -> Html {
165
+ let on_color = ctx.link().callback(StringColumnStyleMsg::ColorChanged);
166
+ let color = self
167
+ .config
168
+ .color
169
+ .clone()
170
+ .unwrap_or_else(|| self.default_config.color.to_owned());
171
+
172
+ let color_props = props!(ColorProps {
173
+ title: title.to_owned(),
174
+ on_color,
175
+ is_modified: color != self.default_config.color,
176
+ color,
177
+ on_reset: ctx.link().callback(|_| StringColumnStyleMsg::ColorReset)
178
+ });
179
+
180
+ if &self.config.string_color_mode == mode {
181
+ html! { <div class="row"><ColorSelector ..color_props /></div> }
182
+ } else {
183
+ html! {}
184
+ }
185
+ }
186
+ }
@@ -10,15 +10,14 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- use web_sys::HtmlStyleElement;
14
13
  use yew::prelude::*;
15
- use yew::virtual_dom::VNode;
16
14
 
17
15
  use super::style_cache::StyleCache;
18
16
 
19
17
  #[derive(Properties, PartialEq)]
20
18
  pub struct StyleProviderProps {
21
19
  pub root: web_sys::HtmlElement,
20
+
22
21
  #[prop_or(true)]
23
22
  pub is_shadow: bool,
24
23
  pub children: Children,
@@ -50,16 +49,3 @@ impl Component for StyleProvider {
50
49
  }
51
50
  }
52
51
  }
53
-
54
- #[derive(Properties, PartialEq)]
55
- struct StyleKeyedProps {
56
- elem: HtmlStyleElement,
57
- }
58
-
59
- /// Necessary only to attach `key` to individual `HtmlStylElement` children,
60
- /// as `yew` does not calculate list updates correctly for sequences of these
61
- /// without keys.
62
- #[function_component(StyleKeyed)]
63
- fn style_renderer(props: &StyleKeyedProps) -> Html {
64
- VNode::VRef(props.elem.clone().into())
65
- }
@@ -21,7 +21,7 @@ use crate::components::containers::select::{Select, SelectItem};
21
21
  use crate::components::form::number_field::NumberField;
22
22
  use crate::components::form::number_range_field::NumberRangeField;
23
23
  use crate::components::form::optional_field::OptionalField;
24
- use crate::components::form::select_field::SelectEnumField;
24
+ use crate::components::form::select_enum_field::SelectEnumField;
25
25
  use crate::components::style_controls::CustomNumberFormatMsg;
26
26
  use crate::config::{
27
27
  ROUNDING_INCREMENTS, RoundingIncrement, RoundingMode, RoundingPriority, TrailingZeroDisplay,
@@ -13,7 +13,7 @@
13
13
  use yew::html;
14
14
 
15
15
  use super::CustomNumberFormat;
16
- use crate::components::form::select_field::SelectEnumField;
16
+ use crate::components::form::select_enum_field::SelectEnumField;
17
17
  use crate::components::style_controls::{CustomNumberFormatMsg, NotationName};
18
18
  use crate::config::*;
19
19
 
@@ -13,7 +13,7 @@
13
13
  use yew::html;
14
14
 
15
15
  use super::CustomNumberFormat;
16
- use crate::components::form::select_field::SelectEnumField;
16
+ use crate::components::form::select_enum_field::SelectEnumField;
17
17
  use crate::components::style_controls::{CustomNumberFormatMsg, NumberStyle};
18
18
  use crate::config::*;
19
19