@perspective-dev/viewer 4.4.1 → 4.5.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.
- package/dist/cdn/perspective-viewer.js +1 -2
- package/dist/cdn/perspective-viewer.js.map +4 -4
- package/dist/css/botanical.css +1 -1
- package/dist/css/dracula.css +1 -1
- package/dist/css/gruvbox-dark.css +1 -1
- package/dist/css/gruvbox.css +1 -1
- package/dist/css/icons.css +1 -1
- package/dist/css/intl/de.css +1 -1
- package/dist/css/intl/es.css +1 -1
- package/dist/css/intl/fr.css +1 -1
- package/dist/css/intl/ja.css +1 -1
- package/dist/css/intl/pt.css +1 -1
- package/dist/css/intl/zh.css +1 -1
- package/dist/css/intl.css +1 -1
- package/dist/css/monokai.css +1 -1
- package/dist/css/phosphor.css +1 -1
- package/dist/css/pro-dark.css +1 -1
- package/dist/css/pro.css +1 -1
- package/dist/css/solarized-dark.css +1 -1
- package/dist/css/solarized.css +1 -1
- package/dist/css/themes.css +1 -1
- package/dist/css/vaporwave.css +1 -1
- package/dist/esm/bootstrap.d.ts +2 -1
- package/dist/esm/column-format.d.ts +51 -0
- package/dist/esm/extensions.d.ts +2 -0
- package/dist/esm/perspective-viewer.d.ts +3 -1
- package/dist/esm/perspective-viewer.inline.js +1 -2
- package/dist/esm/perspective-viewer.inline.js.map +4 -4
- package/dist/esm/perspective-viewer.js +1 -2
- package/dist/esm/perspective-viewer.js.map +4 -4
- package/dist/esm/perspective-viewer.worker.d.ts +2 -0
- package/dist/esm/plugin.d.ts +16 -72
- package/dist/esm/ts-rs/ColumnSelectMode.d.ts +1 -0
- package/dist/esm/ts-rs/PluginStaticConfig.d.ts +77 -0
- package/dist/esm/ts-rs/ViewerConfig.d.ts +6 -3
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +7 -4
- package/dist/wasm/perspective-viewer.d.ts +77 -18
- package/dist/wasm/perspective-viewer.js +293 -144
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +20 -15
- package/package.json +24 -2
- package/src/css/column-selector.css +3 -2
- package/src/css/column-settings-panel.css +35 -6
- package/src/css/column-style.css +27 -2
- package/src/css/containers/scroll-panel.css +2 -1
- package/src/css/containers/tabs.css +8 -52
- package/src/css/dom/checkbox.css +0 -4
- package/src/css/form/code-editor.css +1 -0
- package/src/css/form/debug.css +3 -10
- package/src/css/plugin-selector.css +33 -0
- package/src/css/plugin-settings-panel.css +99 -0
- package/src/css/viewer.css +65 -3
- package/src/rust/components/column_dropdown.rs +3 -1
- package/src/rust/components/column_selector/active_column.rs +13 -19
- package/src/rust/components/column_selector/config_selector.rs +20 -20
- package/src/rust/components/column_selector/filter_column.rs +14 -14
- package/src/rust/components/column_selector/inactive_column.rs +9 -15
- package/src/rust/components/column_selector/pivot_column.rs +7 -7
- package/src/rust/components/column_selector/sort_column.rs +7 -7
- package/src/rust/components/column_selector.rs +55 -37
- package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +15 -7
- package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +394 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +15 -6
- package/src/rust/components/column_settings_sidebar/style_tab.rs +267 -136
- package/src/rust/components/column_settings_sidebar.rs +43 -49
- package/src/rust/components/containers/dragdrop_list.rs +5 -5
- package/src/rust/components/containers/mod.rs +0 -1
- package/src/rust/components/containers/scroll_panel.rs +21 -7
- package/src/rust/components/containers/sidebar.rs +8 -6
- package/src/rust/components/containers/split_panel.rs +3 -3
- package/src/rust/components/containers/tab_list.rs +3 -9
- package/src/rust/components/copy_dropdown.rs +2 -3
- package/src/rust/components/datetime_column_style.rs +19 -81
- package/src/rust/components/editable_header.rs +2 -3
- package/src/rust/components/export_dropdown.rs +2 -3
- package/src/rust/components/expression_editor.rs +29 -17
- package/src/rust/components/filter_dropdown.rs +2 -1
- package/src/rust/components/form/color_range_selector.rs +14 -7
- package/src/rust/components/form/debug.rs +47 -37
- package/src/rust/components/main_panel.rs +24 -65
- package/src/rust/components/mod.rs +2 -1
- package/src/rust/components/number_series_style.rs +161 -0
- package/src/rust/components/plugin_tab.rs +221 -0
- package/src/rust/components/settings_panel.rs +181 -59
- package/src/rust/components/status_bar.rs +140 -173
- package/src/rust/components/status_indicator.rs +15 -22
- package/src/rust/components/string_column_style.rs +20 -82
- package/src/rust/components/style_controls/number_string_format.rs +14 -30
- package/src/rust/components/viewer.rs +92 -131
- package/src/rust/config/column_config_schema.rs +195 -0
- package/src/rust/config/columns_config.rs +4 -97
- package/src/rust/config/datetime_column_style.rs +0 -5
- package/src/rust/config/mod.rs +8 -2
- package/src/rust/config/number_series_style.rs +79 -0
- package/src/rust/config/plugin_static_config.rs +144 -0
- package/src/rust/config/string_column_style.rs +0 -5
- package/src/rust/config/viewer_config.rs +5 -6
- package/src/rust/custom_elements/copy_dropdown.rs +30 -18
- package/src/rust/custom_elements/debug_plugin.rs +1 -3
- package/src/rust/custom_elements/export_dropdown.rs +26 -18
- package/src/rust/custom_elements/viewer.rs +62 -73
- package/src/rust/custom_events.rs +181 -224
- package/src/rust/js/plugin.rs +45 -117
- package/src/rust/lib.rs +34 -5
- package/src/rust/presentation/drag_helpers.rs +206 -0
- package/src/rust/presentation/props.rs +8 -0
- package/src/rust/presentation.rs +256 -41
- package/src/rust/{tasks → queries}/column_locator.rs +17 -73
- package/src/rust/queries/column_values.rs +59 -0
- package/src/rust/{tasks → queries}/columns_iter_set.rs +11 -18
- package/src/rust/queries/exports.rs +96 -0
- package/src/rust/queries/fetch_column_stats.rs +94 -0
- package/src/rust/queries/get_viewer_config.rs +54 -0
- package/src/rust/queries/mod.rs +44 -0
- package/src/rust/queries/plugin_column_styles.rs +101 -0
- package/src/rust/{engines.rs → queries/validate_expression.rs} +26 -15
- package/src/rust/renderer/activate.rs +1 -0
- package/src/rust/renderer/limits.rs +9 -4
- package/src/rust/renderer/plugin_store.rs +12 -0
- package/src/rust/renderer/props.rs +28 -3
- package/src/rust/renderer/registry.rs +40 -15
- package/src/rust/renderer.rs +640 -51
- package/src/rust/session/column_defaults_update.rs +20 -28
- package/src/rust/session/drag_drop_update.rs +10 -10
- package/src/rust/session/metadata.rs +31 -16
- package/src/rust/session/props.rs +15 -6
- package/src/rust/session/view_subscription.rs +10 -0
- package/src/rust/session.rs +109 -147
- package/src/rust/tasks/copy_export.rs +178 -158
- package/src/rust/tasks/{structural.rs → dismiss_render_warning.rs} +20 -40
- package/src/rust/tasks/edit_expression.rs +68 -88
- package/src/rust/tasks/eject.rs +25 -22
- package/src/rust/tasks/intersection_observer.rs +8 -21
- package/src/rust/tasks/mod.rs +19 -21
- package/src/rust/tasks/reset_all.rs +78 -0
- package/src/rust/tasks/resize_observer.rs +11 -33
- package/src/rust/tasks/restore_and_render.rs +117 -90
- package/src/rust/tasks/{get_viewer_config.rs → send_column_config.rs} +38 -35
- package/src/rust/tasks/send_plugin_config.rs +32 -33
- package/src/rust/tasks/update_and_render.rs +66 -47
- package/src/rust/{components/containers/trap_door_panel.rs → tasks/update_theme.rs} +34 -33
- package/src/rust/tasks/validate_expression.rs +61 -0
- package/src/rust/utils/browser/selection.rs +4 -4
- package/src/rust/utils/mod.rs +0 -63
- package/src/svg/mega-menu-icons-density.svg +23 -0
- package/src/svg/mega-menu-icons-map-density.svg +24 -0
- package/src/svg/mega-menu-icons-map-line.svg +19 -0
- package/src/themes/botanical.css +27 -53
- package/src/themes/defaults.css +24 -36
- package/src/themes/dracula.css +36 -54
- package/src/themes/gruvbox-dark.css +39 -59
- package/src/themes/gruvbox.css +16 -28
- package/src/themes/icons.css +3 -0
- package/src/themes/intl/de.css +42 -6
- package/src/themes/intl/es.css +42 -6
- package/src/themes/intl/fr.css +42 -6
- package/src/themes/intl/ja.css +42 -6
- package/src/themes/intl/pt.css +42 -6
- package/src/themes/intl/zh.css +42 -6
- package/src/themes/intl.css +37 -4
- package/src/themes/monokai.css +45 -61
- package/src/themes/phosphor.css +20 -29
- package/src/themes/pro-dark.css +25 -34
- package/src/themes/solarized-dark.css +21 -36
- package/src/themes/solarized.css +13 -23
- package/src/themes/vaporwave.css +40 -74
- package/src/ts/bootstrap.ts +14 -3
- package/src/ts/column-format.ts +162 -0
- package/src/ts/extensions.ts +4 -0
- package/src/ts/perspective-viewer.ts +9 -1
- package/src/{rust/components/column_settings_sidebar/style_tab/stub.rs → ts/perspective-viewer.worker.ts} +2 -22
- package/src/ts/plugin.ts +25 -101
- package/src/ts/ts-rs/{FormatUnit.ts → ColumnSelectMode.ts} +1 -1
- package/src/ts/ts-rs/PluginStaticConfig.ts +78 -0
- package/src/ts/ts-rs/ViewerConfig.ts +1 -2
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +2 -3
- package/dist/esm/ts-rs/ColumnConfigValues.d.ts +0 -31
- package/dist/esm/ts-rs/CustomDatetimeFormat.d.ts +0 -1
- package/dist/esm/ts-rs/CustomDatetimeStyleConfig.d.ts +0 -15
- package/dist/esm/ts-rs/CustomNumberFormatConfig.d.ts +0 -18
- package/dist/esm/ts-rs/DatetimeColorMode.d.ts +0 -1
- package/dist/esm/ts-rs/DatetimeFormatType.d.ts +0 -6
- package/dist/esm/ts-rs/FormatMode.d.ts +0 -1
- package/dist/esm/ts-rs/FormatUnit.d.ts +0 -1
- package/dist/esm/ts-rs/NumberBackgroundMode.d.ts +0 -1
- package/dist/esm/ts-rs/NumberForegroundMode.d.ts +0 -1
- package/dist/esm/ts-rs/PluginConfig.d.ts +0 -2
- package/dist/esm/ts-rs/RoundingMode.d.ts +0 -1
- package/dist/esm/ts-rs/RoundingPriority.d.ts +0 -1
- package/dist/esm/ts-rs/SignDisplay.d.ts +0 -1
- package/dist/esm/ts-rs/SimpleDatetimeFormat.d.ts +0 -1
- package/dist/esm/ts-rs/SimpleDatetimeStyleConfig.d.ts +0 -6
- package/dist/esm/ts-rs/StringColorMode.d.ts +0 -1
- package/dist/esm/ts-rs/TrailingZeroDisplay.d.ts +0 -1
- package/dist/esm/ts-rs/UseGrouping.d.ts +0 -1
- package/src/rust/components/number_column_style.rs +0 -491
- package/src/rust/config/number_column_style.rs +0 -136
- package/src/rust/dragdrop.rs +0 -481
- package/src/rust/tasks/plugin_column_styles.rs +0 -98
- package/src/ts/ts-rs/ColumnConfigValues.ts +0 -14
- package/src/ts/ts-rs/CustomDatetimeFormat.ts +0 -3
- package/src/ts/ts-rs/CustomDatetimeStyleConfig.ts +0 -5
- package/src/ts/ts-rs/CustomNumberFormatConfig.ts +0 -8
- package/src/ts/ts-rs/DatetimeColorMode.ts +0 -3
- package/src/ts/ts-rs/DatetimeFormatType.ts +0 -8
- package/src/ts/ts-rs/FormatMode.ts +0 -3
- package/src/ts/ts-rs/NumberBackgroundMode.ts +0 -3
- package/src/ts/ts-rs/NumberForegroundMode.ts +0 -3
- package/src/ts/ts-rs/PluginConfig.ts +0 -4
- package/src/ts/ts-rs/RoundingMode.ts +0 -3
- package/src/ts/ts-rs/RoundingPriority.ts +0 -3
- package/src/ts/ts-rs/SignDisplay.ts +0 -3
- package/src/ts/ts-rs/SimpleDatetimeFormat.ts +0 -3
- package/src/ts/ts-rs/SimpleDatetimeStyleConfig.ts +0 -4
- package/src/ts/ts-rs/StringColorMode.ts +0 -3
- package/src/ts/ts-rs/TrailingZeroDisplay.ts +0 -3
- package/src/ts/ts-rs/UseGrouping.ts +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline4.js +0 -0
- /package/src/rust/{tasks → config}/export_method.rs +0 -0
- /package/src/rust/{tasks → queries}/export_app.rs +0 -0
- /package/src/rust/{tasks → queries}/is_invalid_drop.rs +0 -0
|
@@ -23,8 +23,11 @@ use super::viewer::PerspectiveViewerElement;
|
|
|
23
23
|
use crate::components::copy_dropdown::CopyDropDownMenu;
|
|
24
24
|
use crate::components::portal::PortalModal;
|
|
25
25
|
use crate::components::style::StyleProvider;
|
|
26
|
+
use crate::config::*;
|
|
26
27
|
use crate::js::*;
|
|
28
|
+
use crate::presentation::Presentation;
|
|
27
29
|
use crate::renderer::*;
|
|
30
|
+
use crate::session::Session;
|
|
28
31
|
use crate::tasks::*;
|
|
29
32
|
use crate::utils::*;
|
|
30
33
|
use crate::*;
|
|
@@ -130,57 +133,66 @@ impl CopyDropDownMenuElement {
|
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
pub fn __set_model(&self, parent: &PerspectiveViewerElement) {
|
|
133
|
-
self.set_config_model(parent)
|
|
136
|
+
self.set_config_model(&parent.session, &parent.renderer, &parent.presentation)
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
pub fn connected_callback(&self) {}
|
|
137
140
|
}
|
|
138
141
|
|
|
139
142
|
impl CopyDropDownMenuElement {
|
|
140
|
-
pub fn new_from_model
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{
|
|
143
|
+
pub fn new_from_model(
|
|
144
|
+
session: &Session,
|
|
145
|
+
renderer: &Renderer,
|
|
146
|
+
presentation: &Presentation,
|
|
147
|
+
) -> Self {
|
|
145
148
|
let dropdown = global::document()
|
|
146
149
|
.create_element("perspective-copy-menu")
|
|
147
150
|
.unwrap()
|
|
148
151
|
.unchecked_into::<HtmlElement>();
|
|
149
152
|
|
|
150
153
|
let elem = Self::new(dropdown);
|
|
151
|
-
elem.set_config_model(
|
|
154
|
+
elem.set_config_model(session, renderer, presentation);
|
|
152
155
|
elem
|
|
153
156
|
}
|
|
154
157
|
|
|
155
|
-
pub fn set_config_model
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
pub fn set_config_model(
|
|
159
|
+
&self,
|
|
160
|
+
session: &Session,
|
|
161
|
+
renderer: &Renderer,
|
|
162
|
+
presentation: &Presentation,
|
|
163
|
+
) {
|
|
160
164
|
let callback = Callback::from({
|
|
161
|
-
let
|
|
165
|
+
let session = session.clone();
|
|
166
|
+
let renderer = renderer.clone();
|
|
167
|
+
let presentation = presentation.clone();
|
|
162
168
|
let target = self.target.clone();
|
|
163
169
|
let root = self.root.clone();
|
|
164
170
|
move |x: ExportFile| {
|
|
165
|
-
let
|
|
171
|
+
let session = session.clone();
|
|
172
|
+
let renderer = renderer.clone();
|
|
173
|
+
let presentation = presentation.clone();
|
|
166
174
|
let target = target.clone();
|
|
167
175
|
let root = root.clone();
|
|
168
176
|
spawn_local(async move {
|
|
169
177
|
let mime = x.method.mimetype(x.is_chart);
|
|
170
|
-
let task =
|
|
178
|
+
let task = export_method_to_blob(&session, &renderer, &presentation, x.method);
|
|
171
179
|
let result = copy_to_clipboard(task, mime).await;
|
|
172
|
-
|
|
180
|
+
let r = (|| -> ApiResult<()> {
|
|
173
181
|
result?;
|
|
174
182
|
*target.borrow_mut() = None;
|
|
175
183
|
if let Some(root) = root.borrow().as_ref() {
|
|
176
184
|
root.send_message(CopyDropDownWrapperMsg::Close);
|
|
177
185
|
}
|
|
178
|
-
|
|
186
|
+
Ok(())
|
|
187
|
+
})();
|
|
188
|
+
if let Err(e) = r {
|
|
189
|
+
web_sys::console::warn_1(&e.into());
|
|
190
|
+
}
|
|
179
191
|
})
|
|
180
192
|
}
|
|
181
193
|
});
|
|
182
194
|
|
|
183
|
-
let renderer =
|
|
195
|
+
let renderer = renderer.clone();
|
|
184
196
|
let init = ShadowRootInit::new(ShadowRootMode::Open);
|
|
185
197
|
let shadow_root = self
|
|
186
198
|
.elem
|
|
@@ -23,6 +23,8 @@ use super::viewer::PerspectiveViewerElement;
|
|
|
23
23
|
use crate::components::export_dropdown::ExportDropDownMenu;
|
|
24
24
|
use crate::components::portal::PortalModal;
|
|
25
25
|
use crate::components::style::StyleProvider;
|
|
26
|
+
use crate::config::*;
|
|
27
|
+
use crate::presentation::Presentation;
|
|
26
28
|
use crate::renderer::*;
|
|
27
29
|
use crate::session::*;
|
|
28
30
|
use crate::tasks::*;
|
|
@@ -132,43 +134,49 @@ impl ExportDropDownMenuElement {
|
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
pub fn __set_model(&self, parent: &PerspectiveViewerElement) {
|
|
135
|
-
self.set_config_model(parent)
|
|
137
|
+
self.set_config_model(&parent.session, &parent.renderer, &parent.presentation)
|
|
136
138
|
}
|
|
137
139
|
|
|
138
140
|
pub fn connected_callback(&self) {}
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
impl ExportDropDownMenuElement {
|
|
142
|
-
pub fn new_from_model
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
{
|
|
144
|
+
pub fn new_from_model(
|
|
145
|
+
session: &Session,
|
|
146
|
+
renderer: &Renderer,
|
|
147
|
+
presentation: &Presentation,
|
|
148
|
+
) -> Self {
|
|
147
149
|
let dropdown = global::document()
|
|
148
150
|
.create_element("perspective-export-menu")
|
|
149
151
|
.unwrap()
|
|
150
152
|
.unchecked_into::<HtmlElement>();
|
|
151
153
|
|
|
152
154
|
let elem = Self::new(dropdown);
|
|
153
|
-
elem.set_config_model(
|
|
155
|
+
elem.set_config_model(session, renderer, presentation);
|
|
154
156
|
elem
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
fn set_config_model
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
fn set_config_model(
|
|
160
|
+
&self,
|
|
161
|
+
session: &Session,
|
|
162
|
+
renderer: &Renderer,
|
|
163
|
+
presentation: &Presentation,
|
|
164
|
+
) {
|
|
162
165
|
let callback = Callback::from({
|
|
163
|
-
let
|
|
166
|
+
let session = session.clone();
|
|
167
|
+
let renderer = renderer.clone();
|
|
168
|
+
let presentation = presentation.clone();
|
|
164
169
|
let target = self.target.clone();
|
|
165
170
|
let root = self.root.clone();
|
|
166
171
|
move |x: ExportFile| {
|
|
167
172
|
if !x.name.is_empty() {
|
|
168
|
-
clone!(target, root,
|
|
173
|
+
clone!(target, root, session, renderer, presentation);
|
|
169
174
|
spawn_local(async move {
|
|
170
|
-
let val =
|
|
171
|
-
|
|
175
|
+
let val =
|
|
176
|
+
export_method_to_blob(&session, &renderer, &presentation, x.method)
|
|
177
|
+
.await
|
|
178
|
+
.unwrap();
|
|
179
|
+
let is_chart = renderer.is_chart();
|
|
172
180
|
download(&x.as_filename(is_chart), &val).unwrap();
|
|
173
181
|
*target.borrow_mut() = None;
|
|
174
182
|
if let Some(root) = root.borrow().as_ref() {
|
|
@@ -179,8 +187,8 @@ impl ExportDropDownMenuElement {
|
|
|
179
187
|
}
|
|
180
188
|
});
|
|
181
189
|
|
|
182
|
-
let renderer =
|
|
183
|
-
let session =
|
|
190
|
+
let renderer = renderer.clone();
|
|
191
|
+
let session = session.clone();
|
|
184
192
|
let init = ShadowRootInit::new(ShadowRootMode::Open);
|
|
185
193
|
let shadow_root = self
|
|
186
194
|
.elem
|
|
@@ -29,9 +29,9 @@ use web_sys::HtmlElement;
|
|
|
29
29
|
use crate::components::viewer::{PerspectiveViewerMsg, PerspectiveViewerProps};
|
|
30
30
|
use crate::config::*;
|
|
31
31
|
use crate::custom_events::*;
|
|
32
|
-
use crate::dragdrop::*;
|
|
33
32
|
use crate::js::*;
|
|
34
33
|
use crate::presentation::*;
|
|
34
|
+
use crate::queries::*;
|
|
35
35
|
use crate::renderer::*;
|
|
36
36
|
use crate::root::Root;
|
|
37
37
|
use crate::session::{ResetOptions, Session, TableLoadState};
|
|
@@ -90,48 +90,17 @@ pub struct PerspectiveViewerElement {
|
|
|
90
90
|
root: Root<components::viewer::PerspectiveViewer>,
|
|
91
91
|
resize_handle: Rc<RefCell<Option<ResizeObserverHandle>>>,
|
|
92
92
|
intersection_handle: Rc<RefCell<Option<IntersectionObserverHandle>>>,
|
|
93
|
-
session: Session,
|
|
94
|
-
renderer: Renderer,
|
|
95
|
-
presentation: Presentation,
|
|
96
|
-
custom_events: CustomEvents,
|
|
93
|
+
pub(crate) session: Session,
|
|
94
|
+
pub(crate) renderer: Renderer,
|
|
95
|
+
pub(crate) presentation: Presentation,
|
|
97
96
|
_subscriptions: Rc<[Subscription; 2]>,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
impl HasCustomEvents for PerspectiveViewerElement {
|
|
101
|
-
fn custom_events(&self) -> &CustomEvents {
|
|
102
|
-
&self.custom_events
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
impl HasPresentation for PerspectiveViewerElement {
|
|
107
|
-
fn presentation(&self) -> &Presentation {
|
|
108
|
-
&self.presentation
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
impl HasRenderer for PerspectiveViewerElement {
|
|
113
|
-
fn renderer(&self) -> &Renderer {
|
|
114
|
-
&self.renderer
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
impl HasSession for PerspectiveViewerElement {
|
|
119
|
-
fn session(&self) -> &Session {
|
|
120
|
-
&self.session
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
impl StateProvider for PerspectiveViewerElement {
|
|
125
|
-
type State = PerspectiveViewerElement;
|
|
126
|
-
|
|
127
|
-
fn clone_state(&self) -> Self::State {
|
|
128
|
-
self.clone()
|
|
129
|
-
}
|
|
97
|
+
_custom_event_subs: Rc<Vec<Subscription>>,
|
|
130
98
|
}
|
|
131
99
|
|
|
132
100
|
impl CustomElementMetadata for PerspectiveViewerElement {
|
|
133
101
|
const CUSTOM_ELEMENT_NAME: &'static str = "perspective-viewer";
|
|
134
|
-
const STATICS: &'static [&'static str] =
|
|
102
|
+
const STATICS: &'static [&'static str] =
|
|
103
|
+
["registerPlugin", "get_wasm_module", "get_worker_url"].as_slice();
|
|
135
104
|
}
|
|
136
105
|
|
|
137
106
|
#[wasm_bindgen]
|
|
@@ -153,7 +122,7 @@ impl PerspectiveViewerElement {
|
|
|
153
122
|
let session = Session::new();
|
|
154
123
|
let renderer = Renderer::new(&elem);
|
|
155
124
|
let presentation = Presentation::new(&elem);
|
|
156
|
-
let
|
|
125
|
+
let custom_event_subs = wire_custom_events(&elem, &session, &renderer, &presentation);
|
|
157
126
|
|
|
158
127
|
// Create Yew App
|
|
159
128
|
let props = yew::props!(PerspectiveViewerProps {
|
|
@@ -161,11 +130,9 @@ impl PerspectiveViewerElement {
|
|
|
161
130
|
session: session.clone(),
|
|
162
131
|
renderer: renderer.clone(),
|
|
163
132
|
presentation: presentation.clone(),
|
|
164
|
-
dragdrop: DragDrop::new(&elem),
|
|
165
|
-
custom_events: custom_events.clone(),
|
|
166
133
|
});
|
|
167
134
|
|
|
168
|
-
let state = props.
|
|
135
|
+
let state = props.clone();
|
|
169
136
|
let root = Root::new(shadow_root, props);
|
|
170
137
|
|
|
171
138
|
// Create callbacks
|
|
@@ -185,7 +152,7 @@ impl PerspectiveViewerElement {
|
|
|
185
152
|
|
|
186
153
|
let eject_sub = presentation.on_eject.add_listener({
|
|
187
154
|
let root = root.clone();
|
|
188
|
-
move |_| ApiFuture::spawn(
|
|
155
|
+
move |_| ApiFuture::spawn(delete_all(&state.session, &state.renderer, &root))
|
|
189
156
|
});
|
|
190
157
|
|
|
191
158
|
let resize_handle =
|
|
@@ -202,8 +169,8 @@ impl PerspectiveViewerElement {
|
|
|
202
169
|
presentation,
|
|
203
170
|
resize_handle: Rc::new(RefCell::new(Some(resize_handle))),
|
|
204
171
|
intersection_handle: Rc::new(RefCell::new(Some(intersect_handle))),
|
|
205
|
-
custom_events,
|
|
206
172
|
_subscriptions: Rc::new([update_sub, eject_sub]),
|
|
173
|
+
_custom_event_subs: Rc::new(custom_event_subs),
|
|
207
174
|
}
|
|
208
175
|
}
|
|
209
176
|
|
|
@@ -370,7 +337,7 @@ impl PerspectiveViewerElement {
|
|
|
370
337
|
/// await viewer.delete();
|
|
371
338
|
/// ```
|
|
372
339
|
pub fn delete(self) -> ApiFuture<()> {
|
|
373
|
-
|
|
340
|
+
delete_all(&self.session, &self.renderer, &self.root)
|
|
374
341
|
}
|
|
375
342
|
|
|
376
343
|
/// Restart this `<perspective-viewer>` to its initial state, before
|
|
@@ -423,12 +390,24 @@ impl PerspectiveViewerElement {
|
|
|
423
390
|
/// [`PerspectiveViewerElement::save`]), and also makes no API calls to the
|
|
424
391
|
/// server (unlike [`PerspectiveViewerElement::getView`] followed by
|
|
425
392
|
/// [`View::get_config`])
|
|
393
|
+
///
|
|
394
|
+
/// Returns the [`ViewConfig`] the currently-bound `View` was constructed
|
|
395
|
+
/// from, so the value is consistent with what the active plugin is
|
|
396
|
+
/// rendering even if a queued [`Self::restore`]/`update_and_render` has
|
|
397
|
+
/// already mutated the live config in anticipation of the next draw.
|
|
398
|
+
/// Falls back to the live session config when no `View` has yet been
|
|
399
|
+
/// created (e.g., after `load` but before the first render).
|
|
426
400
|
#[wasm_bindgen]
|
|
427
401
|
pub fn getViewConfig(&self) -> ApiFuture<JsViewConfig> {
|
|
428
402
|
let session = self.session.clone();
|
|
429
403
|
ApiFuture::new(async move {
|
|
430
|
-
let config = session.
|
|
431
|
-
|
|
404
|
+
let config = if let Some(rendered) = session.get_rendered_view_config() {
|
|
405
|
+
(*rendered).clone()
|
|
406
|
+
} else {
|
|
407
|
+
session.get_view_config().clone()
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
Ok(JsValue::from_serde_ext(&config)?.unchecked_into())
|
|
432
411
|
})
|
|
433
412
|
}
|
|
434
413
|
|
|
@@ -595,8 +574,12 @@ impl PerspectiveViewerElement {
|
|
|
595
574
|
None
|
|
596
575
|
};
|
|
597
576
|
|
|
598
|
-
let result =
|
|
599
|
-
.
|
|
577
|
+
let result = restore_and_render(
|
|
578
|
+
&this.session,
|
|
579
|
+
&this.renderer,
|
|
580
|
+
&this.presentation,
|
|
581
|
+
decoded_update.clone(),
|
|
582
|
+
{
|
|
600
583
|
clone!(this, decoded_update.table);
|
|
601
584
|
async move {
|
|
602
585
|
if let OptionalUpdate::Update(name) = table {
|
|
@@ -614,11 +597,12 @@ impl PerspectiveViewerElement {
|
|
|
614
597
|
receiver.await.unwrap_or_log();
|
|
615
598
|
Ok(())
|
|
616
599
|
}
|
|
617
|
-
}
|
|
618
|
-
|
|
600
|
+
},
|
|
601
|
+
)
|
|
602
|
+
.await;
|
|
619
603
|
|
|
620
604
|
if let Err(e) = &result {
|
|
621
|
-
this.session
|
|
605
|
+
this.session.set_error(false, e.clone()).await?;
|
|
622
606
|
}
|
|
623
607
|
result
|
|
624
608
|
})
|
|
@@ -631,7 +615,7 @@ impl PerspectiveViewerElement {
|
|
|
631
615
|
ApiFuture::spawn(self.session.reset(ResetOptions::default()));
|
|
632
616
|
let this = self.clone();
|
|
633
617
|
ApiFuture::new_throttled(async move {
|
|
634
|
-
this.
|
|
618
|
+
update_and_render(&this.session, &this.renderer, ViewConfigUpdate::default())?.await?;
|
|
635
619
|
Ok(())
|
|
636
620
|
})
|
|
637
621
|
}
|
|
@@ -661,7 +645,9 @@ impl PerspectiveViewerElement {
|
|
|
661
645
|
let viewer_config = this
|
|
662
646
|
.renderer
|
|
663
647
|
.clone()
|
|
664
|
-
.with_lock(async {
|
|
648
|
+
.with_lock(async {
|
|
649
|
+
get_viewer_config(&this.session, &this.renderer, &this.presentation).await
|
|
650
|
+
})
|
|
665
651
|
.await?;
|
|
666
652
|
|
|
667
653
|
viewer_config.encode()
|
|
@@ -696,7 +682,9 @@ impl PerspectiveViewerElement {
|
|
|
696
682
|
ExportMethod::Csv
|
|
697
683
|
};
|
|
698
684
|
|
|
699
|
-
let blob =
|
|
685
|
+
let blob =
|
|
686
|
+
export_method_to_blob(&this.session, &this.renderer, &this.presentation, method)
|
|
687
|
+
.await?;
|
|
700
688
|
let is_chart = this.renderer.is_chart();
|
|
701
689
|
download(
|
|
702
690
|
format!("untitled{}", method.as_filename(is_chart)).as_ref(),
|
|
@@ -711,7 +699,7 @@ impl PerspectiveViewerElement {
|
|
|
711
699
|
///
|
|
712
700
|
/// This method is only really useful for the `"plugin"` method, which
|
|
713
701
|
/// will use the configured plugin's export (e.g. PNG for
|
|
714
|
-
/// `@perspective-dev/viewer-
|
|
702
|
+
/// `@perspective-dev/viewer-charts`). Otherwise, prefer to call the
|
|
715
703
|
/// equivalent method on the underlying [`View`] directly.
|
|
716
704
|
///
|
|
717
705
|
/// # Arguments
|
|
@@ -735,7 +723,8 @@ impl PerspectiveViewerElement {
|
|
|
735
723
|
ExportMethod::Csv
|
|
736
724
|
};
|
|
737
725
|
|
|
738
|
-
this.
|
|
726
|
+
export_method_to_jsvalue(&this.session, &this.renderer, &this.presentation, method)
|
|
727
|
+
.await
|
|
739
728
|
})
|
|
740
729
|
}
|
|
741
730
|
|
|
@@ -766,7 +755,8 @@ impl PerspectiveViewerElement {
|
|
|
766
755
|
ExportMethod::Csv
|
|
767
756
|
};
|
|
768
757
|
|
|
769
|
-
let js_task =
|
|
758
|
+
let js_task =
|
|
759
|
+
export_method_to_blob(&this.session, &this.renderer, &this.presentation, method);
|
|
770
760
|
copy_to_clipboard(js_task, MimeType::TextPlain).await
|
|
771
761
|
})
|
|
772
762
|
}
|
|
@@ -827,19 +817,18 @@ impl PerspectiveViewerElement {
|
|
|
827
817
|
.unwrap_or_default()
|
|
828
818
|
.unwrap_or_default();
|
|
829
819
|
|
|
830
|
-
let state = self.
|
|
820
|
+
let state = self.clone();
|
|
831
821
|
ApiFuture::new_throttled(async move {
|
|
832
|
-
if !state.renderer
|
|
833
|
-
state
|
|
834
|
-
.update_and_render(ViewConfigUpdate::default())?
|
|
822
|
+
if !state.renderer.is_plugin_activated()? {
|
|
823
|
+
update_and_render(&state.session, &state.renderer, ViewConfigUpdate::default())?
|
|
835
824
|
.await?;
|
|
836
825
|
} else if let Some(dims) = opts.dimensions {
|
|
837
826
|
state
|
|
838
|
-
.renderer
|
|
827
|
+
.renderer
|
|
839
828
|
.resize_with_dimensions(dims.width, dims.height)
|
|
840
829
|
.await?;
|
|
841
830
|
} else {
|
|
842
|
-
state.renderer
|
|
831
|
+
state.renderer.resize().await?;
|
|
843
832
|
}
|
|
844
833
|
|
|
845
834
|
Ok(())
|
|
@@ -914,9 +903,13 @@ impl PerspectiveViewerElement {
|
|
|
914
903
|
} else {
|
|
915
904
|
*self.intersection_handle.borrow_mut() = None;
|
|
916
905
|
if self.session.set_pause(false) {
|
|
917
|
-
return ApiFuture::new(
|
|
918
|
-
self.
|
|
919
|
-
|
|
906
|
+
return ApiFuture::new(restore_and_render(
|
|
907
|
+
&self.session,
|
|
908
|
+
&self.renderer,
|
|
909
|
+
&self.presentation,
|
|
910
|
+
ViewerConfigUpdate::default(),
|
|
911
|
+
async move { Ok(()) },
|
|
912
|
+
));
|
|
920
913
|
}
|
|
921
914
|
}
|
|
922
915
|
|
|
@@ -934,10 +927,6 @@ impl PerspectiveViewerElement {
|
|
|
934
927
|
#[wasm_bindgen]
|
|
935
928
|
pub fn setSelection(&self, window: Option<JsViewWindow>) -> ApiResult<()> {
|
|
936
929
|
let window = window.map(|x| x.into_serde_ext()).transpose()?;
|
|
937
|
-
if self.renderer.get_selection() != window {
|
|
938
|
-
self.custom_events.dispatch_select(window.as_ref())?;
|
|
939
|
-
}
|
|
940
|
-
|
|
941
930
|
self.renderer.set_selection(window);
|
|
942
931
|
Ok(())
|
|
943
932
|
}
|
|
@@ -1108,7 +1097,7 @@ impl PerspectiveViewerElement {
|
|
|
1108
1097
|
pub fn toggleColumnSettings(&self, column_name: String) -> ApiFuture<()> {
|
|
1109
1098
|
clone!(self.session, self.root);
|
|
1110
1099
|
ApiFuture::new_throttled(async move {
|
|
1111
|
-
let locator = session.
|
|
1100
|
+
let locator = get_column_locator(&session.metadata(), Some(column_name));
|
|
1112
1101
|
let (sender, receiver) = channel::<()>();
|
|
1113
1102
|
root.borrow().as_ref().into_apierror()?.send_message(
|
|
1114
1103
|
PerspectiveViewerMsg::OpenColumnSettings {
|
|
@@ -1130,7 +1119,7 @@ impl PerspectiveViewerElement {
|
|
|
1130
1119
|
column_name: Option<String>,
|
|
1131
1120
|
toggle: Option<bool>,
|
|
1132
1121
|
) -> ApiFuture<()> {
|
|
1133
|
-
let locator = self.
|
|
1122
|
+
let locator = get_column_locator(&self.session.metadata(), column_name);
|
|
1134
1123
|
clone!(self.root);
|
|
1135
1124
|
ApiFuture::new_throttled(async move {
|
|
1136
1125
|
let (sender, receiver) = channel::<()>();
|