@perspective-dev/viewer 4.4.0 → 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 -0
- 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 +6 -0
- package/dist/esm/perspective-viewer.d.ts +4 -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 +21 -77
- 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 +39 -0
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +7 -4
- package/dist/wasm/perspective-viewer.d.ts +88 -24
- package/dist/wasm/perspective-viewer.js +320 -151
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +22 -17
- package/package.json +24 -2
- package/src/css/column-selector.css +3 -2
- package/src/css/column-settings-panel.css +36 -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/status-bar.css +1 -1
- 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 -132
- 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 +7 -8
- package/src/rust/custom_elements/copy_dropdown.rs +30 -18
- package/src/rust/custom_elements/debug_plugin.rs +5 -7
- package/src/rust/custom_elements/export_dropdown.rs +26 -18
- package/src/rust/custom_elements/viewer.rs +77 -77
- package/src/rust/custom_events.rs +181 -224
- package/src/rust/js/plugin.rs +45 -117
- package/src/rust/lib.rs +39 -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 +649 -55
- 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 -89
- 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/datagrid-select-row-tree.svg +13 -0
- 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 +42 -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 +4 -18
- 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 +175 -0
- 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/themes.css +1 -0
- 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 +12 -1
- package/src/ts/perspective-viewer.ts +10 -1
- package/src/{rust/components/column_settings_sidebar/style_tab/stub.rs → ts/perspective-viewer.worker.ts} +2 -22
- package/src/ts/plugin.ts +29 -105
- 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 +14 -0
- 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 -483
- package/src/rust/config/number_column_style.rs +0 -132
- 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-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → 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
|
|
@@ -93,16 +93,14 @@ impl PerspectiveDebugPluginElement {
|
|
|
93
93
|
ApiFuture::default()
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
pub fn restyle(&self)
|
|
97
|
-
ApiFuture::default()
|
|
98
|
-
}
|
|
96
|
+
pub fn restyle(&self) {}
|
|
99
97
|
|
|
100
|
-
pub fn save(&self) ->
|
|
101
|
-
|
|
98
|
+
pub fn save(&self) -> ApiResult<JsValue> {
|
|
99
|
+
Ok(JsValue::null())
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
pub fn restore(&self) ->
|
|
105
|
-
|
|
102
|
+
pub fn restore(&self, _config: Option<JsValue>) -> ApiResult<()> {
|
|
103
|
+
Ok(())
|
|
106
104
|
}
|
|
107
105
|
|
|
108
106
|
pub fn delete(&self) -> ApiFuture<()> {
|
|
@@ -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};
|
|
@@ -39,6 +39,15 @@ use crate::tasks::*;
|
|
|
39
39
|
use crate::utils::*;
|
|
40
40
|
use crate::*;
|
|
41
41
|
|
|
42
|
+
#[wasm_bindgen]
|
|
43
|
+
extern "C" {
|
|
44
|
+
#[wasm_bindgen(typescript_type = "Promise<ViewerConfig>")]
|
|
45
|
+
pub type JsViewerConfigPromise;
|
|
46
|
+
|
|
47
|
+
#[wasm_bindgen(typescript_type = "ViewerConfigUpdate")]
|
|
48
|
+
pub type JsViewerConfigUpdate;
|
|
49
|
+
}
|
|
50
|
+
|
|
42
51
|
#[derive(serde::Deserialize, Default)]
|
|
43
52
|
struct ResizeOptions {
|
|
44
53
|
dimensions: Option<ResizeDimensions>,
|
|
@@ -81,48 +90,17 @@ pub struct PerspectiveViewerElement {
|
|
|
81
90
|
root: Root<components::viewer::PerspectiveViewer>,
|
|
82
91
|
resize_handle: Rc<RefCell<Option<ResizeObserverHandle>>>,
|
|
83
92
|
intersection_handle: Rc<RefCell<Option<IntersectionObserverHandle>>>,
|
|
84
|
-
session: Session,
|
|
85
|
-
renderer: Renderer,
|
|
86
|
-
presentation: Presentation,
|
|
87
|
-
custom_events: CustomEvents,
|
|
93
|
+
pub(crate) session: Session,
|
|
94
|
+
pub(crate) renderer: Renderer,
|
|
95
|
+
pub(crate) presentation: Presentation,
|
|
88
96
|
_subscriptions: Rc<[Subscription; 2]>,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
impl HasCustomEvents for PerspectiveViewerElement {
|
|
92
|
-
fn custom_events(&self) -> &CustomEvents {
|
|
93
|
-
&self.custom_events
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
impl HasPresentation for PerspectiveViewerElement {
|
|
98
|
-
fn presentation(&self) -> &Presentation {
|
|
99
|
-
&self.presentation
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
impl HasRenderer for PerspectiveViewerElement {
|
|
104
|
-
fn renderer(&self) -> &Renderer {
|
|
105
|
-
&self.renderer
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
impl HasSession for PerspectiveViewerElement {
|
|
110
|
-
fn session(&self) -> &Session {
|
|
111
|
-
&self.session
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
impl StateProvider for PerspectiveViewerElement {
|
|
116
|
-
type State = PerspectiveViewerElement;
|
|
117
|
-
|
|
118
|
-
fn clone_state(&self) -> Self::State {
|
|
119
|
-
self.clone()
|
|
120
|
-
}
|
|
97
|
+
_custom_event_subs: Rc<Vec<Subscription>>,
|
|
121
98
|
}
|
|
122
99
|
|
|
123
100
|
impl CustomElementMetadata for PerspectiveViewerElement {
|
|
124
101
|
const CUSTOM_ELEMENT_NAME: &'static str = "perspective-viewer";
|
|
125
|
-
const STATICS: &'static [&'static str] =
|
|
102
|
+
const STATICS: &'static [&'static str] =
|
|
103
|
+
["registerPlugin", "get_wasm_module", "get_worker_url"].as_slice();
|
|
126
104
|
}
|
|
127
105
|
|
|
128
106
|
#[wasm_bindgen]
|
|
@@ -144,7 +122,7 @@ impl PerspectiveViewerElement {
|
|
|
144
122
|
let session = Session::new();
|
|
145
123
|
let renderer = Renderer::new(&elem);
|
|
146
124
|
let presentation = Presentation::new(&elem);
|
|
147
|
-
let
|
|
125
|
+
let custom_event_subs = wire_custom_events(&elem, &session, &renderer, &presentation);
|
|
148
126
|
|
|
149
127
|
// Create Yew App
|
|
150
128
|
let props = yew::props!(PerspectiveViewerProps {
|
|
@@ -152,11 +130,9 @@ impl PerspectiveViewerElement {
|
|
|
152
130
|
session: session.clone(),
|
|
153
131
|
renderer: renderer.clone(),
|
|
154
132
|
presentation: presentation.clone(),
|
|
155
|
-
dragdrop: DragDrop::new(&elem),
|
|
156
|
-
custom_events: custom_events.clone(),
|
|
157
133
|
});
|
|
158
134
|
|
|
159
|
-
let state = props.
|
|
135
|
+
let state = props.clone();
|
|
160
136
|
let root = Root::new(shadow_root, props);
|
|
161
137
|
|
|
162
138
|
// Create callbacks
|
|
@@ -176,7 +152,7 @@ impl PerspectiveViewerElement {
|
|
|
176
152
|
|
|
177
153
|
let eject_sub = presentation.on_eject.add_listener({
|
|
178
154
|
let root = root.clone();
|
|
179
|
-
move |_| ApiFuture::spawn(
|
|
155
|
+
move |_| ApiFuture::spawn(delete_all(&state.session, &state.renderer, &root))
|
|
180
156
|
});
|
|
181
157
|
|
|
182
158
|
let resize_handle =
|
|
@@ -193,8 +169,8 @@ impl PerspectiveViewerElement {
|
|
|
193
169
|
presentation,
|
|
194
170
|
resize_handle: Rc::new(RefCell::new(Some(resize_handle))),
|
|
195
171
|
intersection_handle: Rc::new(RefCell::new(Some(intersect_handle))),
|
|
196
|
-
custom_events,
|
|
197
172
|
_subscriptions: Rc::new([update_sub, eject_sub]),
|
|
173
|
+
_custom_event_subs: Rc::new(custom_event_subs),
|
|
198
174
|
}
|
|
199
175
|
}
|
|
200
176
|
|
|
@@ -361,7 +337,7 @@ impl PerspectiveViewerElement {
|
|
|
361
337
|
/// await viewer.delete();
|
|
362
338
|
/// ```
|
|
363
339
|
pub fn delete(self) -> ApiFuture<()> {
|
|
364
|
-
|
|
340
|
+
delete_all(&self.session, &self.renderer, &self.root)
|
|
365
341
|
}
|
|
366
342
|
|
|
367
343
|
/// Restart this `<perspective-viewer>` to its initial state, before
|
|
@@ -414,12 +390,24 @@ impl PerspectiveViewerElement {
|
|
|
414
390
|
/// [`PerspectiveViewerElement::save`]), and also makes no API calls to the
|
|
415
391
|
/// server (unlike [`PerspectiveViewerElement::getView`] followed by
|
|
416
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).
|
|
417
400
|
#[wasm_bindgen]
|
|
418
401
|
pub fn getViewConfig(&self) -> ApiFuture<JsViewConfig> {
|
|
419
402
|
let session = self.session.clone();
|
|
420
403
|
ApiFuture::new(async move {
|
|
421
|
-
let config = session.
|
|
422
|
-
|
|
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())
|
|
423
411
|
})
|
|
424
412
|
}
|
|
425
413
|
|
|
@@ -563,7 +551,7 @@ impl PerspectiveViewerElement {
|
|
|
563
551
|
/// ```javascript
|
|
564
552
|
/// await viewer.restore({group_by: ["State"]});
|
|
565
553
|
/// ```
|
|
566
|
-
pub fn restore(&self, update:
|
|
554
|
+
pub fn restore(&self, update: JsViewerConfigUpdate) -> ApiFuture<()> {
|
|
567
555
|
let this = self.clone();
|
|
568
556
|
ApiFuture::new_throttled(async move {
|
|
569
557
|
let decoded_update = ViewerConfigUpdate::decode(&update)?;
|
|
@@ -586,8 +574,12 @@ impl PerspectiveViewerElement {
|
|
|
586
574
|
None
|
|
587
575
|
};
|
|
588
576
|
|
|
589
|
-
let result =
|
|
590
|
-
.
|
|
577
|
+
let result = restore_and_render(
|
|
578
|
+
&this.session,
|
|
579
|
+
&this.renderer,
|
|
580
|
+
&this.presentation,
|
|
581
|
+
decoded_update.clone(),
|
|
582
|
+
{
|
|
591
583
|
clone!(this, decoded_update.table);
|
|
592
584
|
async move {
|
|
593
585
|
if let OptionalUpdate::Update(name) = table {
|
|
@@ -605,11 +597,12 @@ impl PerspectiveViewerElement {
|
|
|
605
597
|
receiver.await.unwrap_or_log();
|
|
606
598
|
Ok(())
|
|
607
599
|
}
|
|
608
|
-
}
|
|
609
|
-
|
|
600
|
+
},
|
|
601
|
+
)
|
|
602
|
+
.await;
|
|
610
603
|
|
|
611
604
|
if let Err(e) = &result {
|
|
612
|
-
this.session
|
|
605
|
+
this.session.set_error(false, e.clone()).await?;
|
|
613
606
|
}
|
|
614
607
|
result
|
|
615
608
|
})
|
|
@@ -622,7 +615,7 @@ impl PerspectiveViewerElement {
|
|
|
622
615
|
ApiFuture::spawn(self.session.reset(ResetOptions::default()));
|
|
623
616
|
let this = self.clone();
|
|
624
617
|
ApiFuture::new_throttled(async move {
|
|
625
|
-
this.
|
|
618
|
+
update_and_render(&this.session, &this.renderer, ViewConfigUpdate::default())?.await?;
|
|
626
619
|
Ok(())
|
|
627
620
|
})
|
|
628
621
|
}
|
|
@@ -646,17 +639,21 @@ impl PerspectiveViewerElement {
|
|
|
646
639
|
/// await viewer.restore(token);
|
|
647
640
|
/// });
|
|
648
641
|
/// ```
|
|
649
|
-
pub fn save(&self) ->
|
|
642
|
+
pub fn save(&self) -> JsViewerConfigPromise {
|
|
650
643
|
let this = self.clone();
|
|
651
|
-
ApiFuture::new(async move {
|
|
644
|
+
let fut = ApiFuture::new(async move {
|
|
652
645
|
let viewer_config = this
|
|
653
646
|
.renderer
|
|
654
647
|
.clone()
|
|
655
|
-
.with_lock(async {
|
|
648
|
+
.with_lock(async {
|
|
649
|
+
get_viewer_config(&this.session, &this.renderer, &this.presentation).await
|
|
650
|
+
})
|
|
656
651
|
.await?;
|
|
657
652
|
|
|
658
653
|
viewer_config.encode()
|
|
659
|
-
})
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
js_sys::Promise::from(fut).unchecked_into()
|
|
660
657
|
}
|
|
661
658
|
|
|
662
659
|
/// Download this viewer's internal [`View`] data via a browser download
|
|
@@ -685,7 +682,9 @@ impl PerspectiveViewerElement {
|
|
|
685
682
|
ExportMethod::Csv
|
|
686
683
|
};
|
|
687
684
|
|
|
688
|
-
let blob =
|
|
685
|
+
let blob =
|
|
686
|
+
export_method_to_blob(&this.session, &this.renderer, &this.presentation, method)
|
|
687
|
+
.await?;
|
|
689
688
|
let is_chart = this.renderer.is_chart();
|
|
690
689
|
download(
|
|
691
690
|
format!("untitled{}", method.as_filename(is_chart)).as_ref(),
|
|
@@ -700,7 +699,7 @@ impl PerspectiveViewerElement {
|
|
|
700
699
|
///
|
|
701
700
|
/// This method is only really useful for the `"plugin"` method, which
|
|
702
701
|
/// will use the configured plugin's export (e.g. PNG for
|
|
703
|
-
/// `@perspective-dev/viewer-
|
|
702
|
+
/// `@perspective-dev/viewer-charts`). Otherwise, prefer to call the
|
|
704
703
|
/// equivalent method on the underlying [`View`] directly.
|
|
705
704
|
///
|
|
706
705
|
/// # Arguments
|
|
@@ -724,7 +723,8 @@ impl PerspectiveViewerElement {
|
|
|
724
723
|
ExportMethod::Csv
|
|
725
724
|
};
|
|
726
725
|
|
|
727
|
-
this.
|
|
726
|
+
export_method_to_jsvalue(&this.session, &this.renderer, &this.presentation, method)
|
|
727
|
+
.await
|
|
728
728
|
})
|
|
729
729
|
}
|
|
730
730
|
|
|
@@ -755,7 +755,8 @@ impl PerspectiveViewerElement {
|
|
|
755
755
|
ExportMethod::Csv
|
|
756
756
|
};
|
|
757
757
|
|
|
758
|
-
let js_task =
|
|
758
|
+
let js_task =
|
|
759
|
+
export_method_to_blob(&this.session, &this.renderer, &this.presentation, method);
|
|
759
760
|
copy_to_clipboard(js_task, MimeType::TextPlain).await
|
|
760
761
|
})
|
|
761
762
|
}
|
|
@@ -816,19 +817,18 @@ impl PerspectiveViewerElement {
|
|
|
816
817
|
.unwrap_or_default()
|
|
817
818
|
.unwrap_or_default();
|
|
818
819
|
|
|
819
|
-
let state = self.
|
|
820
|
+
let state = self.clone();
|
|
820
821
|
ApiFuture::new_throttled(async move {
|
|
821
|
-
if !state.renderer
|
|
822
|
-
state
|
|
823
|
-
.update_and_render(ViewConfigUpdate::default())?
|
|
822
|
+
if !state.renderer.is_plugin_activated()? {
|
|
823
|
+
update_and_render(&state.session, &state.renderer, ViewConfigUpdate::default())?
|
|
824
824
|
.await?;
|
|
825
825
|
} else if let Some(dims) = opts.dimensions {
|
|
826
826
|
state
|
|
827
|
-
.renderer
|
|
827
|
+
.renderer
|
|
828
828
|
.resize_with_dimensions(dims.width, dims.height)
|
|
829
829
|
.await?;
|
|
830
830
|
} else {
|
|
831
|
-
state.renderer
|
|
831
|
+
state.renderer.resize().await?;
|
|
832
832
|
}
|
|
833
833
|
|
|
834
834
|
Ok(())
|
|
@@ -903,9 +903,13 @@ impl PerspectiveViewerElement {
|
|
|
903
903
|
} else {
|
|
904
904
|
*self.intersection_handle.borrow_mut() = None;
|
|
905
905
|
if self.session.set_pause(false) {
|
|
906
|
-
return ApiFuture::new(
|
|
907
|
-
self.
|
|
908
|
-
|
|
906
|
+
return ApiFuture::new(restore_and_render(
|
|
907
|
+
&self.session,
|
|
908
|
+
&self.renderer,
|
|
909
|
+
&self.presentation,
|
|
910
|
+
ViewerConfigUpdate::default(),
|
|
911
|
+
async move { Ok(()) },
|
|
912
|
+
));
|
|
909
913
|
}
|
|
910
914
|
}
|
|
911
915
|
|
|
@@ -923,10 +927,6 @@ impl PerspectiveViewerElement {
|
|
|
923
927
|
#[wasm_bindgen]
|
|
924
928
|
pub fn setSelection(&self, window: Option<JsViewWindow>) -> ApiResult<()> {
|
|
925
929
|
let window = window.map(|x| x.into_serde_ext()).transpose()?;
|
|
926
|
-
if self.renderer.get_selection() != window {
|
|
927
|
-
self.custom_events.dispatch_select(window.as_ref())?;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
930
|
self.renderer.set_selection(window);
|
|
931
931
|
Ok(())
|
|
932
932
|
}
|
|
@@ -1097,7 +1097,7 @@ impl PerspectiveViewerElement {
|
|
|
1097
1097
|
pub fn toggleColumnSettings(&self, column_name: String) -> ApiFuture<()> {
|
|
1098
1098
|
clone!(self.session, self.root);
|
|
1099
1099
|
ApiFuture::new_throttled(async move {
|
|
1100
|
-
let locator = session.
|
|
1100
|
+
let locator = get_column_locator(&session.metadata(), Some(column_name));
|
|
1101
1101
|
let (sender, receiver) = channel::<()>();
|
|
1102
1102
|
root.borrow().as_ref().into_apierror()?.send_message(
|
|
1103
1103
|
PerspectiveViewerMsg::OpenColumnSettings {
|
|
@@ -1119,7 +1119,7 @@ impl PerspectiveViewerElement {
|
|
|
1119
1119
|
column_name: Option<String>,
|
|
1120
1120
|
toggle: Option<bool>,
|
|
1121
1121
|
) -> ApiFuture<()> {
|
|
1122
|
-
let locator = self.
|
|
1122
|
+
let locator = get_column_locator(&self.session.metadata(), column_name);
|
|
1123
1123
|
clone!(self.root);
|
|
1124
1124
|
ApiFuture::new_throttled(async move {
|
|
1125
1125
|
let (sender, receiver) = channel::<()>();
|