@perspective-dev/viewer 5.4.0 → 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 +4 -4
- 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 -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/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/perspective-viewer.d.ts +2 -0
- package/dist/esm/perspective-viewer.inline.js +9 -9
- package/dist/esm/perspective-viewer.inline.js.map +3 -3
- package/dist/esm/perspective-viewer.js +4 -4
- 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/WorkspaceConfigUpdate.d.ts +30 -22
- package/dist/wasm/perspective-viewer.d.ts +91 -47
- package/dist/wasm/perspective-viewer.js +216 -136
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +18 -18
- package/package.json +5 -5
- package/src/css/column-selector.css +11 -3
- package/src/css/column-style.css +162 -0
- package/src/css/config-selector.css +1 -1
- package/src/css/form/debug.css +9 -0
- package/src/css/status-bar.css +11 -0
- package/src/css/ui/containers/tabs.css +2 -1
- package/src/rust/agent/tools.rs +80 -7
- package/src/rust/components/column_selector/active_column.rs +9 -0
- package/src/rust/components/column_selector.rs +11 -0
- 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 +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab.rs +68 -9
- package/src/rust/components/debug_panel.rs +107 -50
- package/src/rust/components/main_panel/msg.rs +4 -0
- package/src/rust/components/main_panel.rs +14 -0
- package/src/rust/components/mod.rs +0 -1
- package/src/rust/components/plugin_tab.rs +57 -3
- package/src/rust/components/settings_panel.rs +6 -0
- package/src/rust/components/status_indicator.rs +4 -0
- package/src/rust/components/viewer/panels.rs +3 -0
- package/src/rust/components/viewer/render.rs +1 -0
- package/src/rust/components/viewer/wiring.rs +10 -1
- package/src/rust/config/column_config_schema.rs +312 -8
- package/src/rust/config/datetime_column_style.rs +0 -11
- package/src/rust/config/mod.rs +0 -2
- package/src/rust/config/options.rs +50 -0
- package/src/rust/config/workspace_config.rs +69 -24
- package/src/rust/custom_elements/viewer.rs +194 -97
- package/src/rust/js/plugin.rs +3 -1
- package/src/rust/lib.rs +7 -3
- package/src/rust/queries/plugin_column_styles.rs +6 -5
- package/src/rust/renderer/plugin_config.rs +200 -41
- package/src/rust/renderer/plugin_store.rs +2 -1
- package/src/rust/renderer/props.rs +5 -0
- package/src/rust/renderer.rs +9 -0
- package/src/rust/session/props.rs +4 -0
- package/src/rust/session.rs +151 -80
- package/src/rust/tasks/create_panel.rs +4 -1
- package/src/rust/tasks/pipeline.rs +18 -7
- package/src/rust/tasks/restore_panel.rs +129 -30
- package/src/rust/tasks/send_column_config.rs +3 -0
- package/src/rust/tasks/sync_update_panels.rs +147 -67
- package/src/rust/tasks/table_lifecycle.rs +7 -1
- package/src/rust/ui/containers/tab_list.rs +1 -1
- package/src/rust/ui/form/intl_label.rs +4 -23
- package/src/rust/ui/portal.rs +1 -0
- package/src/rust/utils/css_vars.rs +13 -0
- package/src/rust/utils/local_fonts.rs +395 -0
- package/src/rust/utils/mod.rs +2 -0
- package/src/rust/workspace.rs +12 -0
- package/src/svg/status_pending.svg +3 -0
- package/src/themes/icons.css +1 -0
- package/src/themes/intl/ar.css +20 -7
- package/src/themes/intl/de.css +20 -7
- package/src/themes/intl/es.css +20 -7
- package/src/themes/intl/fr.css +20 -7
- package/src/themes/intl/ja.css +20 -7
- package/src/themes/intl/pt.css +20 -7
- package/src/themes/intl/zh.css +20 -7
- package/src/themes/intl.css +20 -7
- 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/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/rust/components/string_column_style.rs +0 -120
- package/src/rust/config/datetime_column_style/color_mode.rs +0 -62
- package/src/rust/config/string_column_style.rs +0 -135
- package/src/ts/ts-rs/FormatMode.ts +0 -3
- package/src/ts/ts-rs/StringColorMode.ts +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-adc6f3f79141112b → perspective-viewer-ea71a3990cad35d7}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-adc6f3f79141112b → perspective-viewer-ea71a3990cad35d7}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-adc6f3f79141112b → perspective-viewer-ea71a3990cad35d7}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-adc6f3f79141112b → perspective-viewer-ea71a3990cad35d7}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-adc6f3f79141112b → perspective-viewer-ea71a3990cad35d7}/inline4.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-adc6f3f79141112b → perspective-viewer-ea71a3990cad35d7}/inline5.js +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()?
|
|
@@ -716,7 +746,11 @@ impl PerspectiveViewerElement {
|
|
|
716
746
|
/// await viewer.eject({client: "remote"});
|
|
717
747
|
/// ```
|
|
718
748
|
pub fn eject(&mut self, options: Option<JsClientOptions>) -> ApiFuture<()> {
|
|
719
|
-
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
|
+
|
|
720
754
|
// Default target: the active panel's client, or — when the active panel
|
|
721
755
|
// is unbound (`load(Client)` is now inert) — the default client.
|
|
722
756
|
let Some(target) = client
|
|
@@ -752,32 +786,59 @@ impl PerspectiveViewerElement {
|
|
|
752
786
|
eject_client_panels(&self.workspace, &self.root, target, ids)
|
|
753
787
|
}
|
|
754
788
|
|
|
755
|
-
/// Get
|
|
789
|
+
/// Get a [`View`] for a panel of this viewer, as currently configured by
|
|
790
|
+
/// the user.
|
|
756
791
|
///
|
|
757
|
-
///
|
|
758
|
-
/// configured by the user, for e.g. serializing as an
|
|
759
|
-
/// [Apache Arrow](https://arrow.apache.org/) before passing to another
|
|
760
|
-
/// library.
|
|
792
|
+
/// # Arguments
|
|
761
793
|
///
|
|
762
|
-
///
|
|
763
|
-
/// [`
|
|
764
|
-
///
|
|
765
|
-
///
|
|
766
|
-
///
|
|
767
|
-
///
|
|
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.
|
|
768
811
|
///
|
|
769
812
|
/// # JavaScript Examples
|
|
770
813
|
///
|
|
771
814
|
/// ```javascript
|
|
772
815
|
/// const view = await viewer.getView();
|
|
773
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
|
+
/// ```
|
|
774
827
|
#[wasm_bindgen]
|
|
775
|
-
pub fn getView(&self, options: Option<
|
|
776
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
828
|
+
pub fn getView(&self, options: Option<JsGetViewOptions>) -> ApiFuture<View> {
|
|
777
829
|
let this = self.clone();
|
|
778
830
|
ApiFuture::new(async move {
|
|
831
|
+
let GetViewOptions { mode, panel: name } = parse_options(options)?;
|
|
779
832
|
let panel = this.resolve_panel(name)?;
|
|
780
|
-
|
|
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
|
+
}
|
|
781
842
|
})
|
|
782
843
|
}
|
|
783
844
|
|
|
@@ -788,9 +849,9 @@ impl PerspectiveViewerElement {
|
|
|
788
849
|
/// [`View::get_config`])
|
|
789
850
|
#[wasm_bindgen]
|
|
790
851
|
pub fn getViewConfig(&self, options: Option<JsPanelOptions>) -> ApiFuture<JsViewConfig> {
|
|
791
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
792
852
|
let this = self.clone();
|
|
793
853
|
ApiFuture::new(async move {
|
|
854
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
794
855
|
let panel = this.resolve_panel(name)?;
|
|
795
856
|
let config = if let Some(ctx) = panel.renderer.render_context() {
|
|
796
857
|
(*ctx.view_config).clone()
|
|
@@ -821,12 +882,12 @@ impl PerspectiveViewerElement {
|
|
|
821
882
|
/// ```
|
|
822
883
|
#[wasm_bindgen]
|
|
823
884
|
pub fn getTable(&self, options: Option<JsGetTableOptions>) -> ApiFuture<Table> {
|
|
824
|
-
let GetTableOptions {
|
|
825
|
-
wait: wait_for_table,
|
|
826
|
-
panel: name,
|
|
827
|
-
} = parse_options(options);
|
|
828
885
|
let this = self.clone();
|
|
829
886
|
ApiFuture::new(async move {
|
|
887
|
+
let GetTableOptions {
|
|
888
|
+
wait: wait_for_table,
|
|
889
|
+
panel: name,
|
|
890
|
+
} = parse_options(options)?;
|
|
830
891
|
let panel = this.resolve_panel(name)?;
|
|
831
892
|
if !wait_for_table.unwrap_or_default()
|
|
832
893
|
&& let Some(ctx) = panel.renderer.render_context()
|
|
@@ -866,12 +927,12 @@ impl PerspectiveViewerElement {
|
|
|
866
927
|
&self,
|
|
867
928
|
options: Option<JsGetClientOptions>,
|
|
868
929
|
) -> ApiFuture<perspective_js::Client> {
|
|
869
|
-
let GetClientOptions {
|
|
870
|
-
wait: wait_for_client,
|
|
871
|
-
panel: name,
|
|
872
|
-
} = parse_options(options);
|
|
873
930
|
let this = self.clone();
|
|
874
931
|
ApiFuture::new(async move {
|
|
932
|
+
let GetClientOptions {
|
|
933
|
+
wait: wait_for_client,
|
|
934
|
+
panel: name,
|
|
935
|
+
} = parse_options(options)?;
|
|
875
936
|
let panel = this.resolve_panel(name)?;
|
|
876
937
|
if !wait_for_client.unwrap_or_default()
|
|
877
938
|
&& let Some(ctx) = panel.renderer.render_context()
|
|
@@ -902,7 +963,7 @@ impl PerspectiveViewerElement {
|
|
|
902
963
|
/// ```
|
|
903
964
|
#[wasm_bindgen]
|
|
904
965
|
pub fn getRenderStats(&self, options: Option<JsPanelOptions>) -> ApiResult<JsValue> {
|
|
905
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
966
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
906
967
|
let panel = self.resolve_panel(name)?;
|
|
907
968
|
Ok(JsValue::from_serde_ext(
|
|
908
969
|
&panel.renderer.render_timer().get_stats(),
|
|
@@ -1000,12 +1061,13 @@ impl PerspectiveViewerElement {
|
|
|
1000
1061
|
/// - `options.panel` - The panel to target, or the active panel when
|
|
1001
1062
|
/// omitted.
|
|
1002
1063
|
/// - `options.suppress_errors` - when `true`, a failed restore only rejects
|
|
1003
|
-
/// the returned `Promise
|
|
1004
|
-
/// visible error state and
|
|
1005
|
-
///
|
|
1006
|
-
///
|
|
1007
|
-
///
|
|
1008
|
-
///
|
|
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.
|
|
1009
1071
|
///
|
|
1010
1072
|
/// # JavaScript Examples
|
|
1011
1073
|
///
|
|
@@ -1027,20 +1089,23 @@ impl PerspectiveViewerElement {
|
|
|
1027
1089
|
update: JsViewerConfigUpdate,
|
|
1028
1090
|
options: Option<JsRestoreOptions>,
|
|
1029
1091
|
) -> JsVoidPromise {
|
|
1030
|
-
let RestoreOptions {
|
|
1031
|
-
panel: name,
|
|
1032
|
-
suppress_errors,
|
|
1033
|
-
} = parse_options(options);
|
|
1034
|
-
|
|
1035
|
-
let errors = if suppress_errors.unwrap_or_default() {
|
|
1036
|
-
RestoreErrors::Suppress
|
|
1037
|
-
} else {
|
|
1038
|
-
RestoreErrors::Publish
|
|
1039
|
-
};
|
|
1040
|
-
|
|
1041
1092
|
let effect = self.workspace.effects().guard();
|
|
1042
1093
|
let this = self.clone();
|
|
1043
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
|
+
|
|
1044
1109
|
let _effect = effect;
|
|
1045
1110
|
let id = name.map(PanelId::from);
|
|
1046
1111
|
let mut update = ViewerConfigUpdate::decode(&update)?;
|
|
@@ -1074,19 +1139,6 @@ impl PerspectiveViewerElement {
|
|
|
1074
1139
|
};
|
|
1075
1140
|
|
|
1076
1141
|
if !matches!(settings, OptionalUpdate::Missing) {
|
|
1077
|
-
// Through `ToggleSettingsInit` — the SAME full choreography
|
|
1078
|
-
// the toolbar toggle drives (presize every visible plugin
|
|
1079
|
-
// to its post-toggle box, then the exactness-finalizer
|
|
1080
|
-
// resize) — NOT the bare `ToggleSettingsComplete` leaf,
|
|
1081
|
-
// which only re-renders the pane. The pane is the outer
|
|
1082
|
-
// `SplitPanel` (no `before-resize` event) and the host box
|
|
1083
|
-
// is unchanged, so a leaf-only toggle left every canvas
|
|
1084
|
-
// plugin CSS-stretched at its old backing size.
|
|
1085
|
-
//
|
|
1086
|
-
// No `set_settings_before_open` here: `is_settings_open` is
|
|
1087
|
-
// Init's toggle-vs-no-op DISPATCH state, so pre-writing the
|
|
1088
|
-
// target makes every call resolve as a no-op. Init owns the
|
|
1089
|
-
// write, as it does for the toolbar and `toggleConfig`.
|
|
1090
1142
|
let (sender, receiver) = channel::<ApiResult<JsValue>>();
|
|
1091
1143
|
this.root.borrow().as_ref().into_apierror()?.send_message(
|
|
1092
1144
|
PerspectiveViewerMsg::ToggleSettingsInit(Some(settings), false, Some(sender)),
|
|
@@ -1105,6 +1157,7 @@ impl PerspectiveViewerElement {
|
|
|
1105
1157
|
RestoreMode::Existing { active },
|
|
1106
1158
|
update,
|
|
1107
1159
|
errors,
|
|
1160
|
+
missing,
|
|
1108
1161
|
)
|
|
1109
1162
|
.await
|
|
1110
1163
|
},
|
|
@@ -1117,6 +1170,7 @@ impl PerspectiveViewerElement {
|
|
|
1117
1170
|
RestoreMode::Existing { active: true },
|
|
1118
1171
|
update,
|
|
1119
1172
|
errors,
|
|
1173
|
+
missing,
|
|
1120
1174
|
)
|
|
1121
1175
|
.await
|
|
1122
1176
|
},
|
|
@@ -1129,6 +1183,7 @@ impl PerspectiveViewerElement {
|
|
|
1129
1183
|
id,
|
|
1130
1184
|
*config,
|
|
1131
1185
|
None,
|
|
1186
|
+
missing,
|
|
1132
1187
|
)
|
|
1133
1188
|
.await?;
|
|
1134
1189
|
Ok(())
|
|
@@ -1139,25 +1194,47 @@ impl PerspectiveViewerElement {
|
|
|
1139
1194
|
js_sys::Promise::from(fut).unchecked_into()
|
|
1140
1195
|
}
|
|
1141
1196
|
|
|
1142
|
-
///
|
|
1143
|
-
///
|
|
1144
|
-
///
|
|
1145
|
-
///
|
|
1146
|
-
///
|
|
1147
|
-
///
|
|
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.
|
|
1148
1210
|
///
|
|
1149
1211
|
/// # JavaScript Examples
|
|
1150
1212
|
///
|
|
1151
1213
|
/// ```javascript
|
|
1152
1214
|
/// await viewer.restoreWorkspace(await otherViewer.saveWorkspace());
|
|
1153
1215
|
/// ```
|
|
1154
|
-
|
|
1155
|
-
|
|
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 {
|
|
1156
1227
|
let effect = self.workspace.effects().guard();
|
|
1157
1228
|
let this = self.clone();
|
|
1158
1229
|
let fut = ApiFuture::new(async move {
|
|
1159
1230
|
let _effect = effect;
|
|
1231
|
+
let RestoreWorkspaceOptions { wait_for_table } = parse_options(options)?;
|
|
1232
|
+
let missing = MissingTable::from_wait(wait_for_table);
|
|
1160
1233
|
let (contents, eject_tasks) = sync_update_panels(&this, update)?;
|
|
1234
|
+
let fresh = contents
|
|
1235
|
+
.iter()
|
|
1236
|
+
.map(|(id, ..)| id.clone())
|
|
1237
|
+
.collect::<Vec<_>>();
|
|
1161
1238
|
let results = join_all(contents.into_iter().map(|(id, session, renderer, config)| {
|
|
1162
1239
|
let presentation = this.presentation.clone();
|
|
1163
1240
|
let workspace = this.workspace.clone();
|
|
@@ -1171,6 +1248,7 @@ impl PerspectiveViewerElement {
|
|
|
1171
1248
|
RestoreMode::Fresh,
|
|
1172
1249
|
config,
|
|
1173
1250
|
crate::tasks::RestoreErrors::Publish,
|
|
1251
|
+
missing,
|
|
1174
1252
|
)
|
|
1175
1253
|
.await?;
|
|
1176
1254
|
if workspace.is_master(&id) {
|
|
@@ -1183,6 +1261,7 @@ impl PerspectiveViewerElement {
|
|
|
1183
1261
|
.await;
|
|
1184
1262
|
|
|
1185
1263
|
results.into_iter().collect::<ApiResult<Vec<_>>>()?;
|
|
1264
|
+
this.rerender_retained_overlays(&fresh).await?;
|
|
1186
1265
|
join_all(eject_tasks)
|
|
1187
1266
|
.await
|
|
1188
1267
|
.into_iter()
|
|
@@ -1246,9 +1325,9 @@ impl PerspectiveViewerElement {
|
|
|
1246
1325
|
/// });
|
|
1247
1326
|
/// ```
|
|
1248
1327
|
pub fn save(&self, options: Option<JsPanelOptions>) -> JsViewerConfigPromise {
|
|
1249
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
1250
1328
|
let this = self.clone();
|
|
1251
1329
|
let fut = ApiFuture::new(async move {
|
|
1330
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1252
1331
|
this.workspace.effects().settle().await;
|
|
1253
1332
|
let panel = this.resolve_panel(name)?;
|
|
1254
1333
|
let viewer_config = panel
|
|
@@ -1282,9 +1361,12 @@ impl PerspectiveViewerElement {
|
|
|
1282
1361
|
&self,
|
|
1283
1362
|
options: Option<JsSaveWorkspaceOptions>,
|
|
1284
1363
|
) -> JsWorkspaceConfigPromise {
|
|
1285
|
-
let SaveWorkspaceOptions { full_palette } = parse_options(options);
|
|
1286
1364
|
let this = self.clone();
|
|
1287
|
-
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
|
+
|
|
1288
1370
|
js_sys::Promise::from(fut).unchecked_into()
|
|
1289
1371
|
}
|
|
1290
1372
|
|
|
@@ -1303,13 +1385,13 @@ impl PerspectiveViewerElement {
|
|
|
1303
1385
|
/// })
|
|
1304
1386
|
/// ```
|
|
1305
1387
|
pub fn download(&self, options: Option<JsExportOptions>) -> ApiFuture<()> {
|
|
1306
|
-
let ExportOptions {
|
|
1307
|
-
method,
|
|
1308
|
-
panel: name,
|
|
1309
|
-
} = parse_options(options);
|
|
1310
|
-
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1311
1388
|
let this = self.clone();
|
|
1312
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()));
|
|
1313
1395
|
let method = if let Some(method) = method
|
|
1314
1396
|
.map(|x| x.unchecked_into())
|
|
1315
1397
|
.map(serde_wasm_bindgen::from_value)
|
|
@@ -1350,13 +1432,14 @@ impl PerspectiveViewerElement {
|
|
|
1350
1432
|
/// const data = await viewer.export("plugin");
|
|
1351
1433
|
/// ```
|
|
1352
1434
|
pub fn export(&self, options: Option<JsExportOptions>) -> ApiFuture<JsValue> {
|
|
1353
|
-
let ExportOptions {
|
|
1354
|
-
method,
|
|
1355
|
-
panel: name,
|
|
1356
|
-
} = parse_options(options);
|
|
1357
|
-
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1358
1435
|
let this = self.clone();
|
|
1359
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()));
|
|
1360
1443
|
let method = if let Some(method) = method
|
|
1361
1444
|
.map(|x| x.unchecked_into())
|
|
1362
1445
|
.map(serde_wasm_bindgen::from_value)
|
|
@@ -1388,13 +1471,14 @@ impl PerspectiveViewerElement {
|
|
|
1388
1471
|
/// })
|
|
1389
1472
|
/// ```
|
|
1390
1473
|
pub fn copy(&self, options: Option<JsExportOptions>) -> ApiFuture<()> {
|
|
1391
|
-
let ExportOptions {
|
|
1392
|
-
method,
|
|
1393
|
-
panel: name,
|
|
1394
|
-
} = parse_options(options);
|
|
1395
|
-
let method = method.map(|m| JsString::from(m.as_str()));
|
|
1396
1474
|
let this = self.clone();
|
|
1397
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()));
|
|
1398
1482
|
let method = if let Some(method) = method
|
|
1399
1483
|
.map(|x| x.unchecked_into())
|
|
1400
1484
|
.map(serde_wasm_bindgen::from_value)
|
|
@@ -1433,11 +1517,11 @@ impl PerspectiveViewerElement {
|
|
|
1433
1517
|
/// await viewer.reset(true, {panel: "p1"}); // just "p1", + expressions
|
|
1434
1518
|
/// ```
|
|
1435
1519
|
pub fn reset(&self, reset_all: Option<bool>, options: Option<JsPanelOptions>) -> ApiFuture<()> {
|
|
1436
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
1437
1520
|
let effect = self.workspace.effects().guard();
|
|
1438
1521
|
let this = self.clone();
|
|
1439
1522
|
let all = reset_all.unwrap_or_default();
|
|
1440
1523
|
ApiFuture::new_throttled(async move {
|
|
1524
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1441
1525
|
let _effect = effect;
|
|
1442
1526
|
let (completion, receiver) = Completion::new();
|
|
1443
1527
|
{
|
|
@@ -1615,7 +1699,7 @@ impl PerspectiveViewerElement {
|
|
|
1615
1699
|
/// region of the named panel, or the active panel when `panel` is omitted.
|
|
1616
1700
|
#[wasm_bindgen]
|
|
1617
1701
|
pub fn getSelection(&self, options: Option<JsPanelOptions>) -> ApiResult<Option<JsViewWindow>> {
|
|
1618
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
1702
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1619
1703
|
let panel = self.resolve_panel(name)?;
|
|
1620
1704
|
Ok(panel.renderer.get_selection().map(|x| x.into()))
|
|
1621
1705
|
}
|
|
@@ -1628,7 +1712,7 @@ impl PerspectiveViewerElement {
|
|
|
1628
1712
|
window: Option<JsViewWindow>,
|
|
1629
1713
|
options: Option<JsPanelOptions>,
|
|
1630
1714
|
) -> ApiResult<()> {
|
|
1631
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
1715
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1632
1716
|
let window = window.map(|x| x.into_serde_ext()).transpose()?;
|
|
1633
1717
|
self.resolve_panel(name)?.renderer.set_selection(window);
|
|
1634
1718
|
Ok(())
|
|
@@ -1639,7 +1723,7 @@ impl PerspectiveViewerElement {
|
|
|
1639
1723
|
/// `panel` is omitted.
|
|
1640
1724
|
#[wasm_bindgen]
|
|
1641
1725
|
pub fn getEditPort(&self, options: Option<JsPanelOptions>) -> ApiResult<f64> {
|
|
1642
|
-
let PanelOptions { panel: name } = parse_options(options)
|
|
1726
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1643
1727
|
let panel = self.resolve_panel(name)?;
|
|
1644
1728
|
let edit_port = if let Some(ctx) = panel.renderer.render_context() {
|
|
1645
1729
|
ctx.edit_port
|
|
@@ -1855,13 +1939,25 @@ impl PerspectiveViewerElement {
|
|
|
1855
1939
|
///
|
|
1856
1940
|
/// The element-level `settings` field does not exist on the argument
|
|
1857
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.
|
|
1858
1949
|
#[wasm_bindgen]
|
|
1859
|
-
pub fn addPanel(
|
|
1950
|
+
pub fn addPanel(
|
|
1951
|
+
&self,
|
|
1952
|
+
config: JsViewerConfigInitial,
|
|
1953
|
+
options: Option<JsAddPanelOptions>,
|
|
1954
|
+
) -> ApiFuture<JsValue> {
|
|
1860
1955
|
clone!(self.elem, self.presentation, self.workspace);
|
|
1861
1956
|
let effect = workspace.effects().guard();
|
|
1862
1957
|
let notify = self.layout_changed_notify();
|
|
1863
1958
|
ApiFuture::new(async move {
|
|
1864
1959
|
let _effect = effect;
|
|
1960
|
+
let AddPanelOptions { wait_for_table } = parse_options(options)?;
|
|
1865
1961
|
let config = ViewerConfigInitial::decode(&config)?;
|
|
1866
1962
|
let id = create_panel(
|
|
1867
1963
|
&elem,
|
|
@@ -1871,6 +1967,7 @@ impl PerspectiveViewerElement {
|
|
|
1871
1967
|
None,
|
|
1872
1968
|
config,
|
|
1873
1969
|
None,
|
|
1970
|
+
MissingTable::from_wait(wait_for_table),
|
|
1874
1971
|
)
|
|
1875
1972
|
.await?;
|
|
1876
1973
|
Ok(JsValue::from_str(id.as_str()))
|
|
@@ -1960,10 +2057,10 @@ impl PerspectiveViewerElement {
|
|
|
1960
2057
|
column_name: String,
|
|
1961
2058
|
options: Option<JsPanelOptions>,
|
|
1962
2059
|
) -> ApiFuture<()> {
|
|
1963
|
-
let PanelOptions { panel: name } = parse_options(options);
|
|
1964
2060
|
let effect = self.workspace.effects().guard();
|
|
1965
2061
|
let this = self.clone();
|
|
1966
2062
|
ApiFuture::new_throttled(async move {
|
|
2063
|
+
let PanelOptions { panel: name } = parse_options(options)?;
|
|
1967
2064
|
let _effect = effect;
|
|
1968
2065
|
let panel = this.resolve_panel(name)?;
|
|
1969
2066
|
let was_active = this.workspace.active_id().as_ref() == Some(&panel.id);
|
package/src/rust/js/plugin.rs
CHANGED
|
@@ -53,8 +53,10 @@ extern "C" {
|
|
|
53
53
|
#[wasm_bindgen(method, catch, js_name = column_config_schema)]
|
|
54
54
|
pub fn _column_config_schema(this: &JsPerspectiveViewerPlugin, view_type: &str, group: Option<&str>, column_name: &str, current_value: &JsValue, view_config: &JsValue, column_stats: &JsValue) -> ApiResult<JsValue>;
|
|
55
55
|
|
|
56
|
+
/// The plugin-level settings schema as it applies to `current_value`, the
|
|
57
|
+
/// `plugin_config` state the schema should describe.
|
|
56
58
|
#[wasm_bindgen(method, catch, js_name = plugin_config_schema)]
|
|
57
|
-
pub fn _plugin_config_schema(this: &JsPerspectiveViewerPlugin, view_config: &JsValue) -> ApiResult<JsValue>;
|
|
59
|
+
pub fn _plugin_config_schema(this: &JsPerspectiveViewerPlugin, view_config: &JsValue, current_value: &JsValue) -> ApiResult<JsValue>;
|
|
58
60
|
|
|
59
61
|
/// STATE TRANSFER, not rendering (dispatch semantics, rule for
|
|
60
62
|
/// `restore`/`save`): deliver a `plugin_config` + `columns_config`
|
package/src/rust/lib.rs
CHANGED
|
@@ -93,25 +93,29 @@ export type * from "../../src/ts/ts-rs/WorkspaceConfigUpdate.d.ts";
|
|
|
93
93
|
export type * from "../../src/ts/ts-rs/ExportMethod.d.ts";
|
|
94
94
|
export type * from "../../src/ts/ts-rs/PanelOptions.d.ts";
|
|
95
95
|
export type * from "../../src/ts/ts-rs/RestoreOptions.d.ts";
|
|
96
|
+
export type * from "../../src/ts/ts-rs/RestoreWorkspaceOptions.d.ts";
|
|
97
|
+
export type * from "../../src/ts/ts-rs/AddPanelOptions.d.ts";
|
|
96
98
|
export type * from "../../src/ts/ts-rs/SaveWorkspaceOptions.d.ts";
|
|
97
99
|
export type * from "../../src/ts/ts-rs/ClientOptions.d.ts";
|
|
98
100
|
export type * from "../../src/ts/ts-rs/ExportOptions.d.ts";
|
|
99
101
|
export type * from "../../src/ts/ts-rs/GetTableOptions.d.ts";
|
|
100
102
|
export type * from "../../src/ts/ts-rs/GetClientOptions.d.ts";
|
|
103
|
+
export type * from "../../src/ts/ts-rs/GetViewOptions.d.ts";
|
|
104
|
+
export type * from "../../src/ts/ts-rs/GetViewMode.d.ts";
|
|
101
105
|
export type * from "../../src/ts/ts-rs/CustomNumberFormatConfig.d.ts";
|
|
102
106
|
export type * from "../../src/ts/ts-rs/NumberFormatStyle.d.ts";
|
|
103
107
|
export type * from "../../src/ts/ts-rs/Notation.d.ts";
|
|
104
108
|
export type * from "../../src/ts/ts-rs/DatetimeFormatType.d.ts";
|
|
105
|
-
export type * from "../../src/ts/ts-rs/StringColorMode.d.ts";
|
|
106
|
-
export type * from "../../src/ts/ts-rs/DatetimeColorMode.d.ts";
|
|
107
|
-
export type * from "../../src/ts/ts-rs/FormatMode.d.ts";
|
|
108
109
|
|
|
109
110
|
import type {GetTableOptions} from "../../src/ts/ts-rs/GetTableOptions.d.ts";
|
|
110
111
|
import type {PanelOptions} from "../../src/ts/ts-rs/PanelOptions.d.ts";
|
|
111
112
|
import type {RestoreOptions} from "../../src/ts/ts-rs/RestoreOptions.d.ts";
|
|
113
|
+
import type {RestoreWorkspaceOptions} from "../../src/ts/ts-rs/RestoreWorkspaceOptions.d.ts";
|
|
114
|
+
import type {AddPanelOptions} from "../../src/ts/ts-rs/AddPanelOptions.d.ts";
|
|
112
115
|
import type {SaveWorkspaceOptions} from "../../src/ts/ts-rs/SaveWorkspaceOptions.d.ts";
|
|
113
116
|
import type {ExportOptions} from "../../src/ts/ts-rs/ExportOptions.d.ts";
|
|
114
117
|
import type {GetClientOptions} from "../../src/ts/ts-rs/GetClientOptions.d.ts";
|
|
118
|
+
import type {GetViewOptions} from "../../src/ts/ts-rs/GetViewOptions.d.ts";
|
|
115
119
|
import type {ClientOptions} from "../../src/ts/ts-rs/ClientOptions.d.ts";
|
|
116
120
|
import type {ViewerConfig} from "../../src/ts/ts-rs/ViewerConfig.d.ts";
|
|
117
121
|
import type {ViewerConfigUpdate} from "../../src/ts/ts-rs/ViewerConfigUpdate.d.ts";
|
|
@@ -29,18 +29,19 @@ struct ColumnStats {
|
|
|
29
29
|
abs_max: Option<f64>,
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/// Queries the active plugin for its plugin-scoped
|
|
33
|
-
///
|
|
34
|
-
/// drops the column-specific args — the schema describes the shape
|
|
35
|
-
/// of the plugin's own config bucket on the renderer.
|
|
32
|
+
/// Queries the active plugin for its plugin-scoped [`ColumnConfigSchema`] as
|
|
33
|
+
/// it applies to `current_value`.
|
|
36
34
|
pub fn get_plugin_config_schema(
|
|
37
35
|
renderer: &Renderer,
|
|
38
36
|
view_config: &ViewConfig,
|
|
37
|
+
current_value: Option<&serde_json::Map<String, serde_json::Value>>,
|
|
39
38
|
) -> ApiResult<ColumnConfigSchema> {
|
|
40
39
|
let plugin = renderer.ensure_plugin_selected()?;
|
|
41
40
|
let view_config_js =
|
|
42
41
|
wasm_bindgen::JsValue::from_serde_ext(view_config).unwrap_or(wasm_bindgen::JsValue::NULL);
|
|
43
|
-
let
|
|
42
|
+
let current_js = wasm_bindgen::JsValue::from_serde_ext(¤t_value)
|
|
43
|
+
.unwrap_or(wasm_bindgen::JsValue::NULL);
|
|
44
|
+
let raw = plugin._plugin_config_schema(&view_config_js, ¤t_js)?;
|
|
44
45
|
serde_wasm_bindgen::from_value::<ColumnConfigSchema>(raw)
|
|
45
46
|
.map(|schema| schema.canonicalize())
|
|
46
47
|
.map_err(|e| e.into())
|