@perspective-dev/viewer 5.3.1 → 5.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 +6 -6
- package/dist/cdn/perspective-viewer.js.map +2 -2
- package/dist/css/blueprint.css +1 -1
- package/dist/css/botanical.css +1 -1
- package/dist/css/dracula.css +1 -1
- package/dist/css/eggplant.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/ar.css +1 -0
- 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/ledger.css +1 -1
- package/dist/css/monokai.css +1 -1
- package/dist/css/nord.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/css/velvet.css +1 -1
- package/dist/docs/perspective-docs.json +1 -1
- package/dist/esm/extensions.d.ts +0 -5
- package/dist/esm/perspective-viewer.d.ts +2 -0
- package/dist/esm/perspective-viewer.inline.js +8 -8
- package/dist/esm/perspective-viewer.inline.js.map +2 -2
- package/dist/esm/perspective-viewer.js +5 -5
- package/dist/esm/perspective-viewer.js.map +2 -2
- package/dist/esm/plugin.d.ts +9 -0
- package/dist/esm/ts-rs/AddPanelOptions.d.ts +9 -0
- package/dist/esm/ts-rs/GetViewMode.d.ts +4 -0
- package/dist/esm/ts-rs/GetViewOptions.d.ts +8 -0
- package/dist/esm/ts-rs/RestoreOptions.d.ts +6 -0
- package/dist/esm/ts-rs/RestoreWorkspaceOptions.d.ts +9 -0
- package/dist/esm/ts-rs/ViewOnUpdateResp.d.ts +1 -1
- package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +30 -22
- package/dist/wasm/perspective-viewer.d.ts +137 -104
- package/dist/wasm/perspective-viewer.js +337 -269
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +20 -30
- package/package.json +7 -7
- package/src/css/_context_menu.css +1 -1
- package/src/css/_dropdown_menu.css +1 -1
- package/src/css/_viewer_bundle.css +7 -8
- package/src/css/column-dropdown.css +0 -3
- package/src/css/column-selector.css +18 -7
- package/src/css/column-settings-panel.css +0 -225
- package/src/css/column-style.css +175 -0
- package/src/css/config-selector.css +19 -11
- package/src/css/filter-dropdown.css +5 -5
- package/src/css/form/debug.css +37 -4
- package/src/css/function-dropdown.css +5 -5
- package/src/css/panel-tab.css +23 -0
- package/src/css/plugin-selector.css +5 -5
- package/src/css/render-warning.css +1 -1
- package/src/css/status-bar.css +63 -21
- package/src/css/type-icon.css +1 -3
- package/src/css/{containers → ui/containers}/context-menu.css +22 -16
- package/src/css/ui/containers/dropdown-menu-items.css +66 -0
- package/src/css/{containers → ui/containers}/dropdown-menu.css +8 -53
- package/src/css/{containers → ui/containers}/tabs.css +2 -1
- package/src/css/viewer.css +32 -26
- package/src/rust/agent/tools.rs +80 -7
- package/src/rust/components/chat_panel.rs +1 -1
- package/src/rust/components/{form/code_editor.rs → code_editor.rs} +4 -2
- package/src/rust/components/column_dropdown.rs +2 -2
- package/src/rust/components/column_selector/active_column.rs +24 -9
- package/src/rust/components/column_selector/aggregate_selector.rs +1 -1
- package/src/rust/components/column_selector/config_selector.rs +2 -2
- package/src/rust/components/column_selector/filter_column.rs +8 -5
- package/src/rust/components/column_selector/inactive_column.rs +4 -2
- package/src/rust/components/column_selector/pivot_column.rs +4 -3
- package/src/rust/components/column_selector/sort_column.rs +7 -4
- package/src/rust/components/column_selector.rs +14 -3
- package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab/alignment_field.rs +90 -0
- package/src/rust/components/column_settings_sidebar/style_tab/font_field.rs +267 -0
- package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +16 -18
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab.rs +70 -12
- package/src/rust/components/column_settings_sidebar.rs +3 -4
- package/src/rust/components/copy_dropdown.rs +1 -1
- package/src/rust/components/datetime_column_style/custom.rs +1 -3
- package/src/rust/components/datetime_column_style/simple.rs +1 -2
- package/src/rust/components/datetime_column_style.rs +1 -2
- package/src/rust/components/{form/debug.rs → debug_panel.rs} +112 -55
- package/src/rust/components/{containers/dragdrop_list.rs → dragdrop_list.rs} +2 -10
- package/src/rust/components/export_dropdown.rs +1 -1
- package/src/rust/components/expression_editor.rs +1 -1
- package/src/rust/components/filter_dropdown.rs +2 -2
- package/src/rust/components/function_dropdown.rs +2 -2
- package/src/rust/components/main_panel/frame_theme.rs +3 -59
- package/src/rust/components/main_panel/msg.rs +4 -0
- package/src/rust/components/main_panel/reconcile.rs +9 -4
- package/src/rust/components/main_panel/render.rs +62 -11
- package/src/rust/components/main_panel/update.rs +39 -10
- package/src/rust/components/main_panel.rs +40 -2
- package/src/rust/components/mod.rs +5 -8
- package/src/rust/components/new_panel_menu.rs +97 -0
- package/src/rust/components/number_series_style.rs +2 -3
- package/src/rust/components/panel_menu.rs +61 -87
- package/src/rust/components/panel_tab.rs +100 -43
- package/src/rust/components/plugin_tab.rs +58 -4
- package/src/rust/components/render_warning.rs +2 -2
- package/src/rust/components/{status_bar_counter.rs → rows_counter.rs} +10 -10
- package/src/rust/components/settings_panel.rs +8 -2
- package/src/rust/components/status_bar.rs +113 -19
- package/src/rust/components/status_indicator.rs +9 -14
- package/src/rust/components/{style/mod.rs → style.rs} +32 -15
- package/src/rust/components/style_controls/number_string_format/digits_section.rs +3 -5
- package/src/rust/components/style_controls/number_string_format/misc_section.rs +1 -1
- package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -1
- package/src/rust/components/viewer/msg.rs +43 -30
- package/src/rust/components/viewer/panels.rs +53 -19
- package/src/rust/components/viewer/render.rs +16 -13
- package/src/rust/components/viewer/settings.rs +137 -68
- package/src/rust/components/viewer/snapshots.rs +5 -10
- package/src/rust/components/viewer/wiring.rs +11 -22
- package/src/rust/components/viewer.rs +15 -10
- package/src/rust/components/window_editor.rs +8 -9
- package/src/rust/config/column_config_schema.rs +312 -33
- package/src/rust/config/datetime_column_style.rs +0 -11
- package/src/rust/config/mod.rs +0 -4
- package/src/rust/config/options.rs +50 -0
- package/src/rust/config/workspace_config.rs +70 -24
- package/src/rust/custom_elements/debug_plugin.rs +1 -10
- package/src/rust/custom_elements/mod.rs +0 -3
- package/src/rust/custom_elements/viewer.rs +194 -115
- package/src/rust/js/plugin.rs +3 -87
- package/src/rust/lib.rs +19 -18
- package/src/rust/presentation/column_locator.rs +3 -7
- package/src/rust/presentation.rs +68 -38
- package/src/rust/queries/hosted_tables.rs +38 -0
- package/src/rust/queries/mod.rs +2 -0
- package/src/rust/queries/palette_set.rs +1 -1
- package/src/rust/queries/plugin_column_styles.rs +6 -5
- package/src/rust/renderer/activate.rs +1 -3
- package/src/rust/renderer/dispatch.rs +83 -22
- package/src/rust/renderer/limits.rs +24 -5
- package/src/rust/renderer/plugin_config.rs +201 -41
- package/src/rust/renderer/plugin_store.rs +2 -1
- package/src/rust/renderer/props.rs +7 -1
- package/src/rust/renderer.rs +23 -27
- package/src/rust/session/props.rs +8 -3
- package/src/rust/session/view_subscription.rs +19 -6
- package/src/rust/session.rs +189 -150
- package/src/rust/tasks/create_panel.rs +5 -2
- package/src/rust/tasks/dismiss_render_warning.rs +1 -1
- package/src/rust/tasks/eject.rs +1 -0
- package/src/rust/tasks/pipeline.rs +18 -67
- package/src/rust/tasks/presize_panels.rs +24 -1
- package/src/rust/tasks/restore_and_render.rs +0 -17
- package/src/rust/tasks/restore_panel.rs +129 -30
- package/src/rust/tasks/send_column_config.rs +4 -1
- package/src/rust/tasks/send_plugin_config.rs +1 -1
- package/src/rust/tasks/set_edit_mode.rs +1 -1
- package/src/rust/tasks/sync_update_panels.rs +147 -67
- package/src/rust/tasks/table_lifecycle.rs +7 -1
- package/src/rust/{components → ui}/containers/control_group.rs +25 -3
- package/src/rust/{components → ui}/containers/dropdown_menu.rs +5 -2
- package/src/rust/{components → ui}/containers/mod.rs +0 -4
- package/src/rust/{components → ui}/containers/scroll_panel.rs +0 -22
- package/src/rust/{components → ui}/containers/scroll_panel_item.rs +0 -13
- package/src/rust/{components → ui}/containers/select.rs +0 -6
- package/src/rust/{components → ui}/containers/sidebar.rs +5 -32
- package/src/rust/{components → ui}/containers/split_panel.rs +8 -80
- package/src/rust/{components → ui}/containers/tab_list.rs +15 -9
- package/src/rust/{components → ui}/context_menu.rs +8 -13
- package/src/rust/{presentation/drag_helpers.rs → ui/dragdrop.rs} +26 -31
- package/src/rust/{components → ui}/font_loader.rs +0 -26
- package/src/rust/{components → ui}/form/color_selector.rs +4 -2
- package/src/rust/{config/datetime_column_style/color_mode.rs → ui/form/intl_label.rs} +42 -42
- package/src/rust/{components → ui}/form/mirrored_textarea.rs +0 -53
- package/src/rust/{components → ui}/form/mod.rs +1 -10
- package/src/rust/{components → ui}/form/multi_stop_gradient_selector.rs +4 -5
- package/src/rust/{components → ui}/form/named_value_picker.rs +1 -6
- package/src/rust/{components → ui}/form/number_field.rs +1 -1
- package/src/rust/{components → ui}/form/number_range_field.rs +1 -1
- package/src/rust/{components → ui}/form/optional_field.rs +3 -1
- package/src/rust/{components → ui}/form/palette_selector.rs +4 -5
- package/src/rust/{components → ui}/form/select_enum_field.rs +2 -2
- package/src/rust/{components → ui}/form/select_value_field.rs +2 -2
- package/src/rust/ui/mod.rs +56 -0
- package/src/rust/ui/modal.rs +61 -0
- package/src/rust/{components → ui}/portal.rs +175 -79
- package/src/rust/{components/style/style_provider.rs → ui/style.rs} +4 -34
- package/src/rust/utils/completion.rs +0 -6
- package/src/rust/{config/css_scale.rs → utils/css.rs} +38 -35
- package/src/rust/utils/css_vars.rs +13 -0
- package/src/rust/utils/local_fonts.rs +395 -0
- package/src/rust/utils/mod.rs +4 -0
- package/src/rust/workspace.rs +47 -0
- package/src/svg/boolean-type.svg +3 -2
- package/src/svg/checkbox-checked-icon.svg +4 -7
- package/src/svg/checkbox-hover.svg +3 -3
- package/src/svg/checkbox-off.svg +2 -3
- package/src/svg/checkbox-on.svg +3 -3
- package/src/svg/checkbox-unchecked-icon.svg +3 -3
- package/src/svg/datagrid-select-column.svg +8 -15
- package/src/svg/datagrid-select-region.svg +8 -15
- package/src/svg/datagrid-select-row-tree.svg +7 -12
- package/src/svg/datagrid-select-row.svg +8 -13
- package/src/svg/date-type.svg +4 -23
- package/src/svg/drawer-tab-hover.svg +4 -6
- package/src/svg/drawer-tab-invert-hover.svg +5 -5
- package/src/svg/drawer-tab-invert.svg +3 -5
- package/src/svg/drawer-tab.svg +5 -5
- package/src/svg/mega-menu-icons-candlestick.svg +5 -37
- package/src/svg/mega-menu-icons-ohlc.svg +4 -39
- package/src/svg/mega-menu-icons-sunburst.svg +4 -38
- package/src/svg/mega-menu-icons-treemap.svg +3 -43
- package/src/svg/mega-menu-icons-y-scatter.svg +12 -72
- package/src/svg/new-panel-icon.svg +4 -0
- package/src/svg/number-type.svg +3 -3
- package/src/svg/radio-hover.svg +3 -3
- package/src/svg/radio-off.svg +3 -3
- package/src/svg/radio-on.svg +3 -3
- package/src/svg/status_ok.svg +3 -26
- package/src/svg/status_pending.svg +3 -0
- package/src/svg/string-type.svg +4 -8
- package/src/svg/theme-icon.svg +5 -5
- package/src/themes/blueprint.css +0 -57
- package/src/themes/botanical.css +0 -36
- package/src/themes/defaults.css +1 -24
- package/src/themes/dracula.css +0 -58
- package/src/themes/eggplant.css +0 -58
- package/src/themes/gruvbox-dark.css +0 -65
- package/src/themes/gruvbox.css +1 -39
- package/src/themes/icons.css +2 -8
- package/src/themes/intl/ar.css +198 -0
- package/src/themes/intl/de.css +63 -40
- package/src/themes/intl/es.css +58 -35
- package/src/themes/intl/fr.css +57 -34
- package/src/themes/intl/ja.css +59 -36
- package/src/themes/intl/pt.css +54 -31
- package/src/themes/intl/zh.css +65 -42
- package/src/themes/intl.css +34 -8
- package/src/themes/ledger.css +1 -59
- package/src/themes/monokai.css +0 -51
- package/src/themes/nord.css +0 -55
- package/src/themes/phosphor.css +0 -48
- package/src/themes/pro-dark.css +0 -37
- package/src/themes/pro.css +3 -23
- package/src/themes/solarized-dark.css +0 -31
- package/src/themes/solarized.css +1 -24
- package/src/themes/vaporwave.css +0 -44
- package/src/themes/velvet.css +0 -60
- package/src/ts/extensions.ts +0 -13
- package/src/ts/perspective-viewer.ts +2 -0
- package/src/ts/plugin.ts +9 -0
- package/src/ts/ts-rs/AddPanelOptions.ts +10 -0
- package/src/ts/ts-rs/{DatetimeColorMode.ts → GetViewMode.ts} +4 -1
- package/src/ts/ts-rs/GetViewOptions.ts +7 -0
- package/src/ts/ts-rs/RestoreOptions.ts +7 -1
- package/src/ts/ts-rs/RestoreWorkspaceOptions.ts +10 -0
- package/src/ts/ts-rs/ViewOnUpdateResp.ts +1 -1
- package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +31 -20
- package/dist/esm/ts-rs/DatetimeColorMode.d.ts +0 -1
- package/dist/esm/ts-rs/FormatMode.d.ts +0 -1
- package/dist/esm/ts-rs/StringColorMode.d.ts +0 -1
- package/src/css/plugin-settings-panel.css +0 -171
- package/src/rust/components/modal.rs +0 -177
- package/src/rust/components/string_column_style.rs +0 -121
- package/src/rust/config/string_column_style.rs +0 -135
- package/src/rust/custom_elements/copy_dropdown.rs +0 -219
- package/src/rust/custom_elements/export_dropdown.rs +0 -216
- package/src/rust/custom_elements/modal.rs +0 -299
- package/src/ts/ts-rs/FormatMode.ts +0 -3
- package/src/ts/ts-rs/StringColorMode.ts +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline4.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-87bd21b215d0631a → perspective-viewer-ea71a3990cad35d7}/inline5.js +0 -0
- /package/src/css/{containers → ui/containers}/scroll-panel.css +0 -0
- /package/src/css/{containers → ui/containers}/split-panel.css +0 -0
- /package/src/css/{dom → ui/dom}/checkbox.css +0 -0
- /package/src/css/{dom → ui/dom}/scrollbar.css +0 -0
- /package/src/css/{dom → ui/dom}/select.css +0 -0
- /package/src/css/{form → ui/form}/mirrored-textarea.css +0 -0
- /package/src/rust/components/{form → code_editor}/highlight.rs +0 -0
- /package/src/rust/{components → ui}/containers/sidebar_close_button.rs +0 -0
- /package/src/rust/{components → ui}/form/number_input.rs +0 -0
|
@@ -38,7 +38,7 @@ use crate::js::*;
|
|
|
38
38
|
use crate::presentation::*;
|
|
39
39
|
use crate::queries::*;
|
|
40
40
|
use crate::root::Root;
|
|
41
|
-
use crate::session::{ResetOptions, TableLoadState};
|
|
41
|
+
use crate::session::{MissingTable, ResetOptions, TableLoadState};
|
|
42
42
|
use crate::tasks::*;
|
|
43
43
|
use crate::utils::*;
|
|
44
44
|
use crate::workspace::{Panel, PanelId, Workspace};
|
|
@@ -61,11 +61,18 @@ extern "C" {
|
|
|
61
61
|
#[wasm_bindgen(typescript_type = "PanelOptions")]
|
|
62
62
|
pub type JsPanelOptions;
|
|
63
63
|
|
|
64
|
-
/// `restore()` options dict
|
|
65
|
-
/// (`{ panel?: string, suppress_errors?: boolean }`).
|
|
64
|
+
/// The `restore()` options dict.
|
|
66
65
|
#[wasm_bindgen(typescript_type = "RestoreOptions")]
|
|
67
66
|
pub type JsRestoreOptions;
|
|
68
67
|
|
|
68
|
+
/// The `restoreWorkspace()` options dict.
|
|
69
|
+
#[wasm_bindgen(typescript_type = "RestoreWorkspaceOptions")]
|
|
70
|
+
pub type JsRestoreWorkspaceOptions;
|
|
71
|
+
|
|
72
|
+
/// The `addPanel()` options dict.
|
|
73
|
+
#[wasm_bindgen(typescript_type = "AddPanelOptions")]
|
|
74
|
+
pub type JsAddPanelOptions;
|
|
75
|
+
|
|
69
76
|
/// `addPanel()` argument: a new panel's initial config — `table`
|
|
70
77
|
/// REQUIRED.
|
|
71
78
|
#[wasm_bindgen(typescript_type = "ViewerConfigInitial")]
|
|
@@ -84,9 +91,9 @@ extern "C" {
|
|
|
84
91
|
#[wasm_bindgen(typescript_type = "GetClientOptions")]
|
|
85
92
|
pub type JsGetClientOptions;
|
|
86
93
|
|
|
87
|
-
/// `
|
|
88
|
-
#[wasm_bindgen(typescript_type = "
|
|
89
|
-
pub type
|
|
94
|
+
/// `getView` options dict (`{ mode?: GetViewMode, panel?: string }`).
|
|
95
|
+
#[wasm_bindgen(typescript_type = "GetViewOptions")]
|
|
96
|
+
pub type JsGetViewOptions;
|
|
90
97
|
|
|
91
98
|
/// `saveWorkspace()` options dict (`{ full_palette?: boolean }`).
|
|
92
99
|
#[wasm_bindgen(typescript_type = "SaveWorkspaceOptions")]
|
|
@@ -121,14 +128,15 @@ struct ResizeDimensions {
|
|
|
121
128
|
/// falling back to `Default` on absence or a malformed argument (matching the
|
|
122
129
|
/// `ResizeOptions` precedent — an options bag is a best-effort convenience,
|
|
123
130
|
/// not a hard-validated payload).
|
|
124
|
-
fn parse_options<T, U>(options: Option<T>) -> U
|
|
131
|
+
fn parse_options<T, U>(options: Option<T>) -> ApiResult<U>
|
|
125
132
|
where
|
|
126
133
|
T: Into<JsValue>,
|
|
127
134
|
U: Default + for<'a> serde::Deserialize<'a>,
|
|
128
135
|
{
|
|
129
|
-
options
|
|
130
|
-
|
|
131
|
-
.
|
|
136
|
+
match options {
|
|
137
|
+
None => Ok(U::default()),
|
|
138
|
+
Some(x) => Ok(x.into_serde_ext()?),
|
|
139
|
+
}
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
/// The `<perspective-viewer>` custom element.
|
|
@@ -196,6 +204,28 @@ impl PerspectiveViewerElement {
|
|
|
196
204
|
})
|
|
197
205
|
}
|
|
198
206
|
|
|
207
|
+
/// Re-stamp the global-filter overlay on every panel not in `fresh` and
|
|
208
|
+
/// re-render those whose overlay changed.
|
|
209
|
+
async fn rerender_retained_overlays(&self, fresh: &[PanelId]) -> ApiResult<()> {
|
|
210
|
+
let retained = self
|
|
211
|
+
.workspace
|
|
212
|
+
.panels()
|
|
213
|
+
.into_iter()
|
|
214
|
+
.filter(|panel| !fresh.contains(&panel.id))
|
|
215
|
+
.filter(|panel| stamp_global_overlay(&self.workspace, &panel.id, &panel.session))
|
|
216
|
+
.collect::<Vec<_>>();
|
|
217
|
+
|
|
218
|
+
join_all(retained.iter().map(|panel| async move {
|
|
219
|
+
apply_and_render(&panel.session, &panel.renderer, ViewConfigUpdate::default())?.await?;
|
|
220
|
+
Ok(())
|
|
221
|
+
}))
|
|
222
|
+
.await
|
|
223
|
+
.into_iter()
|
|
224
|
+
.collect::<ApiResult<Vec<_>>>()?;
|
|
225
|
+
|
|
226
|
+
Ok(())
|
|
227
|
+
}
|
|
228
|
+
|
|
199
229
|
fn layout_element(&self) -> Option<RegularLayout> {
|
|
200
230
|
self.elem
|
|
201
231
|
.shadow_root()?
|
|
@@ -512,31 +542,13 @@ impl PerspectiveViewerElement {
|
|
|
512
542
|
.expect("just-reserved panel is present")
|
|
513
543
|
});
|
|
514
544
|
|
|
515
|
-
// Carrying `Some(notify)` marks this load as the reservation's
|
|
516
|
-
// owner — the only call that may place or discard it below.
|
|
517
545
|
(panel, Some(self.layout_changed_notify()))
|
|
518
546
|
},
|
|
519
547
|
};
|
|
520
548
|
|
|
521
|
-
// A `Table` payload targets this panel's engines; a `Client` registers
|
|
522
|
-
// inertly against it. Selecting the panel here (not at construction)
|
|
523
|
-
// keeps the registry race safe — by `load()` time real plugins have
|
|
524
|
-
// registered.
|
|
525
549
|
let session = panel.session;
|
|
526
550
|
let renderer = panel.renderer;
|
|
527
|
-
|
|
528
|
-
// Open the pending-load window SYNCHRONOUSLY, at the call site — this
|
|
529
|
-
// is what fixes the ordering. The payload's RESET disposition (a
|
|
530
|
-
// `Table` resets the view; a `Client` does not) is unknown until the
|
|
531
|
-
// promise resolves, but the window's POSITION on the config-commit
|
|
532
|
-
// stream is fixed NOW. A `restore()` a caller fires immediately after
|
|
533
|
-
// this unawaited `load()` (the React prop-binding pattern, which has
|
|
534
|
-
// no async ordering guarantees) commits INTO this window's journal and
|
|
535
|
-
// is replayed over the reset base if the payload proves to be a
|
|
536
|
-
// `Table` — so a moved-async reset can no longer clobber a later
|
|
537
|
-
// commit. See `SESSION_CONFIG_COHERENCE_PLAN.md`.
|
|
538
551
|
let generation = session.begin_pending_load();
|
|
539
|
-
|
|
540
552
|
clone!(self.workspace, self.presentation);
|
|
541
553
|
Ok(ApiFuture::new_throttled(async move {
|
|
542
554
|
let _effect = effect;
|
|
@@ -734,7 +746,11 @@ impl PerspectiveViewerElement {
|
|
|
734
746
|
/// await viewer.eject({client: "remote"});
|
|
735
747
|
/// ```
|
|
736
748
|
pub fn eject(&mut self, options: Option<JsClientOptions>) -> ApiFuture<()> {
|
|
737
|
-
let ClientOptions { client } = parse_options(options)
|
|
749
|
+
let ClientOptions { client } = match parse_options(options) {
|
|
750
|
+
Ok(x) => x,
|
|
751
|
+
Err(x) => return ApiFuture::new_err(x),
|
|
752
|
+
};
|
|
753
|
+
|
|
738
754
|
// Default target: the active panel's client, or — when the active panel
|
|
739
755
|
// is unbound (`load(Client)` is now inert) — the default client.
|
|
740
756
|
let Some(target) = client
|
|
@@ -770,32 +786,59 @@ impl PerspectiveViewerElement {
|
|
|
770
786
|
eject_client_panels(&self.workspace, &self.root, target, ids)
|
|
771
787
|
}
|
|
772
788
|
|
|
773
|
-
/// Get
|
|
789
|
+
/// Get a [`View`] for a panel of this viewer, as currently configured by
|
|
790
|
+
/// the user.
|
|
774
791
|
///
|
|
775
|
-
///
|
|
776
|
-
/// configured by the user, for e.g. serializing as an
|
|
777
|
-
/// [Apache Arrow](https://arrow.apache.org/) before passing to another
|
|
778
|
-
/// library.
|
|
792
|
+
/// # Arguments
|
|
779
793
|
///
|
|
780
|
-
///
|
|
781
|
-
/// [`
|
|
782
|
-
///
|
|
783
|
-
///
|
|
784
|
-
///
|
|
785
|
-
///
|
|
794
|
+
/// - `mode` - which [`View`] to return:
|
|
795
|
+
/// - `"live"` (default) - the panel's own [`View`], which the viewer
|
|
796
|
+
/// replaces on every config change and deletes when auto-paused or
|
|
797
|
+
/// [`PerspectiveViewerElement::delete`]d, so calls on it may fail with
|
|
798
|
+
/// "View already deleted", it must never be deleted by the caller, and
|
|
799
|
+
/// it rejects with `No View for panel "<name>"` while none is bound
|
|
800
|
+
/// (auto-paused or not yet rendered).
|
|
801
|
+
/// - `"clone"` - a new [`View`] built from the panel's effective config
|
|
802
|
+
/// (global filter included), independent of the render lifecycle, which
|
|
803
|
+
/// the caller owns and must [`View::delete`].
|
|
804
|
+
/// - `"auto"` - `"live"` when the panel has a bound [`View`], else
|
|
805
|
+
/// `"clone"`.
|
|
806
|
+
/// - `panel` - the target panel, or the active panel when omitted.
|
|
807
|
+
///
|
|
808
|
+
/// Plugins which rely on the live [`View`] for their
|
|
809
|
+
/// [`HTMLPerspectiveViewerPluginElement::draw`] implementations should
|
|
810
|
+
/// treat "View already deleted" as a _cancellation_ by silently aborting.
|
|
786
811
|
///
|
|
787
812
|
/// # JavaScript Examples
|
|
788
813
|
///
|
|
789
814
|
/// ```javascript
|
|
790
815
|
/// const view = await viewer.getView();
|
|
791
816
|
/// ```
|
|
817
|
+
///
|
|
818
|
+
/// Export every panel without borrowing the viewer's own [`View`]:
|
|
819
|
+
///
|
|
820
|
+
/// ```javascript
|
|
821
|
+
/// for (const panel of viewer.getPanelNames()) {
|
|
822
|
+
/// const view = await viewer.getView({ panel, mode: "clone" });
|
|
823
|
+
/// const arrow = await view.to_arrow();
|
|
824
|
+
/// await view.delete();
|
|
825
|
+
/// }
|
|
826
|
+
/// ```
|
|
792
827
|
#[wasm_bindgen]
|
|
793
|
-
pub fn getView(&self, options: Option<
|
|
794
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
828
|
+
pub fn getView(&self, options: Option<JsGetViewOptions>) -> ApiFuture<View> {
|
|
795
829
|
let this = self.clone();
|
|
796
830
|
ApiFuture::new(async move {
|
|
831
|
+
let GetViewOptions { mode, panel: name } = parse_options(options)?;
|
|
797
832
|
let panel = this.resolve_panel(name)?;
|
|
798
|
-
|
|
833
|
+
match (mode.unwrap_or_default(), panel.session.get_view()) {
|
|
834
|
+
(GetViewMode::Live | GetViewMode::Auto, Some(view)) => Ok(view.into()),
|
|
835
|
+
(GetViewMode::Live, None) => {
|
|
836
|
+
Err(format!("No View for panel \"{}\"", panel.id.as_str()).into())
|
|
837
|
+
},
|
|
838
|
+
(GetViewMode::Clone, _) | (GetViewMode::Auto, None) => {
|
|
839
|
+
Ok(panel.session.create_detached_view().await?.into())
|
|
840
|
+
},
|
|
841
|
+
}
|
|
799
842
|
})
|
|
800
843
|
}
|
|
801
844
|
|
|
@@ -806,9 +849,9 @@ impl PerspectiveViewerElement {
|
|
|
806
849
|
/// [`View::get_config`])
|
|
807
850
|
#[wasm_bindgen]
|
|
808
851
|
pub fn getViewConfig(&self, options: Option<JsPanelOptions>) -> ApiFuture<JsViewConfig> {
|
|
809
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
810
852
|
let this = self.clone();
|
|
811
853
|
ApiFuture::new(async move {
|
|
854
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
812
855
|
let panel = this.resolve_panel(name)?;
|
|
813
856
|
let config = if let Some(ctx) = panel.renderer.render_context() {
|
|
814
857
|
(*ctx.view_config).clone()
|
|
@@ -839,12 +882,12 @@ impl PerspectiveViewerElement {
|
|
|
839
882
|
/// ```
|
|
840
883
|
#[wasm_bindgen]
|
|
841
884
|
pub fn getTable(&self, options: Option<JsGetTableOptions>) -> ApiFuture<Table> {
|
|
842
|
-
let GetTableOptions {
|
|
843
|
-
wait: wait_for_table,
|
|
844
|
-
panel: name,
|
|
845
|
-
} = parse_options(options);
|
|
846
885
|
let this = self.clone();
|
|
847
886
|
ApiFuture::new(async move {
|
|
887
|
+
let GetTableOptions {
|
|
888
|
+
wait: wait_for_table,
|
|
889
|
+
panel: name,
|
|
890
|
+
} = parse_options(options)?;
|
|
848
891
|
let panel = this.resolve_panel(name)?;
|
|
849
892
|
if !wait_for_table.unwrap_or_default()
|
|
850
893
|
&& let Some(ctx) = panel.renderer.render_context()
|
|
@@ -884,12 +927,12 @@ impl PerspectiveViewerElement {
|
|
|
884
927
|
&self,
|
|
885
928
|
options: Option<JsGetClientOptions>,
|
|
886
929
|
) -> ApiFuture<perspective_js::Client> {
|
|
887
|
-
let GetClientOptions {
|
|
888
|
-
wait: wait_for_client,
|
|
889
|
-
panel: name,
|
|
890
|
-
} = parse_options(options);
|
|
891
930
|
let this = self.clone();
|
|
892
931
|
ApiFuture::new(async move {
|
|
932
|
+
let GetClientOptions {
|
|
933
|
+
wait: wait_for_client,
|
|
934
|
+
panel: name,
|
|
935
|
+
} = parse_options(options)?;
|
|
893
936
|
let panel = this.resolve_panel(name)?;
|
|
894
937
|
if !wait_for_client.unwrap_or_default()
|
|
895
938
|
&& let Some(ctx) = panel.renderer.render_context()
|
|
@@ -920,7 +963,7 @@ impl PerspectiveViewerElement {
|
|
|
920
963
|
/// ```
|
|
921
964
|
#[wasm_bindgen]
|
|
922
965
|
pub fn getRenderStats(&self, options: Option<JsPanelOptions>) -> ApiResult<JsValue> {
|
|
923
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
966
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
924
967
|
let panel = self.resolve_panel(name)?;
|
|
925
968
|
Ok(JsValue::from_serde_ext(
|
|
926
969
|
&panel.renderer.render_timer().get_stats(),
|
|
@@ -1018,12 +1061,13 @@ impl PerspectiveViewerElement {
|
|
|
1018
1061
|
/// - `options.panel` - The panel to target, or the active panel when
|
|
1019
1062
|
/// omitted.
|
|
1020
1063
|
/// - `options.suppress_errors` - when `true`, a failed restore only rejects
|
|
1021
|
-
/// the returned `Promise
|
|
1022
|
-
/// visible error state and
|
|
1023
|
-
///
|
|
1024
|
-
///
|
|
1025
|
-
///
|
|
1026
|
-
///
|
|
1064
|
+
/// the returned `Promise` and rolls the view config back, leaving the
|
|
1065
|
+
/// viewer's visible error state and any element-level state the call
|
|
1066
|
+
/// already applied (theme, title, plugin, a successful `table` change)
|
|
1067
|
+
/// untouched.
|
|
1068
|
+
/// - `options.wait_for_table` - when `true`, a `table` no loaded client
|
|
1069
|
+
/// hosts yet leaves the panel empty and pending until the table is
|
|
1070
|
+
/// created, instead of the default error.
|
|
1027
1071
|
///
|
|
1028
1072
|
/// # JavaScript Examples
|
|
1029
1073
|
///
|
|
@@ -1045,20 +1089,23 @@ impl PerspectiveViewerElement {
|
|
|
1045
1089
|
update: JsViewerConfigUpdate,
|
|
1046
1090
|
options: Option<JsRestoreOptions>,
|
|
1047
1091
|
) -> JsVoidPromise {
|
|
1048
|
-
let RestoreOptions {
|
|
1049
|
-
panel: name,
|
|
1050
|
-
suppress_errors,
|
|
1051
|
-
} = parse_options(options);
|
|
1052
|
-
|
|
1053
|
-
let errors = if suppress_errors.unwrap_or_default() {
|
|
1054
|
-
RestoreErrors::Suppress
|
|
1055
|
-
} else {
|
|
1056
|
-
RestoreErrors::Publish
|
|
1057
|
-
};
|
|
1058
|
-
|
|
1059
1092
|
let effect = self.workspace.effects().guard();
|
|
1060
1093
|
let this = self.clone();
|
|
1061
1094
|
let fut = ApiFuture::new_throttled(async move {
|
|
1095
|
+
let RestoreOptions {
|
|
1096
|
+
panel: name,
|
|
1097
|
+
suppress_errors,
|
|
1098
|
+
wait_for_table,
|
|
1099
|
+
} = parse_options(options)?;
|
|
1100
|
+
|
|
1101
|
+
let errors = if suppress_errors.unwrap_or_default() {
|
|
1102
|
+
RestoreErrors::Suppress
|
|
1103
|
+
} else {
|
|
1104
|
+
RestoreErrors::Publish
|
|
1105
|
+
};
|
|
1106
|
+
|
|
1107
|
+
let missing = MissingTable::from_wait(wait_for_table);
|
|
1108
|
+
|
|
1062
1109
|
let _effect = effect;
|
|
1063
1110
|
let id = name.map(PanelId::from);
|
|
1064
1111
|
let mut update = ViewerConfigUpdate::decode(&update)?;
|
|
@@ -1092,19 +1139,6 @@ impl PerspectiveViewerElement {
|
|
|
1092
1139
|
};
|
|
1093
1140
|
|
|
1094
1141
|
if !matches!(settings, OptionalUpdate::Missing) {
|
|
1095
|
-
// Through `ToggleSettingsInit` — the SAME full choreography
|
|
1096
|
-
// the toolbar toggle drives (presize every visible plugin
|
|
1097
|
-
// to its post-toggle box, then the exactness-finalizer
|
|
1098
|
-
// resize) — NOT the bare `ToggleSettingsComplete` leaf,
|
|
1099
|
-
// which only re-renders the pane. The pane is the outer
|
|
1100
|
-
// `SplitPanel` (no `before-resize` event) and the host box
|
|
1101
|
-
// is unchanged, so a leaf-only toggle left every canvas
|
|
1102
|
-
// plugin CSS-stretched at its old backing size.
|
|
1103
|
-
//
|
|
1104
|
-
// No `set_settings_before_open` here: `is_settings_open` is
|
|
1105
|
-
// Init's toggle-vs-no-op DISPATCH state, so pre-writing the
|
|
1106
|
-
// target makes every call resolve as a no-op. Init owns the
|
|
1107
|
-
// write, as it does for the toolbar and `toggleConfig`.
|
|
1108
1142
|
let (sender, receiver) = channel::<ApiResult<JsValue>>();
|
|
1109
1143
|
this.root.borrow().as_ref().into_apierror()?.send_message(
|
|
1110
1144
|
PerspectiveViewerMsg::ToggleSettingsInit(Some(settings), false, Some(sender)),
|
|
@@ -1123,6 +1157,7 @@ impl PerspectiveViewerElement {
|
|
|
1123
1157
|
RestoreMode::Existing { active },
|
|
1124
1158
|
update,
|
|
1125
1159
|
errors,
|
|
1160
|
+
missing,
|
|
1126
1161
|
)
|
|
1127
1162
|
.await
|
|
1128
1163
|
},
|
|
@@ -1135,6 +1170,7 @@ impl PerspectiveViewerElement {
|
|
|
1135
1170
|
RestoreMode::Existing { active: true },
|
|
1136
1171
|
update,
|
|
1137
1172
|
errors,
|
|
1173
|
+
missing,
|
|
1138
1174
|
)
|
|
1139
1175
|
.await
|
|
1140
1176
|
},
|
|
@@ -1147,6 +1183,7 @@ impl PerspectiveViewerElement {
|
|
|
1147
1183
|
id,
|
|
1148
1184
|
*config,
|
|
1149
1185
|
None,
|
|
1186
|
+
missing,
|
|
1150
1187
|
)
|
|
1151
1188
|
.await?;
|
|
1152
1189
|
Ok(())
|
|
@@ -1157,25 +1194,47 @@ impl PerspectiveViewerElement {
|
|
|
1157
1194
|
js_sys::Promise::from(fut).unchecked_into()
|
|
1158
1195
|
}
|
|
1159
1196
|
|
|
1160
|
-
///
|
|
1161
|
-
///
|
|
1162
|
-
///
|
|
1163
|
-
///
|
|
1164
|
-
///
|
|
1165
|
-
///
|
|
1197
|
+
/// Apply a [`WorkspaceConfigUpdate`] to the element — the multi-panel
|
|
1198
|
+
/// counterpart of [`Self::restore`] and like it a field-wise update, where
|
|
1199
|
+
/// an absent field is unchanged, `null` resets and a value replaces.
|
|
1200
|
+
///
|
|
1201
|
+
/// # Arguments
|
|
1202
|
+
///
|
|
1203
|
+
/// - `update` - The workspace config update: a [`Self::saveWorkspace`]
|
|
1204
|
+
/// token replaces every panel (`panels` is the whole set), while a token
|
|
1205
|
+
/// without `panels` keeps them and `layout`, `active` and `masters` name
|
|
1206
|
+
/// them by their existing ids.
|
|
1207
|
+
/// - `options.wait_for_table` - when `true`, a panel whose `table` no
|
|
1208
|
+
/// loaded client hosts yet is created empty and pending until the table
|
|
1209
|
+
/// is created, instead of the default error.
|
|
1166
1210
|
///
|
|
1167
1211
|
/// # JavaScript Examples
|
|
1168
1212
|
///
|
|
1169
1213
|
/// ```javascript
|
|
1170
1214
|
/// await viewer.restoreWorkspace(await otherViewer.saveWorkspace());
|
|
1171
1215
|
/// ```
|
|
1172
|
-
|
|
1173
|
-
|
|
1216
|
+
///
|
|
1217
|
+
/// Cross-filter the current panels without re-creating them:
|
|
1218
|
+
///
|
|
1219
|
+
/// ```javascript
|
|
1220
|
+
/// await viewer.restoreWorkspace({ global_filters: [["Region", "==", "West"]] });
|
|
1221
|
+
/// ```
|
|
1222
|
+
pub fn restoreWorkspace(
|
|
1223
|
+
&self,
|
|
1224
|
+
update: JsWorkspaceConfigUpdate,
|
|
1225
|
+
options: Option<JsRestoreWorkspaceOptions>,
|
|
1226
|
+
) -> JsVoidPromise {
|
|
1174
1227
|
let effect = self.workspace.effects().guard();
|
|
1175
1228
|
let this = self.clone();
|
|
1176
1229
|
let fut = ApiFuture::new(async move {
|
|
1177
1230
|
let _effect = effect;
|
|
1231
|
+
let RestoreWorkspaceOptions { wait_for_table } = parse_options(options)?;
|
|
1232
|
+
let missing = MissingTable::from_wait(wait_for_table);
|
|
1178
1233
|
let (contents, eject_tasks) = sync_update_panels(&this, update)?;
|
|
1234
|
+
let fresh = contents
|
|
1235
|
+
.iter()
|
|
1236
|
+
.map(|(id, ..)| id.clone())
|
|
1237
|
+
.collect::<Vec<_>>();
|
|
1179
1238
|
let results = join_all(contents.into_iter().map(|(id, session, renderer, config)| {
|
|
1180
1239
|
let presentation = this.presentation.clone();
|
|
1181
1240
|
let workspace = this.workspace.clone();
|
|
@@ -1189,6 +1248,7 @@ impl PerspectiveViewerElement {
|
|
|
1189
1248
|
RestoreMode::Fresh,
|
|
1190
1249
|
config,
|
|
1191
1250
|
crate::tasks::RestoreErrors::Publish,
|
|
1251
|
+
missing,
|
|
1192
1252
|
)
|
|
1193
1253
|
.await?;
|
|
1194
1254
|
if workspace.is_master(&id) {
|
|
@@ -1201,6 +1261,7 @@ impl PerspectiveViewerElement {
|
|
|
1201
1261
|
.await;
|
|
1202
1262
|
|
|
1203
1263
|
results.into_iter().collect::<ApiResult<Vec<_>>>()?;
|
|
1264
|
+
this.rerender_retained_overlays(&fresh).await?;
|
|
1204
1265
|
join_all(eject_tasks)
|
|
1205
1266
|
.await
|
|
1206
1267
|
.into_iter()
|
|
@@ -1264,9 +1325,9 @@ impl PerspectiveViewerElement {
|
|
|
1264
1325
|
/// });
|
|
1265
1326
|
/// ```
|
|
1266
1327
|
pub fn save(&self, options: Option<JsPanelOptions>) -> JsViewerConfigPromise {
|
|
1267
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
1268
1328
|
let this = self.clone();
|
|
1269
1329
|
let fut = ApiFuture::new(async move {
|
|
1330
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1270
1331
|
this.workspace.effects().settle().await;
|
|
1271
1332
|
let panel = this.resolve_panel(name)?;
|
|
1272
1333
|
let viewer_config = panel
|
|
@@ -1300,9 +1361,12 @@ impl PerspectiveViewerElement {
|
|
|
1300
1361
|
&self,
|
|
1301
1362
|
options: Option<JsSaveWorkspaceOptions>,
|
|
1302
1363
|
) -> JsWorkspaceConfigPromise {
|
|
1303
|
-
let SaveWorkspaceOptions { full_palette } = parse_options(options);
|
|
1304
1364
|
let this = self.clone();
|
|
1305
|
-
let fut = ApiFuture::new(
|
|
1365
|
+
let fut = ApiFuture::new(async move {
|
|
1366
|
+
let SaveWorkspaceOptions { full_palette } = parse_options(options)?;
|
|
1367
|
+
Self::workspace_config(this, full_palette.unwrap_or(false)).await
|
|
1368
|
+
});
|
|
1369
|
+
|
|
1306
1370
|
js_sys::Promise::from(fut).unchecked_into()
|
|
1307
1371
|
}
|
|
1308
1372
|
|
|
@@ -1321,13 +1385,13 @@ impl PerspectiveViewerElement {
|
|
|
1321
1385
|
/// })
|
|
1322
1386
|
/// ```
|
|
1323
1387
|
pub fn download(&self, options: Option<JsExportOptions>) -> ApiFuture<()> {
|
|
1324
|
-
let ExportOptions {
|
|
1325
|
-
method,
|
|
1326
|
-
panel: name,
|
|
1327
|
-
} = parse_options(options);
|
|
1328
|
-
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1329
1388
|
let this = self.clone();
|
|
1330
1389
|
ApiFuture::new_throttled(async move {
|
|
1390
|
+
let ExportOptions {
|
|
1391
|
+
method,
|
|
1392
|
+
panel: name,
|
|
1393
|
+
} = parse_options(options)?;
|
|
1394
|
+
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1331
1395
|
let method = if let Some(method) = method
|
|
1332
1396
|
.map(|x| x.unchecked_into())
|
|
1333
1397
|
.map(serde_wasm_bindgen::from_value)
|
|
@@ -1368,13 +1432,14 @@ impl PerspectiveViewerElement {
|
|
|
1368
1432
|
/// const data = await viewer.export("plugin");
|
|
1369
1433
|
/// ```
|
|
1370
1434
|
pub fn export(&self, options: Option<JsExportOptions>) -> ApiFuture<JsValue> {
|
|
1371
|
-
let ExportOptions {
|
|
1372
|
-
method,
|
|
1373
|
-
panel: name,
|
|
1374
|
-
} = parse_options(options);
|
|
1375
|
-
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1376
1435
|
let this = self.clone();
|
|
1377
1436
|
ApiFuture::new(async move {
|
|
1437
|
+
let ExportOptions {
|
|
1438
|
+
method,
|
|
1439
|
+
panel: name,
|
|
1440
|
+
} = parse_options(options)?;
|
|
1441
|
+
|
|
1442
|
+
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1378
1443
|
let method = if let Some(method) = method
|
|
1379
1444
|
.map(|x| x.unchecked_into())
|
|
1380
1445
|
.map(serde_wasm_bindgen::from_value)
|
|
@@ -1406,13 +1471,14 @@ impl PerspectiveViewerElement {
|
|
|
1406
1471
|
/// })
|
|
1407
1472
|
/// ```
|
|
1408
1473
|
pub fn copy(&self, options: Option<JsExportOptions>) -> ApiFuture<()> {
|
|
1409
|
-
let ExportOptions {
|
|
1410
|
-
method,
|
|
1411
|
-
panel: name,
|
|
1412
|
-
} = parse_options(options);
|
|
1413
|
-
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1414
1474
|
let this = self.clone();
|
|
1415
1475
|
ApiFuture::new_throttled(async move {
|
|
1476
|
+
let ExportOptions {
|
|
1477
|
+
method,
|
|
1478
|
+
panel: name,
|
|
1479
|
+
} = parse_options(options)?;
|
|
1480
|
+
|
|
1481
|
+
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1416
1482
|
let method = if let Some(method) = method
|
|
1417
1483
|
.map(|x| x.unchecked_into())
|
|
1418
1484
|
.map(serde_wasm_bindgen::from_value)
|
|
@@ -1451,11 +1517,11 @@ impl PerspectiveViewerElement {
|
|
|
1451
1517
|
/// await viewer.reset(true, {panel: "p1"}); // just "p1", + expressions
|
|
1452
1518
|
/// ```
|
|
1453
1519
|
pub fn reset(&self, reset_all: Option<bool>, options: Option<JsPanelOptions>) -> ApiFuture<()> {
|
|
1454
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
1455
1520
|
let effect = self.workspace.effects().guard();
|
|
1456
1521
|
let this = self.clone();
|
|
1457
1522
|
let all = reset_all.unwrap_or_default();
|
|
1458
1523
|
ApiFuture::new_throttled(async move {
|
|
1524
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1459
1525
|
let _effect = effect;
|
|
1460
1526
|
let (completion, receiver) = Completion::new();
|
|
1461
1527
|
{
|
|
@@ -1633,7 +1699,7 @@ impl PerspectiveViewerElement {
|
|
|
1633
1699
|
/// region of the named panel, or the active panel when `panel` is omitted.
|
|
1634
1700
|
#[wasm_bindgen]
|
|
1635
1701
|
pub fn getSelection(&self, options: Option<JsPanelOptions>) -> ApiResult<Option<JsViewWindow>> {
|
|
1636
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
1702
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1637
1703
|
let panel = self.resolve_panel(name)?;
|
|
1638
1704
|
Ok(panel.renderer.get_selection().map(|x| x.into()))
|
|
1639
1705
|
}
|
|
@@ -1646,7 +1712,7 @@ impl PerspectiveViewerElement {
|
|
|
1646
1712
|
window: Option<JsViewWindow>,
|
|
1647
1713
|
options: Option<JsPanelOptions>,
|
|
1648
1714
|
) -> ApiResult<()> {
|
|
1649
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
1715
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1650
1716
|
let window = window.map(|x| x.into_serde_ext()).transpose()?;
|
|
1651
1717
|
self.resolve_panel(name)?.renderer.set_selection(window);
|
|
1652
1718
|
Ok(())
|
|
@@ -1657,7 +1723,7 @@ impl PerspectiveViewerElement {
|
|
|
1657
1723
|
/// `panel` is omitted.
|
|
1658
1724
|
#[wasm_bindgen]
|
|
1659
1725
|
pub fn getEditPort(&self, options: Option<JsPanelOptions>) -> ApiResult<f64> {
|
|
1660
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
1726
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1661
1727
|
let panel = self.resolve_panel(name)?;
|
|
1662
1728
|
let edit_port = if let Some(ctx) = panel.renderer.render_context() {
|
|
1663
1729
|
ctx.edit_port
|
|
@@ -1873,13 +1939,25 @@ impl PerspectiveViewerElement {
|
|
|
1873
1939
|
///
|
|
1874
1940
|
/// The element-level `settings` field does not exist on the argument
|
|
1875
1941
|
/// type (it is shared across the element, not per-panel).
|
|
1942
|
+
///
|
|
1943
|
+
/// # Arguments
|
|
1944
|
+
///
|
|
1945
|
+
/// - `config` - The new panel's initial config, whose `table` is required.
|
|
1946
|
+
/// - `options.wait_for_table` - when `true`, a `table` no loaded client
|
|
1947
|
+
/// hosts yet creates the panel empty and pending until the table is
|
|
1948
|
+
/// created, instead of the default rejection.
|
|
1876
1949
|
#[wasm_bindgen]
|
|
1877
|
-
pub fn addPanel(
|
|
1950
|
+
pub fn addPanel(
|
|
1951
|
+
&self,
|
|
1952
|
+
config: JsViewerConfigInitial,
|
|
1953
|
+
options: Option<JsAddPanelOptions>,
|
|
1954
|
+
) -> ApiFuture<JsValue> {
|
|
1878
1955
|
clone!(self.elem, self.presentation, self.workspace);
|
|
1879
1956
|
let effect = workspace.effects().guard();
|
|
1880
1957
|
let notify = self.layout_changed_notify();
|
|
1881
1958
|
ApiFuture::new(async move {
|
|
1882
1959
|
let _effect = effect;
|
|
1960
|
+
let AddPanelOptions { wait_for_table } = parse_options(options)?;
|
|
1883
1961
|
let config = ViewerConfigInitial::decode(&config)?;
|
|
1884
1962
|
let id = create_panel(
|
|
1885
1963
|
&elem,
|
|
@@ -1889,6 +1967,7 @@ impl PerspectiveViewerElement {
|
|
|
1889
1967
|
None,
|
|
1890
1968
|
config,
|
|
1891
1969
|
None,
|
|
1970
|
+
MissingTable::from_wait(wait_for_table),
|
|
1892
1971
|
)
|
|
1893
1972
|
.await?;
|
|
1894
1973
|
Ok(JsValue::from_str(id.as_str()))
|
|
@@ -1978,10 +2057,10 @@ impl PerspectiveViewerElement {
|
|
|
1978
2057
|
column_name: String,
|
|
1979
2058
|
options: Option<JsPanelOptions>,
|
|
1980
2059
|
) -> ApiFuture<()> {
|
|
1981
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
1982
2060
|
let effect = self.workspace.effects().guard();
|
|
1983
2061
|
let this = self.clone();
|
|
1984
2062
|
ApiFuture::new_throttled(async move {
|
|
2063
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1985
2064
|
let _effect = effect;
|
|
1986
2065
|
let panel = this.resolve_panel(name)?;
|
|
1987
2066
|
let was_active = this.workspace.active_id().as_ref() == Some(&panel.id);
|