@perspective-dev/viewer 4.0.1 → 4.1.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 +2 -2
- package/dist/cdn/perspective-viewer.js.map +4 -4
- 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/monokai.css +1 -1
- package/dist/css/pro-dark.css +1 -1
- package/dist/css/pro.css +1 -1
- package/dist/css/solarized-dark.css +1 -1
- package/dist/css/solarized.css +1 -1
- package/dist/css/themes.css +1 -1
- package/dist/css/vaporwave.css +1 -1
- package/dist/esm/extensions.d.ts +23 -2
- package/dist/esm/perspective-viewer.d.ts +2 -7
- package/dist/esm/perspective-viewer.inline.js +2 -2
- package/dist/esm/perspective-viewer.inline.js.map +4 -4
- package/dist/esm/perspective-viewer.js +2 -2
- package/dist/esm/perspective-viewer.js.map +4 -4
- package/dist/esm/plugin.d.ts +1 -1
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +1 -0
- package/dist/wasm/perspective-viewer.d.ts +218 -46
- package/dist/wasm/perspective-viewer.js +1250 -761
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +38 -19
- package/package.json +1 -1
- package/src/less/containers/scroll-panel.less +0 -1
- package/src/less/plugin-selector.less +15 -5
- package/src/less/status-bar.less +75 -27
- package/src/less/viewer.less +140 -58
- package/src/rust/components/column_dropdown.rs +21 -21
- package/src/rust/components/column_selector/active_column.rs +131 -120
- package/src/rust/components/column_selector/add_expression_button.rs +5 -0
- package/src/rust/components/column_selector/aggregate_selector.rs +8 -4
- package/src/rust/components/column_selector/config_selector.rs +170 -161
- package/src/rust/components/column_selector/empty_column.rs +16 -11
- package/src/rust/components/column_selector/{expression_toolbar.rs → expr_edit_button.rs} +7 -0
- package/src/rust/components/column_selector/filter_column.rs +195 -194
- package/src/rust/components/column_selector/inactive_column.rs +82 -67
- package/src/rust/components/column_selector/pivot_column.rs +16 -11
- package/src/rust/components/column_selector/sort_column.rs +9 -7
- package/src/rust/components/column_selector.rs +42 -37
- package/src/rust/components/column_settings_sidebar/save_settings.rs +3 -1
- package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +58 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +6 -6
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +2 -94
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +111 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +3 -3
- package/src/rust/components/column_settings_sidebar/style_tab.rs +23 -83
- package/src/rust/components/{column_settings_sidebar/sidebar.rs → column_settings_sidebar.rs} +198 -171
- package/src/rust/components/containers/dragdrop_list.rs +20 -20
- package/src/rust/components/containers/dropdown_menu.rs +4 -6
- package/src/rust/components/containers/mod.rs +1 -4
- package/src/rust/components/containers/scroll_panel.rs +80 -80
- package/src/rust/components/containers/scroll_panel_item.rs +36 -36
- package/src/rust/components/containers/select.rs +46 -44
- package/src/rust/components/containers/sidebar.rs +3 -19
- package/src/rust/components/{column_settings_sidebar/style_tab/symbol/symbol_config.rs → containers/sidebar_close_button.rs} +15 -9
- package/src/rust/components/containers/split_panel.rs +212 -200
- package/src/rust/components/containers/tab_list.rs +11 -11
- package/src/rust/components/copy_dropdown.rs +22 -25
- package/src/rust/components/datetime_column_style/custom.rs +19 -19
- package/src/rust/components/datetime_column_style/simple.rs +13 -14
- package/src/rust/components/datetime_column_style.rs +75 -76
- package/src/rust/components/editable_header.rs +18 -14
- package/src/rust/components/empty_row.rs +5 -5
- package/src/rust/components/export_dropdown.rs +42 -42
- package/src/rust/components/expression_editor.rs +25 -19
- package/src/rust/components/filter_dropdown.rs +22 -22
- package/src/rust/components/font_loader.rs +11 -9
- package/src/rust/components/form/code_editor.rs +106 -105
- package/src/rust/components/form/color_range_selector.rs +14 -12
- package/src/rust/components/form/color_selector.rs +3 -1
- package/src/rust/components/form/debug.rs +95 -94
- package/src/rust/components/form/highlight.rs +5 -3
- package/src/rust/components/form/mod.rs +3 -2
- package/src/rust/components/form/optional_field.rs +2 -2
- package/src/rust/components/form/{select_field.rs → select_enum_field.rs} +1 -46
- package/src/rust/components/form/select_value_field.rs +64 -0
- package/src/rust/components/function_dropdown.rs +21 -21
- package/src/rust/components/main_panel.rs +219 -0
- package/src/rust/components/mod.rs +6 -6
- package/src/rust/components/modal.rs +42 -42
- package/src/rust/components/number_column_style.rs +34 -88
- package/src/rust/components/plugin_selector.rs +22 -25
- package/src/rust/components/render_warning.rs +9 -6
- package/src/rust/components/settings_panel.rs +82 -0
- package/src/rust/components/status_bar.rs +250 -146
- package/src/rust/components/status_bar_counter.rs +26 -119
- package/src/rust/components/status_indicator.rs +95 -79
- package/src/rust/components/string_column_style.rs +45 -45
- package/src/rust/components/style/style_provider.rs +1 -15
- package/src/rust/components/style_controls/number_string_format/digits_section.rs +1 -1
- 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/style_controls/number_string_format.rs +45 -46
- package/src/rust/components/type_icon.rs +14 -11
- package/src/rust/components/viewer.rs +241 -384
- package/src/rust/config/columns_config.rs +2 -2
- package/src/rust/config/datetime_column_style.rs +1 -6
- package/src/rust/config/mod.rs +1 -0
- package/src/rust/config/number_column_style.rs +0 -6
- package/src/rust/config/number_string_format.rs +27 -4
- package/src/rust/config/viewer_config.rs +27 -167
- package/src/rust/custom_elements/copy_dropdown.rs +14 -6
- package/src/rust/custom_elements/export_dropdown.rs +15 -7
- package/src/rust/custom_elements/filter_dropdown.rs +4 -4
- package/src/rust/custom_elements/mod.rs +3 -0
- package/src/rust/custom_elements/viewer.rs +353 -161
- package/src/rust/custom_events.rs +55 -32
- package/src/rust/dragdrop.rs +4 -24
- package/src/rust/exprtk/cursor.rs +10 -1
- package/src/rust/exprtk/mod.rs +2 -0
- package/src/rust/exprtk/tokenize.rs +20 -3
- package/src/rust/js/clipboard.rs +2 -2
- package/src/rust/js/mimetype.rs +2 -7
- package/src/rust/js/mod.rs +0 -1
- package/src/rust/js/plugin.rs +7 -0
- package/src/rust/lib.rs +18 -5
- package/src/rust/model/column_locator.rs +82 -0
- package/src/rust/model/columns_iter_set.rs +1 -0
- package/src/rust/model/copy_export.rs +50 -14
- package/src/rust/model/edit_expression.rs +2 -5
- package/src/rust/model/eject.rs +41 -0
- package/src/rust/model/get_viewer_config.rs +4 -28
- package/src/rust/model/intersection_observer.rs +20 -8
- package/src/rust/model/mod.rs +11 -4
- package/src/rust/model/plugin_column_styles.rs +0 -31
- package/src/rust/model/reset_all.rs +38 -0
- package/src/rust/model/resize_observer.rs +34 -7
- package/src/rust/model/restore_and_render.rs +12 -7
- package/src/rust/{utils/scope.rs → model/send_plugin_config.rs} +32 -35
- package/src/rust/model/structural.rs +194 -23
- package/src/rust/model/update_and_render.rs +14 -4
- package/src/rust/{model/create_col.rs → presentation/column_locator.rs} +73 -42
- package/src/rust/{utils/wasm_abi.rs → presentation/sheets.rs} +54 -40
- package/src/rust/presentation.rs +60 -119
- package/src/rust/renderer/activate.rs +20 -5
- package/src/rust/renderer/limits.rs +0 -149
- package/src/rust/renderer/render_timer.rs +1 -1
- package/src/rust/renderer.rs +34 -18
- package/src/rust/root.rs +50 -0
- package/src/rust/session/column_defaults_update.rs +4 -4
- package/src/rust/session/drag_drop_update.rs +1 -1
- package/src/rust/session/metadata.rs +3 -17
- package/src/rust/session/replace_expression_update.rs +1 -2
- package/src/rust/session.rs +162 -82
- package/src/rust/utils/browser/blob.rs +16 -2
- package/src/rust/utils/browser/download.rs +1 -0
- package/src/rust/{components/column_settings_sidebar/mod.rs → utils/browser/dragdrop.rs} +14 -5
- package/src/rust/utils/browser/mod.rs +8 -4
- package/src/rust/utils/browser/selection.rs +5 -0
- package/src/rust/utils/custom_element.rs +28 -13
- package/src/rust/utils/datetime.rs +5 -0
- package/src/rust/utils/debounce.rs +7 -1
- package/src/rust/utils/hooks/use_async_callback.rs +7 -17
- package/src/rust/utils/mod.rs +28 -40
- package/src/rust/utils/number_format.rs +6 -5
- package/src/rust/utils/pubsub.rs +15 -10
- package/src/rust/utils/weak_scope.rs +11 -1
- package/src/svg/bookmark-icon.svg +4 -0
- package/src/svg/drag-handle copy.svg +10 -0
- package/src/svg/drawer-tab-hover.svg +5 -7
- package/src/svg/drawer-tab-invert-hover.svg +4 -8
- package/src/svg/drawer-tab-invert.svg +4 -7
- package/src/svg/drawer-tab.svg +4 -6
- package/src/svg/status_ok.svg +24 -24
- package/src/ts/extensions.ts +51 -3
- package/src/ts/perspective-viewer.ts +2 -14
- package/src/ts/plugin.ts +1 -1
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +0 -177
- package/src/rust/components/containers/tests/mod.rs +0 -11
- package/src/rust/components/containers/tests/split_panel.rs +0 -91
- package/src/rust/js/testing.rs +0 -149
- package/src/rust/utils/tee.rs +0 -88
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-0d326a25c1022412}/inline4.js +0 -0
- /package/src/rust/components/{style_controls.rs → style_controls/mod.rs} +0 -0
- /package/src/rust/{components/containers → config}/kvpair.rs +0 -0
|
@@ -14,20 +14,17 @@ use perspective_client::config::{Expression, ViewConfigUpdate};
|
|
|
14
14
|
|
|
15
15
|
use super::UpdateAndRender;
|
|
16
16
|
use super::structural::*;
|
|
17
|
-
use crate::
|
|
18
|
-
use crate::components::viewer::ColumnLocator;
|
|
19
|
-
use crate::presentation::{OpenColumnSettings, Presentation};
|
|
17
|
+
use crate::presentation::{ColumnLocator, ColumnSettingsTab, OpenColumnSettings, Presentation};
|
|
20
18
|
use crate::renderer::Renderer;
|
|
21
19
|
use crate::session::Session;
|
|
22
20
|
use crate::*;
|
|
23
21
|
|
|
24
|
-
#[derive(PartialEq)]
|
|
22
|
+
#[derive(PartialEq, PerspectiveProperties!)]
|
|
25
23
|
pub struct ExpressionUpdater {
|
|
26
24
|
presentation: Presentation,
|
|
27
25
|
renderer: Renderer,
|
|
28
26
|
session: Session,
|
|
29
27
|
}
|
|
30
|
-
derive_model!(Presentation, Renderer, Session for ExpressionUpdater);
|
|
31
28
|
|
|
32
29
|
pub trait EditExpression: HasPresentation + HasRenderer + HasSession + UpdateAndRender {
|
|
33
30
|
fn get_expression_updater(&self) -> ExpressionUpdater {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
use perspective_client::clone;
|
|
14
|
+
use yew::Component;
|
|
15
|
+
|
|
16
|
+
use super::{HasRenderer, HasSession};
|
|
17
|
+
use crate::ApiFuture;
|
|
18
|
+
use crate::root::Root;
|
|
19
|
+
use crate::session::ResetOptions;
|
|
20
|
+
|
|
21
|
+
pub trait DeleteAll: HasSession + HasRenderer {
|
|
22
|
+
fn delete_all<T: Component>(&self, root: &Root<T>) -> ApiFuture<()> {
|
|
23
|
+
self.session().table_unloaded.emit(false);
|
|
24
|
+
clone!(self.renderer(), self.session(), root);
|
|
25
|
+
ApiFuture::new(self.renderer().clone().with_lock(async move {
|
|
26
|
+
renderer.delete()?;
|
|
27
|
+
root.borrow_mut().take().ok_or("Already deleted")?.destroy();
|
|
28
|
+
session
|
|
29
|
+
.reset(ResetOptions {
|
|
30
|
+
config: true,
|
|
31
|
+
expressions: true,
|
|
32
|
+
table: true,
|
|
33
|
+
..ResetOptions::default()
|
|
34
|
+
})
|
|
35
|
+
.await?;
|
|
36
|
+
Ok(())
|
|
37
|
+
}))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
impl<T: HasSession + HasRenderer> DeleteAll for T {}
|
|
@@ -15,9 +15,6 @@ use perspective_client::config::ViewConfig;
|
|
|
15
15
|
use super::columns_iter_set::*;
|
|
16
16
|
use super::structural::*;
|
|
17
17
|
use crate::config::*;
|
|
18
|
-
use crate::presentation::Presentation;
|
|
19
|
-
use crate::renderer::*;
|
|
20
|
-
use crate::session::*;
|
|
21
18
|
use crate::*;
|
|
22
19
|
|
|
23
20
|
/// A `ViewerConfig` is constructed from various properties acrosss the
|
|
@@ -27,21 +24,7 @@ use crate::*;
|
|
|
27
24
|
/// `GetViewerConfigModel` provides methods which should be used to get the
|
|
28
25
|
/// applications `ViewerConfig` from across these state objects.
|
|
29
26
|
pub trait GetViewerConfigModel: HasSession + HasRenderer + HasPresentation {
|
|
30
|
-
///
|
|
31
|
-
/// discretely `.clone()` the state objects for dispatching to `async`.
|
|
32
|
-
///
|
|
33
|
-
/// Calling `.cloned()` yields just the state object clones of
|
|
34
|
-
/// `GetViewerConfigModel` which itself implements this trait and other
|
|
35
|
-
/// `crate::model` traits.
|
|
36
|
-
fn cloned(&self) -> GetViewerConfigModelCloned {
|
|
37
|
-
GetViewerConfigModelCloned {
|
|
38
|
-
renderer: self.renderer().clone(),
|
|
39
|
-
session: self.session().clone(),
|
|
40
|
-
presentation: self.presentation().clone(),
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/// Get the current ViewerConfig
|
|
27
|
+
/// Get the current [`ViewerConfig`]`
|
|
45
28
|
async fn get_viewer_config(&self) -> ApiResult<ViewerConfig> {
|
|
46
29
|
let version = config::API_VERSION.to_string();
|
|
47
30
|
let view_config = self.session().get_view_config().clone();
|
|
@@ -50,7 +33,8 @@ pub trait GetViewerConfigModel: HasSession + HasRenderer + HasPresentation {
|
|
|
50
33
|
let plugin = js_plugin.name();
|
|
51
34
|
let plugin_config: serde_json::Value = js_plugin.save()?.into_serde_ext()?;
|
|
52
35
|
let theme = self.presentation().get_selected_theme_name().await;
|
|
53
|
-
let title = self.
|
|
36
|
+
let title = self.session().get_title();
|
|
37
|
+
let table = self.session().get_table().map(|x| x.get_name().to_owned());
|
|
54
38
|
let columns_config = self.presentation().all_columns_configs();
|
|
55
39
|
Ok(ViewerConfig {
|
|
56
40
|
version,
|
|
@@ -59,6 +43,7 @@ pub trait GetViewerConfigModel: HasSession + HasRenderer + HasPresentation {
|
|
|
59
43
|
plugin_config,
|
|
60
44
|
columns_config,
|
|
61
45
|
settings,
|
|
46
|
+
table,
|
|
62
47
|
view_config,
|
|
63
48
|
theme,
|
|
64
49
|
})
|
|
@@ -67,15 +52,6 @@ pub trait GetViewerConfigModel: HasSession + HasRenderer + HasPresentation {
|
|
|
67
52
|
|
|
68
53
|
impl<T: HasRenderer + HasSession + HasPresentation> GetViewerConfigModel for T {}
|
|
69
54
|
|
|
70
|
-
#[derive(Clone)]
|
|
71
|
-
pub struct GetViewerConfigModelCloned {
|
|
72
|
-
renderer: Renderer,
|
|
73
|
-
session: Session,
|
|
74
|
-
presentation: Presentation,
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
derive_model!(Renderer, Session, Presentation for GetViewerConfigModelCloned);
|
|
78
|
-
|
|
79
55
|
pub trait ColumnIteratorModel: HasSession + HasRenderer + HasDragDrop {
|
|
80
56
|
fn column_selector_iter_set<'a>(&'a self, config: &'a ViewConfig) -> ColumnsIteratorSet<'a> {
|
|
81
57
|
ColumnsIteratorSet::new(config, self.session(), self.renderer(), self.dragdrop())
|
|
@@ -10,13 +10,14 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
use perspective_client::config::ViewConfigUpdate;
|
|
14
13
|
use wasm_bindgen::JsCast;
|
|
15
14
|
use wasm_bindgen::prelude::*;
|
|
16
15
|
use web_sys::*;
|
|
17
16
|
|
|
17
|
+
use crate::config::ViewerConfigUpdate;
|
|
18
18
|
use crate::js::*;
|
|
19
19
|
use crate::model::*;
|
|
20
|
+
use crate::presentation::Presentation;
|
|
20
21
|
use crate::renderer::*;
|
|
21
22
|
use crate::session::Session;
|
|
22
23
|
use crate::utils::*;
|
|
@@ -29,16 +30,25 @@ pub struct IntersectionObserverHandle {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
impl IntersectionObserverHandle {
|
|
32
|
-
pub fn new(
|
|
33
|
-
|
|
33
|
+
pub fn new(
|
|
34
|
+
elem: &HtmlElement,
|
|
35
|
+
presentation: &Presentation,
|
|
36
|
+
session: &Session,
|
|
37
|
+
renderer: &Renderer,
|
|
38
|
+
) -> Self {
|
|
39
|
+
clone!(session, renderer, presentation);
|
|
34
40
|
let _callback = Closure::new(move |xs: js_sys::Array| {
|
|
35
41
|
let intersect = xs
|
|
36
42
|
.get(0)
|
|
37
43
|
.unchecked_into::<IntersectionObserverEntry>()
|
|
38
44
|
.is_intersecting();
|
|
39
45
|
|
|
40
|
-
clone!(session, renderer);
|
|
41
|
-
let state = IntersectionObserverState {
|
|
46
|
+
clone!(session, renderer, presentation);
|
|
47
|
+
let state = IntersectionObserverState {
|
|
48
|
+
presentation,
|
|
49
|
+
session,
|
|
50
|
+
renderer,
|
|
51
|
+
};
|
|
42
52
|
ApiFuture::spawn(state.set_pause(intersect));
|
|
43
53
|
});
|
|
44
54
|
|
|
@@ -59,16 +69,20 @@ impl Drop for IntersectionObserverHandle {
|
|
|
59
69
|
}
|
|
60
70
|
}
|
|
61
71
|
|
|
72
|
+
#[derive(PerspectiveProperties!)]
|
|
62
73
|
struct IntersectionObserverState {
|
|
63
74
|
session: Session,
|
|
64
75
|
renderer: Renderer,
|
|
76
|
+
presentation: Presentation,
|
|
65
77
|
}
|
|
66
78
|
|
|
67
79
|
impl IntersectionObserverState {
|
|
68
80
|
async fn set_pause(self, intersect: bool) -> ApiResult<()> {
|
|
69
81
|
if intersect {
|
|
70
82
|
if self.session.set_pause(false) {
|
|
71
|
-
self.
|
|
83
|
+
self.presentation.visibility_changed.emit(intersect);
|
|
84
|
+
self.restore_and_render(ViewerConfigUpdate::default(), async move { Ok(()) })
|
|
85
|
+
.await?;
|
|
72
86
|
}
|
|
73
87
|
} else {
|
|
74
88
|
self.session.set_pause(true);
|
|
@@ -77,5 +91,3 @@ impl IntersectionObserverState {
|
|
|
77
91
|
Ok(())
|
|
78
92
|
}
|
|
79
93
|
}
|
|
80
|
-
|
|
81
|
-
derive_model!(Renderer, Session for IntersectionObserverState);
|
package/src/rust/model/mod.rs
CHANGED
|
@@ -30,23 +30,22 @@
|
|
|
30
30
|
//! # Examples
|
|
31
31
|
//!
|
|
32
32
|
//! ```rust
|
|
33
|
+
//! #[derive(PerspectiveProperties!)]
|
|
33
34
|
//! struct A {
|
|
34
35
|
//! session: Session,
|
|
35
36
|
//! }
|
|
36
37
|
//!
|
|
38
|
+
//! #[derive(PerspectiveProperties!)]
|
|
37
39
|
//! struct B {
|
|
38
40
|
//! renderer: Renderer,
|
|
39
41
|
//! }
|
|
40
42
|
//!
|
|
43
|
+
//! #[derive(PerspectiveProperties!)]
|
|
41
44
|
//! struct C {
|
|
42
45
|
//! session: Session,
|
|
43
46
|
//! renderer: Renderer,
|
|
44
47
|
//! }
|
|
45
48
|
//!
|
|
46
|
-
//! derive_model!(Session for A);
|
|
47
|
-
//! derive_model!(Renderer for B);
|
|
48
|
-
//! derive_model!(Session, Renderer for C);
|
|
49
|
-
//!
|
|
50
49
|
//! trait SessionRenderModel: HasSession + HasRenderer {
|
|
51
50
|
//! fn render_session_now(&self) {
|
|
52
51
|
//! // Do some thing that requires `.session()` and `.renderer()`
|
|
@@ -65,29 +64,37 @@
|
|
|
65
64
|
//! }
|
|
66
65
|
//! ```
|
|
67
66
|
|
|
67
|
+
mod column_locator;
|
|
68
68
|
mod columns_iter_set;
|
|
69
69
|
mod copy_export;
|
|
70
70
|
mod edit_expression;
|
|
71
|
+
mod eject;
|
|
71
72
|
mod export_app;
|
|
72
73
|
mod export_method;
|
|
73
74
|
mod get_viewer_config;
|
|
74
75
|
mod intersection_observer;
|
|
75
76
|
mod is_invalid_drop;
|
|
76
77
|
mod plugin_column_styles;
|
|
78
|
+
mod reset_all;
|
|
77
79
|
mod resize_observer;
|
|
78
80
|
mod restore_and_render;
|
|
81
|
+
mod send_plugin_config;
|
|
79
82
|
mod structural;
|
|
80
83
|
mod update_and_render;
|
|
81
84
|
|
|
85
|
+
pub use self::column_locator::*;
|
|
82
86
|
pub use self::columns_iter_set::*;
|
|
83
87
|
pub use self::copy_export::*;
|
|
84
88
|
pub use self::edit_expression::*;
|
|
89
|
+
pub use self::eject::*;
|
|
85
90
|
pub use self::export_method::*;
|
|
86
91
|
pub use self::get_viewer_config::*;
|
|
87
92
|
pub use self::intersection_observer::*;
|
|
88
93
|
pub use self::is_invalid_drop::*;
|
|
89
94
|
pub use self::plugin_column_styles::*;
|
|
95
|
+
pub use self::reset_all::*;
|
|
90
96
|
pub use self::resize_observer::*;
|
|
91
97
|
pub use self::restore_and_render::*;
|
|
98
|
+
pub use self::send_plugin_config::*;
|
|
92
99
|
pub use self::structural::*;
|
|
93
100
|
pub use self::update_and_render::*;
|
|
@@ -15,39 +15,8 @@ use perspective_js::utils::ApiResult;
|
|
|
15
15
|
|
|
16
16
|
use super::{HasRenderer, HasSession};
|
|
17
17
|
use crate::config::ColumnStyleOpts;
|
|
18
|
-
use crate::derive_model;
|
|
19
|
-
use crate::renderer::Renderer;
|
|
20
|
-
use crate::session::Session;
|
|
21
|
-
|
|
22
|
-
// TODO: This pattern of creating query objects to pass around would be
|
|
23
|
-
// redundant if we had a grab-bag of models to clone around.
|
|
24
|
-
// We could easily generate all the needed types for this in a proc_macro
|
|
25
|
-
// crate. e.g. create structs like `SessionAndRendererModel {session,
|
|
26
|
-
// renderer}` which are then called through a proc_macro like
|
|
27
|
-
// `get_model!(Session, Renderer for self)` where the function is defined as
|
|
28
|
-
// `get_model! => {($($name:ty),+ for $owner:ident)}`
|
|
29
|
-
//
|
|
30
|
-
// Or, we could just lump
|
|
31
|
-
// all the state into a single object where all these model functions are
|
|
32
|
-
// defined. Generally, we could keep the hub-and-spoke architecture "under the
|
|
33
|
-
// hood", but just not expose it to the yew framework, since it requires a lot
|
|
34
|
-
// of unecessary prop-drilling and complexity.
|
|
35
|
-
|
|
36
|
-
#[derive(Clone)]
|
|
37
|
-
pub struct PluginColumnStylesQuery {
|
|
38
|
-
session: Session,
|
|
39
|
-
renderer: Renderer,
|
|
40
|
-
}
|
|
41
|
-
derive_model!(Session, Renderer for PluginColumnStylesQuery);
|
|
42
18
|
|
|
43
19
|
pub trait PluginColumnStyles: HasSession + HasRenderer {
|
|
44
|
-
fn get_plugin_column_styles_query(&self) -> PluginColumnStylesQuery {
|
|
45
|
-
PluginColumnStylesQuery {
|
|
46
|
-
session: self.session().clone(),
|
|
47
|
-
renderer: self.renderer().clone(),
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
20
|
/// This function will query the plugin to see if a given column can render
|
|
52
21
|
/// column styles.
|
|
53
22
|
fn can_render_column_styles(&self, column_name: &str) -> ApiResult<bool> {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
use super::structural::*;
|
|
14
|
+
use crate::session::ResetOptions;
|
|
15
|
+
use crate::utils::*;
|
|
16
|
+
use crate::*;
|
|
17
|
+
|
|
18
|
+
pub trait ResetAll: HasRenderer + HasSession + HasPresentation {
|
|
19
|
+
/// Completely reset viewer state
|
|
20
|
+
fn reset_all(&self) -> ApiFuture<()> {
|
|
21
|
+
clone!(self.session(), self.renderer(), self.presentation());
|
|
22
|
+
ApiFuture::new(async move {
|
|
23
|
+
session
|
|
24
|
+
.reset(ResetOptions {
|
|
25
|
+
config: true,
|
|
26
|
+
expressions: true,
|
|
27
|
+
..ResetOptions::default()
|
|
28
|
+
})
|
|
29
|
+
.await?;
|
|
30
|
+
presentation.reset_columns_configs();
|
|
31
|
+
renderer.reset(None).await?;
|
|
32
|
+
presentation.reset_available_themes(None).await;
|
|
33
|
+
Ok(())
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
impl<T: HasRenderer + HasSession + HasPresentation> ResetAll for T {}
|
|
@@ -16,9 +16,13 @@ use wasm_bindgen::prelude::*;
|
|
|
16
16
|
use web_sys::*;
|
|
17
17
|
use yew::prelude::*;
|
|
18
18
|
|
|
19
|
+
use crate::PerspectiveProperties;
|
|
19
20
|
use crate::components::viewer::{PerspectiveViewer, PerspectiveViewerMsg};
|
|
20
21
|
use crate::js::*;
|
|
22
|
+
use crate::model::*;
|
|
21
23
|
use crate::renderer::*;
|
|
24
|
+
use crate::root::Root;
|
|
25
|
+
use crate::session::Session;
|
|
22
26
|
use crate::utils::*;
|
|
23
27
|
|
|
24
28
|
pub struct ResizeObserverHandle {
|
|
@@ -31,20 +35,26 @@ impl ResizeObserverHandle {
|
|
|
31
35
|
pub fn new(
|
|
32
36
|
elem: &HtmlElement,
|
|
33
37
|
renderer: &Renderer,
|
|
34
|
-
|
|
38
|
+
session: &Session,
|
|
39
|
+
root: &Root<PerspectiveViewer>,
|
|
35
40
|
) -> Self {
|
|
36
|
-
let on_resize = root
|
|
41
|
+
let on_resize = root
|
|
42
|
+
.borrow()
|
|
43
|
+
.as_ref()
|
|
44
|
+
.unwrap()
|
|
45
|
+
.callback(|()| PerspectiveViewerMsg::Resize);
|
|
46
|
+
|
|
37
47
|
let mut state = ResizeObserverState {
|
|
38
48
|
elem: elem.clone(),
|
|
39
49
|
renderer: renderer.clone(),
|
|
50
|
+
session: session.clone(),
|
|
40
51
|
width: elem.offset_width(),
|
|
41
52
|
height: elem.offset_height(),
|
|
42
53
|
on_resize,
|
|
43
54
|
};
|
|
44
55
|
|
|
45
|
-
let _callback = Closure::new(move |xs| state.on_resize(&xs));
|
|
46
|
-
let
|
|
47
|
-
let observer = ResizeObserver::new(func);
|
|
56
|
+
let _callback = Closure::new(move |xs: js_sys::Array| state.on_resize(&xs));
|
|
57
|
+
let observer = ResizeObserver::new(_callback.as_ref().unchecked_ref::<js_sys::Function>());
|
|
48
58
|
observer.observe(elem);
|
|
49
59
|
Self {
|
|
50
60
|
elem: elem.clone(),
|
|
@@ -60,9 +70,11 @@ impl Drop for ResizeObserverHandle {
|
|
|
60
70
|
}
|
|
61
71
|
}
|
|
62
72
|
|
|
73
|
+
#[derive(PerspectiveProperties!)]
|
|
63
74
|
struct ResizeObserverState {
|
|
64
75
|
elem: HtmlElement,
|
|
65
76
|
renderer: Renderer,
|
|
77
|
+
session: Session,
|
|
66
78
|
width: i32,
|
|
67
79
|
height: i32,
|
|
68
80
|
on_resize: Callback<()>,
|
|
@@ -83,9 +95,24 @@ impl ResizeObserverState {
|
|
|
83
95
|
let content_height = content.height().floor() as i32;
|
|
84
96
|
let resized = self.width != content_width || self.height != content_height;
|
|
85
97
|
if resized && is_visible {
|
|
86
|
-
|
|
98
|
+
let state = self.clone_state();
|
|
99
|
+
clone!(self.on_resize);
|
|
87
100
|
ApiFuture::spawn(async move {
|
|
88
|
-
|
|
101
|
+
let needs_render = state
|
|
102
|
+
.renderer()
|
|
103
|
+
.clone()
|
|
104
|
+
.with_lock(async {
|
|
105
|
+
Ok(!state.renderer().is_plugin_activated()?
|
|
106
|
+
&& state.session().has_table())
|
|
107
|
+
})
|
|
108
|
+
.await?;
|
|
109
|
+
|
|
110
|
+
if needs_render {
|
|
111
|
+
state.update_and_render(Default::default())?.await?;
|
|
112
|
+
} else {
|
|
113
|
+
state.renderer().resize().await?;
|
|
114
|
+
}
|
|
115
|
+
|
|
89
116
|
on_resize.emit(());
|
|
90
117
|
Ok(())
|
|
91
118
|
});
|
|
@@ -35,16 +35,15 @@ pub trait RestoreAndRender: HasRenderer + HasSession + HasPresentation {
|
|
|
35
35
|
) -> ApiFuture<()> {
|
|
36
36
|
clone!(self.session(), self.renderer(), self.presentation());
|
|
37
37
|
ApiFuture::new(async move {
|
|
38
|
-
if
|
|
39
|
-
&& let OptionalUpdate::Update(x) = settings
|
|
40
|
-
{
|
|
38
|
+
if let OptionalUpdate::Update(x) = settings {
|
|
41
39
|
presentation.set_settings_attribute(x);
|
|
40
|
+
presentation.set_settings_before_open(x);
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
if let OptionalUpdate::Update(title) = title {
|
|
45
|
-
|
|
44
|
+
session.set_title(Some(title));
|
|
46
45
|
} else if matches!(title, OptionalUpdate::SetDefault) {
|
|
47
|
-
|
|
46
|
+
session.set_title(None);
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
let needs_restyle = match theme_name {
|
|
@@ -93,17 +92,23 @@ pub trait RestoreAndRender: HasRenderer + HasSession + HasPresentation {
|
|
|
93
92
|
return Err(error);
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
session.validate().await?.create_view().await
|
|
95
|
+
let view = session.validate().await?.create_view().await;
|
|
96
|
+
if !presentation.is_visible() {
|
|
97
|
+
Ok(None)
|
|
98
|
+
} else {
|
|
99
|
+
view
|
|
100
|
+
}
|
|
97
101
|
});
|
|
98
102
|
|
|
99
103
|
draw_task.await?;
|
|
100
104
|
|
|
101
105
|
// TODO this should be part of the API for `draw()` above, such that
|
|
102
106
|
// the plugin need not render twice when a theme is provided.
|
|
103
|
-
if needs_restyle {
|
|
107
|
+
if needs_restyle && presentation.is_visible() {
|
|
104
108
|
let view = session.get_view().into_apierror()?;
|
|
105
109
|
renderer.restyle_all(&view).await?;
|
|
106
110
|
}
|
|
111
|
+
// }
|
|
107
112
|
|
|
108
113
|
Ok(())
|
|
109
114
|
})
|
|
@@ -10,45 +10,42 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
use
|
|
14
|
-
use futures::channel::oneshot::*;
|
|
15
|
-
use perspective_js::utils::ApiResult;
|
|
16
|
-
use yew::html::Scope;
|
|
17
|
-
use yew::prelude::*;
|
|
13
|
+
use perspective_js::utils::*;
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/// invoked.
|
|
26
|
-
fn send_message_async<F, U>(&self, f: F) -> Receiver<U>
|
|
27
|
-
where
|
|
28
|
-
F: FnOnce(Sender<U>) -> T::Message,
|
|
29
|
-
{
|
|
30
|
-
let (sender, receiver) = channel::<U>();
|
|
31
|
-
self.send_message(f(sender));
|
|
32
|
-
receiver
|
|
33
|
-
}
|
|
15
|
+
use crate::config::ColumnConfigValueUpdate;
|
|
16
|
+
use crate::model::*;
|
|
17
|
+
|
|
18
|
+
pub trait SendPluginConfig {
|
|
19
|
+
/// Update te urrent plugin with a [`ColumnonfigValueUpdate`]
|
|
20
|
+
fn send_plugin_config(&self, column_name: &str, update: ColumnConfigValueUpdate);
|
|
34
21
|
}
|
|
35
22
|
|
|
36
|
-
|
|
37
|
-
pub(crate) impl<T> Callback<Sender<T>>
|
|
23
|
+
impl<A> SendPluginConfig for A
|
|
38
24
|
where
|
|
39
|
-
|
|
25
|
+
A: Clone + HasCustomEvents + HasPresentation + HasRenderer + HasSession + 'static,
|
|
40
26
|
{
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
27
|
+
fn send_plugin_config(&self, column_name: &str, update: ColumnConfigValueUpdate) {
|
|
28
|
+
let name = column_name.to_string();
|
|
29
|
+
let props = self.clone();
|
|
30
|
+
ApiFuture::spawn(async move {
|
|
31
|
+
props
|
|
32
|
+
.presentation()
|
|
33
|
+
.update_columns_config_value(name.clone(), update);
|
|
34
|
+
|
|
35
|
+
let columns_configs = props.presentation().all_columns_configs();
|
|
36
|
+
let plugin_config = props.renderer().get_active_plugin()?.save()?;
|
|
37
|
+
props
|
|
38
|
+
.renderer()
|
|
39
|
+
.get_active_plugin()?
|
|
40
|
+
.restore(&plugin_config, Some(&columns_configs))?;
|
|
41
|
+
|
|
42
|
+
props.renderer().update(props.session().get_view()).await?;
|
|
43
|
+
let detail = serde_wasm_bindgen::to_value(&columns_configs).unwrap();
|
|
44
|
+
props
|
|
45
|
+
.custom_events()
|
|
46
|
+
.dispatch_column_style_changed(&detail)?;
|
|
47
|
+
|
|
48
|
+
Ok(())
|
|
49
|
+
})
|
|
53
50
|
}
|
|
54
51
|
}
|