@perspective-dev/viewer 4.2.0 → 4.4.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 (240) 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/botanical.css +1 -0
  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/pro-dark.css +1 -1
  17. package/dist/css/pro.css +1 -1
  18. package/dist/css/solarized-dark.css +1 -1
  19. package/dist/css/solarized.css +1 -1
  20. package/dist/css/themes.css +1 -1
  21. package/dist/css/vaporwave.css +1 -1
  22. package/dist/esm/extensions.d.ts +32 -1
  23. package/dist/esm/perspective-viewer.d.ts +1 -0
  24. package/dist/esm/perspective-viewer.inline.js +2 -2
  25. package/dist/esm/perspective-viewer.inline.js.map +4 -4
  26. package/dist/esm/perspective-viewer.js +2 -2
  27. package/dist/esm/perspective-viewer.js.map +4 -4
  28. package/dist/esm/ts-rs/GroupRollupMode.d.ts +1 -0
  29. package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +2 -0
  30. package/dist/wasm/perspective-viewer.d.ts +57 -53
  31. package/dist/wasm/perspective-viewer.js +197 -164
  32. package/dist/wasm/perspective-viewer.wasm +0 -0
  33. package/dist/wasm/perspective-viewer.wasm.d.ts +17 -18
  34. package/package.json +9 -6
  35. package/src/{less/aggregate-selector.less → css/aggregate-selector.css} +23 -20
  36. package/src/css/column-dropdown.css +109 -0
  37. package/src/{less/column-selector.less → css/column-selector.css} +161 -159
  38. package/src/{less/column-settings-panel.less → css/column-settings-panel.css} +69 -59
  39. package/src/{less/column-style.less → css/column-style.css} +52 -66
  40. package/src/{less/column-symbol-attributes.less → css/column-symbol-attributes.css} +15 -14
  41. package/src/css/config-selector.css +441 -0
  42. package/src/{less/containers/dropdown-menu.less → css/containers/dropdown-menu.css} +20 -19
  43. package/src/{less/containers/pairs-list.less → css/containers/pairs-list.css} +13 -12
  44. package/src/{themes/variables.less → css/containers/scroll-panel.css} +25 -22
  45. package/src/{less/containers/split-panel.less → css/containers/split-panel.css} +15 -14
  46. package/src/{less/containers/tabs.less → css/containers/tabs.css} +17 -19
  47. package/src/css/dom/checkbox.css +102 -0
  48. package/src/css/dom/scrollbar.css +35 -0
  49. package/src/{less/dom/select.less → css/dom/select.css} +17 -18
  50. package/src/{less/empty-column.less → css/empty-column.css} +19 -18
  51. package/src/{less/expression-editor.less → css/expression-editor.css} +19 -18
  52. package/src/{less/filter-dropdown.less → css/filter-dropdown.css} +12 -11
  53. package/src/{less/filter-item.less → css/filter-item.css} +16 -15
  54. package/src/{less/form/code-editor.less → css/form/code-editor.css} +26 -30
  55. package/src/{less/form/debug.less → css/form/debug.css} +19 -18
  56. package/src/{less/function-dropdown.less → css/function-dropdown.css} +12 -11
  57. package/src/css/plugin-selector.css +261 -0
  58. package/src/{less/render-warning.less → css/render-warning.css} +18 -17
  59. package/src/{less/status-bar.less → css/status-bar.css} +156 -144
  60. package/src/css/type-icon.css +116 -0
  61. package/src/{less/viewer.less → css/viewer.css} +112 -146
  62. package/src/rust/components/column_dropdown.rs +229 -119
  63. package/src/rust/components/column_selector/active_column.rs +81 -62
  64. package/src/rust/components/column_selector/add_expression_button.rs +1 -0
  65. package/src/rust/components/column_selector/aggregate_selector.rs +25 -15
  66. package/src/rust/components/column_selector/config_selector.rs +374 -185
  67. package/src/rust/components/column_selector/empty_column.rs +2 -2
  68. package/src/rust/components/column_selector/expr_edit_button.rs +8 -2
  69. package/src/rust/components/column_selector/filter_column.rs +37 -26
  70. package/src/rust/components/column_selector/inactive_column.rs +41 -29
  71. package/src/rust/components/column_selector/invalid_column.rs +7 -18
  72. package/src/rust/components/column_selector/pivot_column.rs +21 -10
  73. package/src/rust/components/column_selector/sort_column.rs +23 -13
  74. package/src/rust/components/column_selector.rs +189 -100
  75. package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +1 -1
  76. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +3 -2
  77. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +3 -2
  78. package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +2 -3
  79. package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +7 -1
  80. package/src/rust/components/column_settings_sidebar/style_tab.rs +153 -112
  81. package/src/rust/components/column_settings_sidebar.rs +91 -53
  82. package/src/rust/components/containers/dragdrop_list.rs +29 -7
  83. package/src/rust/components/containers/scroll_panel.rs +8 -1
  84. package/src/rust/components/containers/select.rs +3 -3
  85. package/src/rust/components/containers/sidebar_close_button.rs +1 -1
  86. package/src/rust/components/containers/split_panel.rs +3 -2
  87. package/src/rust/components/containers/tab_list.rs +1 -1
  88. package/src/rust/components/copy_dropdown.rs +7 -28
  89. package/src/rust/components/datetime_column_style/custom.rs +2 -2
  90. package/src/rust/components/datetime_column_style/simple.rs +2 -2
  91. package/src/rust/components/datetime_column_style.rs +4 -2
  92. package/src/rust/components/editable_header.rs +7 -4
  93. package/src/rust/components/empty_row.rs +1 -1
  94. package/src/rust/components/export_dropdown.rs +4 -30
  95. package/src/rust/components/expression_editor.rs +19 -10
  96. package/src/rust/components/filter_dropdown.rs +246 -102
  97. package/src/rust/components/font_loader.rs +11 -28
  98. package/src/rust/components/form/code_editor.rs +17 -2
  99. package/src/rust/components/form/color_range_selector.rs +19 -6
  100. package/src/rust/components/form/debug.rs +30 -13
  101. package/src/rust/components/function_dropdown.rs +186 -113
  102. package/src/rust/components/main_panel.rs +71 -89
  103. package/src/rust/components/mod.rs +1 -1
  104. package/src/rust/components/modal.rs +7 -1
  105. package/src/rust/components/number_column_style.rs +22 -7
  106. package/src/rust/components/plugin_selector.rs +34 -92
  107. package/src/rust/components/portal.rs +274 -0
  108. package/src/rust/components/render_warning.rs +72 -123
  109. package/src/rust/components/settings_panel.rs +115 -11
  110. package/src/rust/components/status_bar.rs +222 -98
  111. package/src/rust/components/status_bar_counter.rs +8 -20
  112. package/src/rust/components/status_indicator.rs +64 -111
  113. package/src/rust/components/string_column_style.rs +2 -2
  114. package/src/rust/components/style/style_cache.rs +5 -1
  115. package/src/rust/components/viewer.rs +391 -39
  116. package/src/rust/custom_elements/copy_dropdown.rs +102 -21
  117. package/src/rust/custom_elements/export_dropdown.rs +102 -20
  118. package/src/rust/custom_elements/mod.rs +0 -7
  119. package/src/rust/custom_elements/modal.rs +7 -103
  120. package/src/rust/custom_elements/viewer.rs +99 -35
  121. package/src/rust/custom_events.rs +23 -2
  122. package/src/rust/dragdrop.rs +149 -10
  123. package/src/{less/containers/scroll-panel.less → rust/engines.rs} +15 -13
  124. package/src/rust/js/plugin.rs +20 -1
  125. package/src/rust/lib.rs +5 -4
  126. package/src/rust/presentation/props.rs +39 -0
  127. package/src/rust/presentation/sheets.rs +3 -3
  128. package/src/rust/presentation.rs +44 -8
  129. package/src/rust/renderer/limits.rs +32 -3
  130. package/src/{less/dom/scrollbar.less → rust/renderer/props.rs} +18 -19
  131. package/src/rust/renderer/registry.rs +8 -1
  132. package/src/rust/renderer.rs +83 -9
  133. package/src/rust/session/column_defaults_update.rs +18 -0
  134. package/src/rust/session/metadata.rs +23 -2
  135. package/src/rust/session/props.rs +178 -0
  136. package/src/rust/session/replace_expression_update.rs +1 -0
  137. package/src/rust/session.rs +124 -117
  138. package/src/rust/tasks/column_locator.rs +133 -0
  139. package/src/rust/{model → tasks}/columns_iter_set.rs +14 -23
  140. package/src/rust/{model → tasks}/edit_expression.rs +34 -10
  141. package/src/rust/{model → tasks}/eject.rs +2 -2
  142. package/src/rust/{model → tasks}/get_viewer_config.rs +0 -11
  143. package/src/rust/{model → tasks}/intersection_observer.rs +22 -4
  144. package/src/{less/containers/radio-list.less → rust/tasks/is_invalid_drop.rs} +21 -14
  145. package/src/rust/tasks/mod.rs +52 -0
  146. package/src/rust/{model → tasks}/plugin_column_styles.rs +69 -46
  147. package/src/rust/{model → tasks}/resize_observer.rs +39 -6
  148. package/src/rust/{model → tasks}/send_plugin_config.rs +1 -1
  149. package/src/rust/tasks/structural.rs +53 -0
  150. package/src/rust/utils/mod.rs +4 -0
  151. package/src/rust/utils/modal_position.rs +110 -0
  152. package/src/rust/utils/ptr_eq_rc.rs +74 -0
  153. package/src/rust/utils/pubsub.rs +11 -1
  154. package/src/svg/bg-pattern.png +0 -0
  155. package/src/svg/close-icon.svg +1 -1
  156. package/src/svg/expression.svg +1 -1
  157. package/src/svg/mega-menu-icons-candlestick.svg +1 -1
  158. package/src/svg/mega-menu-icons-datagrid.svg +1 -2
  159. package/src/svg/mega-menu-icons-heatmap.svg +1 -1
  160. package/src/svg/mega-menu-icons-map-scatter.svg +1 -1
  161. package/src/svg/mega-menu-icons-ohlc.svg +1 -1
  162. package/src/svg/mega-menu-icons-sunburst.svg +1 -1
  163. package/src/svg/mega-menu-icons-treemap.svg +1 -1
  164. package/src/svg/mega-menu-icons-x-bar.svg +1 -1
  165. package/src/svg/mega-menu-icons-x-y-line.svg +1 -1
  166. package/src/svg/mega-menu-icons-x-y-scatter.svg +1 -1
  167. package/src/svg/mega-menu-icons-y-area.svg +1 -1
  168. package/src/svg/mega-menu-icons-y-bar.svg +1 -1
  169. package/src/svg/mega-menu-icons-y-line.svg +1 -1
  170. package/src/svg/mega-menu-icons-y-scatter.svg +1 -1
  171. package/src/svg/radio-hover.svg +1 -1
  172. package/src/svg/radio-off.svg +1 -1
  173. package/src/svg/radio-on.svg +1 -1
  174. package/src/themes/botanical.css +157 -0
  175. package/src/themes/defaults.css +139 -0
  176. package/src/themes/dracula.css +233 -0
  177. package/src/themes/gruvbox-dark.css +255 -0
  178. package/src/themes/gruvbox.css +134 -0
  179. package/src/themes/icons.css +124 -0
  180. package/src/themes/intl/de.css +102 -0
  181. package/src/themes/intl/es.css +102 -0
  182. package/src/themes/intl/fr.css +102 -0
  183. package/src/themes/intl/ja.css +102 -0
  184. package/src/themes/intl/pt.css +102 -0
  185. package/src/themes/intl/zh.css +102 -0
  186. package/src/themes/intl.css +102 -0
  187. package/src/themes/monokai.css +233 -0
  188. package/src/themes/pro-dark.css +158 -0
  189. package/src/themes/{themes.less → pro.css} +17 -20
  190. package/src/themes/solarized-dark.css +135 -0
  191. package/src/themes/solarized.css +95 -0
  192. package/src/themes/themes.css +22 -0
  193. package/src/themes/vaporwave.css +256 -0
  194. package/src/ts/extensions.ts +73 -2
  195. package/src/ts/perspective-viewer.ts +1 -0
  196. package/src/ts/ts-rs/GroupRollupMode.ts +3 -0
  197. package/src/ts/ts-rs/ViewerConfigUpdate.ts +2 -1
  198. package/tsconfig.json +1 -0
  199. package/dist/css/variables.css +0 -0
  200. package/src/less/column-dropdown.less +0 -95
  201. package/src/less/config-selector.less +0 -363
  202. package/src/less/dom/checkbox.less +0 -100
  203. package/src/less/plugin-selector.less +0 -183
  204. package/src/less/type-icon.less +0 -68
  205. package/src/rust/components/error_message.rs +0 -56
  206. package/src/rust/custom_elements/column_dropdown.rs +0 -123
  207. package/src/rust/custom_elements/filter_dropdown.rs +0 -179
  208. package/src/rust/custom_elements/function_dropdown.rs +0 -115
  209. package/src/rust/model/column_locator.rs +0 -82
  210. package/src/rust/model/is_invalid_drop.rs +0 -36
  211. package/src/rust/model/mod.rs +0 -100
  212. package/src/rust/model/reset_all.rs +0 -38
  213. package/src/rust/model/structural.rs +0 -244
  214. package/src/themes/dracula.less +0 -101
  215. package/src/themes/gruvbox-dark.less +0 -116
  216. package/src/themes/gruvbox.less +0 -152
  217. package/src/themes/icons.less +0 -130
  218. package/src/themes/intl/de.less +0 -102
  219. package/src/themes/intl/es.less +0 -102
  220. package/src/themes/intl/fr.less +0 -102
  221. package/src/themes/intl/ja.less +0 -102
  222. package/src/themes/intl/pt.less +0 -102
  223. package/src/themes/intl/zh.less +0 -102
  224. package/src/themes/intl.less +0 -102
  225. package/src/themes/monokai.less +0 -107
  226. package/src/themes/pro-dark.less +0 -147
  227. package/src/themes/pro.less +0 -186
  228. package/src/themes/solarized-dark.less +0 -78
  229. package/src/themes/solarized.less +0 -102
  230. package/src/themes/vaporwave.less +0 -145
  231. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline0.js +0 -0
  232. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline1.js +0 -0
  233. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline2.js +0 -0
  234. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline3.js +0 -0
  235. /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline4.js +0 -0
  236. /package/src/rust/{model → tasks}/copy_export.rs +0 -0
  237. /package/src/rust/{model → tasks}/export_app.rs +0 -0
  238. /package/src/rust/{model → tasks}/export_method.rs +0 -0
  239. /package/src/rust/{model → tasks}/restore_and_render.rs +0 -0
  240. /package/src/rust/{model → tasks}/update_and_render.rs +0 -0
@@ -10,35 +10,23 @@
10
10
  // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
11
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
12
 
13
- use perspective_client::*;
14
13
  use yew::prelude::*;
15
14
 
16
- use crate::PerspectiveProperties;
17
- use crate::session::{Session, ViewStats};
18
- use crate::utils::{AddListener, u32Ext};
15
+ use crate::session::ViewStats;
16
+ use crate::utils::u32Ext;
19
17
 
20
- #[derive(PartialEq, Properties, PerspectiveProperties!)]
18
+ /// Props are now pure value types: no `Session` handle, no PubSub
19
+ /// subscriptions. The parent passes an updated `stats` whenever the
20
+ /// underlying data changes (driven by the root's `UpdateSession` message).
21
+ #[derive(PartialEq, Properties)]
21
22
  pub struct StatusBarRowsCounterProps {
22
- pub session: Session,
23
+ pub stats: Option<ViewStats>,
23
24
  }
24
25
 
25
26
  /// A component to show the current [`Table`]'s dimensions.
26
27
  #[function_component]
27
28
  pub fn StatusBarRowsCounter(props: &StatusBarRowsCounterProps) -> Html {
28
- let stats = use_state_eq(|| props.session.get_table_stats());
29
- use_effect_with(
30
- (props.session.clone(), stats.setter()),
31
- |(session, set_stats)| {
32
- let sub = session.stats_changed.add_listener({
33
- clone!(session, set_stats);
34
- move |_| set_stats.set(session.get_table_stats())
35
- });
36
-
37
- || drop(sub)
38
- },
39
- );
40
-
41
- match props.session.get_table_stats() {
29
+ match props.stats {
42
30
  Some(
43
31
  ViewStats {
44
32
  num_table_cells: Some((tr, tc)),
@@ -16,18 +16,28 @@ use wasm_bindgen::JsValue;
16
16
  use web_sys::*;
17
17
  use yew::prelude::*;
18
18
 
19
- use crate::PerspectiveProperties;
20
19
  use crate::custom_events::CustomEvents;
21
- use crate::model::*;
22
- use crate::renderer::*;
23
- use crate::session::*;
20
+ use crate::renderer::Renderer;
21
+ use crate::session::{Session, TableErrorState, TableLoadState, ViewStats};
24
22
  use crate::utils::*;
25
23
 
26
- #[derive(PartialEq, Properties, PerspectiveProperties!)]
24
+ /// Value-prop version: no PubSub subscriptions, no reducer.
25
+ /// The parent (`StatusBar`) re-renders this component whenever
26
+ /// `update_count`, `error`, or `stats` change (via root's
27
+ /// `IncrementUpdateCount` / `DecrementUpdateCount` / `UpdateSession` messages).
28
+ #[derive(PartialEq, Properties)]
27
29
  pub struct StatusIndicatorProps {
28
30
  pub custom_events: CustomEvents,
29
31
  pub renderer: Renderer,
30
32
  pub session: Session,
33
+ /// Number of in-flight renders (>0 → "updating" spinner).
34
+ pub update_count: u32,
35
+ /// Full error state (if any), used for the error dialog and reconnect.
36
+ pub error: Option<TableErrorState>,
37
+ /// Whether a table has been loaded.
38
+ pub has_table: Option<TableLoadState>,
39
+ /// Row/column statistics — used to distinguish "loading" from "connected".
40
+ pub stats: Option<ViewStats>,
31
41
  }
32
42
 
33
43
  /// An indicator component which displays the current status of the perspective
@@ -35,68 +45,62 @@ pub struct StatusIndicatorProps {
35
45
  /// reconnect callback when in an error state.
36
46
  #[function_component]
37
47
  pub fn StatusIndicator(props: &StatusIndicatorProps) -> Html {
38
- let state = use_reducer_eq(|| {
39
- if let Some(err) = props.session.get_error() {
40
- StatusIconState::Errored(err.message(), err.stacktrace(), err.kind())
41
- } else {
42
- StatusIconState::Normal
43
- }
44
- });
45
-
46
- use_effect_with(
47
- (props.session.clone(), state.dispatcher()),
48
- |(session, set_state)| {
49
- let subs = [
50
- session
51
- .table_errored
52
- .add_listener(set_state.callback(StatusIconStateAction::SetError)),
53
- session
54
- .stats_changed
55
- .add_listener(set_state.callback(StatusIconStateAction::Load)),
56
- session
57
- .view_config_changed
58
- .add_listener(set_state.callback(|_| StatusIconStateAction::Increment)),
59
- session
60
- .view_created
61
- .add_listener(set_state.callback(|_| StatusIconStateAction::Decrement)),
62
- ];
63
-
64
- move || drop(subs)
65
- },
66
- );
48
+ let has_table_cells = props
49
+ .stats
50
+ .as_ref()
51
+ .and_then(|s| s.num_table_cells)
52
+ .is_some();
53
+
54
+ let state = if let Some(err) = &props.error {
55
+ StatusIconState::Errored(
56
+ err.message(),
57
+ err.stacktrace(),
58
+ err.kind(),
59
+ err.is_reconnect(),
60
+ )
61
+ } else if !has_table_cells && matches!(props.has_table, Some(TableLoadState::Loading)) {
62
+ StatusIconState::Loading
63
+ } else if props.update_count > 0 {
64
+ StatusIconState::Updating
65
+ } else if has_table_cells {
66
+ StatusIconState::Normal
67
+ } else {
68
+ StatusIconState::Uninitialized
69
+ };
67
70
 
68
- let class_name = match (&*state, props.session.is_reconnect()) {
69
- (StatusIconState::Errored(..), true) => "errored",
70
- (StatusIconState::Errored(..), false) => "errored disabled",
71
- (StatusIconState::Normal, _) => "connected",
72
- (StatusIconState::Updating(_), _) => "updating",
73
- (StatusIconState::Loading, _) => "loading",
74
- (StatusIconState::Unititialized, _) => "uninitialized",
71
+ let class_name = match &state {
72
+ StatusIconState::Errored(_, _, _, true) => "errored",
73
+ StatusIconState::Errored(_, _, _, false) => "errored disabled",
74
+ StatusIconState::Normal => "connected",
75
+ StatusIconState::Updating => "updating",
76
+ StatusIconState::Loading => "loading",
77
+ StatusIconState::Uninitialized => "uninitialized",
75
78
  };
76
79
 
77
80
  let onclick = use_async_callback(
78
- (props.clone_state(), state.clone()),
79
- async move |_: MouseEvent, (props, state)| {
80
- match &**state {
81
+ (
82
+ props.session.clone(),
83
+ props.renderer.clone(),
84
+ props.custom_events.clone(),
85
+ state.clone(),
86
+ ),
87
+ async move |_: MouseEvent, (session, renderer, custom_events, state)| {
88
+ match &state {
81
89
  StatusIconState::Errored(..) => {
82
- props.session.reconnect().await?;
90
+ session.reconnect().await?;
83
91
  let cfg = ViewConfigUpdate::default();
84
- props.update_and_render(cfg)?.await?;
92
+ session.update_view_config(cfg)?;
93
+ renderer.apply_pending_plugin()?;
94
+ renderer
95
+ .draw(session.validate().await?.create_view())
96
+ .await?;
85
97
  },
86
98
  StatusIconState::Normal => {
87
- props
88
- .custom_events
89
- .dispatch_event("status-indicator-click", JsValue::UNDEFINED)?;
99
+ custom_events.dispatch_event("status-indicator-click", JsValue::UNDEFINED)?;
90
100
  },
91
101
  _ => {},
92
102
  };
93
103
 
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
104
  Ok::<_, ApiError>(())
101
105
  },
102
106
  );
@@ -108,7 +112,7 @@ pub fn StatusIndicator(props: &StatusIndicatorProps) -> Html {
108
112
  <span id="status" class={class_name} />
109
113
  <span id="status_updating" class={class_name} />
110
114
  </div>
111
- if let StatusIconState::Errored(err, stack, kind) = &*state {
115
+ if let StatusIconState::Errored(err, stack, kind, _) = &state {
112
116
  <div class="error-dialog">
113
117
  <div class="error-dialog-message">{ format!("{} {}", kind, err) }</div>
114
118
  <div class="error-dialog-stack">{ stack }</div>
@@ -119,62 +123,11 @@ pub fn StatusIndicator(props: &StatusIndicatorProps) -> Html {
119
123
  }
120
124
  }
121
125
 
122
- #[derive(Clone, Default, Debug, PartialEq)]
126
+ #[derive(Clone, Debug, PartialEq)]
123
127
  enum StatusIconState {
124
128
  Loading,
125
- Updating(u32),
126
- Errored(String, String, &'static str),
129
+ Updating,
130
+ Errored(String, String, &'static str, bool),
127
131
  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
- }
132
+ Uninitialized,
180
133
  }
@@ -40,8 +40,8 @@ impl ModalLink<StringColumnStyle> for StringColumnStyleProps {
40
40
  }
41
41
 
42
42
  impl PartialEq for StringColumnStyleProps {
43
- fn eq(&self, _other: &Self) -> bool {
44
- false
43
+ fn eq(&self, other: &Self) -> bool {
44
+ self.config == other.config && self.default_config == other.default_config
45
45
  }
46
46
  }
47
47
 
@@ -24,7 +24,11 @@ type CSSResource = (&'static str, &'static str);
24
24
  /// A dictionary of CSS fragments for native HTML elements which should always
25
25
  /// be loaded (and perhaps lack yew components wrappers from which to have
26
26
  /// their styles registered).
27
- static DOM_STYLES: &[CSSResource] = &[css!("dom/checkbox"), css!("dom/select")];
27
+ static DOM_STYLES: &[CSSResource] = &[
28
+ css!("dom/checkbox"),
29
+ css!("dom/scrollbar"),
30
+ css!("dom/select"),
31
+ ];
28
32
 
29
33
  thread_local! {
30
34
  /// Cache of `CssStyleSheet` objects, which can safely be re-used across