@perspective-dev/viewer 4.2.0 → 4.4.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/botanical.css +1 -0
- package/dist/css/dracula.css +1 -1
- package/dist/css/gruvbox-dark.css +1 -1
- package/dist/css/gruvbox.css +1 -1
- package/dist/css/icons.css +1 -1
- package/dist/css/intl/de.css +1 -1
- package/dist/css/intl/es.css +1 -1
- package/dist/css/intl/fr.css +1 -1
- package/dist/css/intl/ja.css +1 -1
- package/dist/css/intl/pt.css +1 -1
- package/dist/css/intl/zh.css +1 -1
- package/dist/css/intl.css +1 -1
- package/dist/css/monokai.css +1 -1
- package/dist/css/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 +32 -1
- package/dist/esm/perspective-viewer.d.ts +1 -0
- 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/ts-rs/GroupRollupMode.d.ts +1 -0
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +2 -0
- package/dist/wasm/perspective-viewer.d.ts +57 -53
- package/dist/wasm/perspective-viewer.js +197 -164
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +17 -18
- package/package.json +9 -6
- package/src/{less/aggregate-selector.less → css/aggregate-selector.css} +23 -20
- package/src/css/column-dropdown.css +109 -0
- package/src/{less/column-selector.less → css/column-selector.css} +161 -159
- package/src/{less/column-settings-panel.less → css/column-settings-panel.css} +69 -59
- package/src/{less/column-style.less → css/column-style.css} +52 -66
- package/src/{less/column-symbol-attributes.less → css/column-symbol-attributes.css} +15 -14
- package/src/css/config-selector.css +441 -0
- package/src/{less/containers/dropdown-menu.less → css/containers/dropdown-menu.css} +20 -19
- package/src/{less/containers/pairs-list.less → css/containers/pairs-list.css} +13 -12
- package/src/{themes/variables.less → css/containers/scroll-panel.css} +25 -22
- package/src/{less/containers/split-panel.less → css/containers/split-panel.css} +15 -14
- package/src/{less/containers/tabs.less → css/containers/tabs.css} +17 -19
- package/src/css/dom/checkbox.css +102 -0
- package/src/css/dom/scrollbar.css +35 -0
- package/src/{less/dom/select.less → css/dom/select.css} +17 -18
- package/src/{less/empty-column.less → css/empty-column.css} +19 -18
- package/src/{less/expression-editor.less → css/expression-editor.css} +19 -18
- package/src/{less/filter-dropdown.less → css/filter-dropdown.css} +12 -11
- package/src/{less/filter-item.less → css/filter-item.css} +16 -15
- package/src/{less/form/code-editor.less → css/form/code-editor.css} +26 -30
- package/src/{less/form/debug.less → css/form/debug.css} +19 -18
- package/src/{less/function-dropdown.less → css/function-dropdown.css} +12 -11
- package/src/css/plugin-selector.css +261 -0
- package/src/{less/render-warning.less → css/render-warning.css} +18 -17
- package/src/{less/status-bar.less → css/status-bar.css} +156 -144
- package/src/css/type-icon.css +116 -0
- package/src/{less/viewer.less → css/viewer.css} +112 -146
- package/src/rust/components/column_dropdown.rs +229 -119
- package/src/rust/components/column_selector/active_column.rs +81 -62
- package/src/rust/components/column_selector/add_expression_button.rs +1 -0
- package/src/rust/components/column_selector/aggregate_selector.rs +25 -15
- package/src/rust/components/column_selector/config_selector.rs +374 -185
- package/src/rust/components/column_selector/empty_column.rs +2 -2
- package/src/rust/components/column_selector/expr_edit_button.rs +8 -2
- package/src/rust/components/column_selector/filter_column.rs +37 -26
- package/src/rust/components/column_selector/inactive_column.rs +41 -29
- package/src/rust/components/column_selector/invalid_column.rs +7 -18
- package/src/rust/components/column_selector/pivot_column.rs +21 -10
- package/src/rust/components/column_selector/sort_column.rs +23 -13
- package/src/rust/components/column_selector.rs +189 -100
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +3 -2
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +3 -2
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +2 -3
- package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +7 -1
- package/src/rust/components/column_settings_sidebar/style_tab.rs +153 -112
- package/src/rust/components/column_settings_sidebar.rs +91 -53
- package/src/rust/components/containers/dragdrop_list.rs +29 -7
- package/src/rust/components/containers/scroll_panel.rs +8 -1
- package/src/rust/components/containers/select.rs +3 -3
- package/src/rust/components/containers/sidebar_close_button.rs +1 -1
- package/src/rust/components/containers/split_panel.rs +3 -2
- package/src/rust/components/containers/tab_list.rs +1 -1
- package/src/rust/components/copy_dropdown.rs +7 -28
- package/src/rust/components/datetime_column_style/custom.rs +2 -2
- package/src/rust/components/datetime_column_style/simple.rs +2 -2
- package/src/rust/components/datetime_column_style.rs +4 -2
- package/src/rust/components/editable_header.rs +7 -4
- package/src/rust/components/empty_row.rs +1 -1
- package/src/rust/components/export_dropdown.rs +4 -30
- package/src/rust/components/expression_editor.rs +19 -10
- package/src/rust/components/filter_dropdown.rs +246 -102
- package/src/rust/components/font_loader.rs +11 -28
- package/src/rust/components/form/code_editor.rs +17 -2
- package/src/rust/components/form/color_range_selector.rs +19 -6
- package/src/rust/components/form/debug.rs +30 -13
- package/src/rust/components/function_dropdown.rs +186 -113
- package/src/rust/components/main_panel.rs +71 -89
- package/src/rust/components/mod.rs +1 -1
- package/src/rust/components/modal.rs +7 -1
- package/src/rust/components/number_column_style.rs +22 -7
- package/src/rust/components/plugin_selector.rs +34 -92
- package/src/rust/components/portal.rs +274 -0
- package/src/rust/components/render_warning.rs +72 -123
- package/src/rust/components/settings_panel.rs +115 -11
- package/src/rust/components/status_bar.rs +222 -98
- package/src/rust/components/status_bar_counter.rs +8 -20
- package/src/rust/components/status_indicator.rs +64 -111
- package/src/rust/components/string_column_style.rs +2 -2
- package/src/rust/components/style/style_cache.rs +5 -1
- package/src/rust/components/viewer.rs +391 -39
- package/src/rust/custom_elements/copy_dropdown.rs +102 -21
- package/src/rust/custom_elements/export_dropdown.rs +102 -20
- package/src/rust/custom_elements/mod.rs +0 -7
- package/src/rust/custom_elements/modal.rs +7 -103
- package/src/rust/custom_elements/viewer.rs +99 -35
- package/src/rust/custom_events.rs +23 -2
- package/src/rust/dragdrop.rs +149 -10
- package/src/{less/containers/scroll-panel.less → rust/engines.rs} +15 -13
- package/src/rust/js/plugin.rs +20 -1
- package/src/rust/lib.rs +5 -4
- package/src/rust/presentation/props.rs +39 -0
- package/src/rust/presentation/sheets.rs +3 -3
- package/src/rust/presentation.rs +44 -8
- package/src/rust/renderer/limits.rs +32 -3
- package/src/{less/dom/scrollbar.less → rust/renderer/props.rs} +18 -19
- package/src/rust/renderer/registry.rs +8 -1
- package/src/rust/renderer.rs +83 -9
- package/src/rust/session/column_defaults_update.rs +18 -0
- package/src/rust/session/metadata.rs +23 -2
- package/src/rust/session/props.rs +178 -0
- package/src/rust/session/replace_expression_update.rs +1 -0
- package/src/rust/session.rs +124 -117
- package/src/rust/tasks/column_locator.rs +133 -0
- package/src/rust/{model → tasks}/columns_iter_set.rs +14 -23
- package/src/rust/{model → tasks}/edit_expression.rs +34 -10
- package/src/rust/{model → tasks}/eject.rs +2 -2
- package/src/rust/{model → tasks}/get_viewer_config.rs +0 -11
- package/src/rust/{model → tasks}/intersection_observer.rs +22 -4
- package/src/{less/containers/radio-list.less → rust/tasks/is_invalid_drop.rs} +21 -14
- package/src/rust/tasks/mod.rs +52 -0
- package/src/rust/{model → tasks}/plugin_column_styles.rs +69 -46
- package/src/rust/{model → tasks}/resize_observer.rs +39 -6
- package/src/rust/{model → tasks}/send_plugin_config.rs +1 -1
- package/src/rust/tasks/structural.rs +53 -0
- package/src/rust/utils/mod.rs +4 -0
- package/src/rust/utils/modal_position.rs +110 -0
- package/src/rust/utils/ptr_eq_rc.rs +74 -0
- package/src/rust/utils/pubsub.rs +11 -1
- package/src/svg/bg-pattern.png +0 -0
- package/src/svg/close-icon.svg +1 -1
- package/src/svg/expression.svg +1 -1
- package/src/svg/mega-menu-icons-candlestick.svg +1 -1
- package/src/svg/mega-menu-icons-datagrid.svg +1 -2
- package/src/svg/mega-menu-icons-heatmap.svg +1 -1
- package/src/svg/mega-menu-icons-map-scatter.svg +1 -1
- package/src/svg/mega-menu-icons-ohlc.svg +1 -1
- package/src/svg/mega-menu-icons-sunburst.svg +1 -1
- package/src/svg/mega-menu-icons-treemap.svg +1 -1
- package/src/svg/mega-menu-icons-x-bar.svg +1 -1
- package/src/svg/mega-menu-icons-x-y-line.svg +1 -1
- package/src/svg/mega-menu-icons-x-y-scatter.svg +1 -1
- package/src/svg/mega-menu-icons-y-area.svg +1 -1
- package/src/svg/mega-menu-icons-y-bar.svg +1 -1
- package/src/svg/mega-menu-icons-y-line.svg +1 -1
- package/src/svg/mega-menu-icons-y-scatter.svg +1 -1
- package/src/svg/radio-hover.svg +1 -1
- package/src/svg/radio-off.svg +1 -1
- package/src/svg/radio-on.svg +1 -1
- package/src/themes/botanical.css +157 -0
- package/src/themes/defaults.css +139 -0
- package/src/themes/dracula.css +233 -0
- package/src/themes/gruvbox-dark.css +255 -0
- package/src/themes/gruvbox.css +134 -0
- package/src/themes/icons.css +124 -0
- package/src/themes/intl/de.css +102 -0
- package/src/themes/intl/es.css +102 -0
- package/src/themes/intl/fr.css +102 -0
- package/src/themes/intl/ja.css +102 -0
- package/src/themes/intl/pt.css +102 -0
- package/src/themes/intl/zh.css +102 -0
- package/src/themes/intl.css +102 -0
- package/src/themes/monokai.css +233 -0
- package/src/themes/pro-dark.css +158 -0
- package/src/themes/{themes.less → pro.css} +17 -20
- package/src/themes/solarized-dark.css +135 -0
- package/src/themes/solarized.css +95 -0
- package/src/themes/themes.css +22 -0
- package/src/themes/vaporwave.css +256 -0
- package/src/ts/extensions.ts +73 -2
- package/src/ts/perspective-viewer.ts +1 -0
- package/src/ts/ts-rs/GroupRollupMode.ts +3 -0
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +2 -1
- package/tsconfig.json +1 -0
- package/dist/css/variables.css +0 -0
- package/src/less/column-dropdown.less +0 -95
- package/src/less/config-selector.less +0 -363
- package/src/less/dom/checkbox.less +0 -100
- package/src/less/plugin-selector.less +0 -183
- package/src/less/type-icon.less +0 -68
- package/src/rust/components/error_message.rs +0 -56
- package/src/rust/custom_elements/column_dropdown.rs +0 -123
- package/src/rust/custom_elements/filter_dropdown.rs +0 -179
- package/src/rust/custom_elements/function_dropdown.rs +0 -115
- package/src/rust/model/column_locator.rs +0 -82
- package/src/rust/model/is_invalid_drop.rs +0 -36
- package/src/rust/model/mod.rs +0 -100
- package/src/rust/model/reset_all.rs +0 -38
- package/src/rust/model/structural.rs +0 -244
- package/src/themes/dracula.less +0 -101
- package/src/themes/gruvbox-dark.less +0 -116
- package/src/themes/gruvbox.less +0 -152
- package/src/themes/icons.less +0 -130
- package/src/themes/intl/de.less +0 -102
- package/src/themes/intl/es.less +0 -102
- package/src/themes/intl/fr.less +0 -102
- package/src/themes/intl/ja.less +0 -102
- package/src/themes/intl/pt.less +0 -102
- package/src/themes/intl/zh.less +0 -102
- package/src/themes/intl.less +0 -102
- package/src/themes/monokai.less +0 -107
- package/src/themes/pro-dark.less +0 -147
- package/src/themes/pro.less +0 -186
- package/src/themes/solarized-dark.less +0 -78
- package/src/themes/solarized.less +0 -102
- package/src/themes/vaporwave.less +0 -145
- /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-1586156e058be573 → perspective-viewer-68fef752754ffbc6}/inline4.js +0 -0
- /package/src/rust/{model → tasks}/copy_export.rs +0 -0
- /package/src/rust/{model → tasks}/export_app.rs +0 -0
- /package/src/rust/{model → tasks}/export_method.rs +0 -0
- /package/src/rust/{model → tasks}/restore_and_render.rs +0 -0
- /package/src/rust/{model → tasks}/update_and_render.rs +0 -0
|
@@ -27,7 +27,9 @@ use std::rc::Rc;
|
|
|
27
27
|
|
|
28
28
|
pub use empty_column::*;
|
|
29
29
|
pub use invalid_column::*;
|
|
30
|
+
use perspective_client::config::ViewConfig;
|
|
30
31
|
use perspective_js::utils::ApiFuture;
|
|
32
|
+
pub use pivot_column::*;
|
|
31
33
|
use web_sys::*;
|
|
32
34
|
use yew::prelude::*;
|
|
33
35
|
|
|
@@ -38,17 +40,20 @@ use self::inactive_column::*;
|
|
|
38
40
|
use super::containers::scroll_panel::*;
|
|
39
41
|
use super::containers::split_panel::{Orientation, SplitPanel};
|
|
40
42
|
use super::style::LocalStyle;
|
|
43
|
+
use crate::components::column_dropdown::{ColumnDropDownElement, ColumnDropDownPortal};
|
|
41
44
|
use crate::components::containers::scroll_panel_item::ScrollPanelItem;
|
|
42
|
-
use crate::
|
|
45
|
+
use crate::css;
|
|
43
46
|
use crate::dragdrop::*;
|
|
44
|
-
use crate::model::*;
|
|
45
47
|
use crate::presentation::ColumnLocator;
|
|
46
48
|
use crate::renderer::*;
|
|
49
|
+
use crate::session::drag_drop_update::*;
|
|
47
50
|
use crate::session::*;
|
|
51
|
+
use crate::tasks::{
|
|
52
|
+
ActiveColumnState, ActiveColumnStateData, ColumnsIteratorSet, can_render_column_styles,
|
|
53
|
+
};
|
|
48
54
|
use crate::utils::*;
|
|
49
|
-
use crate::*;
|
|
50
55
|
|
|
51
|
-
#[derive(Properties
|
|
56
|
+
#[derive(Properties)]
|
|
52
57
|
pub struct ColumnSelectorProps {
|
|
53
58
|
/// Fires when the expression/config column is open.
|
|
54
59
|
pub on_open_expr_panel: Callback<ColumnLocator>,
|
|
@@ -56,29 +61,48 @@ pub struct ColumnSelectorProps {
|
|
|
56
61
|
/// This is passed to the add_expression_button for styling.
|
|
57
62
|
pub selected_column: Option<ColumnLocator>,
|
|
58
63
|
|
|
59
|
-
///
|
|
60
|
-
|
|
61
|
-
pub
|
|
64
|
+
/// Value props threaded from root's `SessionProps` / `RendererProps`.
|
|
65
|
+
pub has_table: Option<TableLoadState>,
|
|
66
|
+
pub named_column_count: usize,
|
|
67
|
+
pub view_config: PtrEqRc<ViewConfig>,
|
|
68
|
+
pub drag_column: Option<String>,
|
|
69
|
+
|
|
70
|
+
/// Cloned session metadata snapshot — threaded from `SessionProps`
|
|
71
|
+
/// so that metadata changes trigger re-renders via prop diffing.
|
|
72
|
+
pub metadata: SessionMetadataRc,
|
|
73
|
+
|
|
74
|
+
/// Selected theme name, threaded for PortalModal consumers.
|
|
75
|
+
pub selected_theme: Option<String>,
|
|
62
76
|
|
|
63
77
|
// State
|
|
64
78
|
pub session: Session,
|
|
65
79
|
pub renderer: Renderer,
|
|
66
80
|
pub dragdrop: DragDrop,
|
|
81
|
+
|
|
82
|
+
/// Fires when this component is resized via the UI.
|
|
83
|
+
#[prop_or_default]
|
|
84
|
+
pub on_resize: Option<Rc<PubSub<()>>>,
|
|
67
85
|
}
|
|
68
86
|
|
|
69
87
|
impl PartialEq for ColumnSelectorProps {
|
|
70
88
|
fn eq(&self, rhs: &Self) -> bool {
|
|
71
89
|
self.selected_column == rhs.selected_column
|
|
90
|
+
&& self.has_table == rhs.has_table
|
|
91
|
+
&& self.named_column_count == rhs.named_column_count
|
|
92
|
+
&& self.view_config == rhs.view_config
|
|
93
|
+
&& self.drag_column == rhs.drag_column
|
|
94
|
+
&& self.metadata == rhs.metadata
|
|
95
|
+
&& self.selected_theme == rhs.selected_theme
|
|
72
96
|
}
|
|
73
97
|
}
|
|
74
98
|
|
|
75
99
|
#[derive(Debug)]
|
|
76
100
|
pub enum ColumnSelectorMsg {
|
|
77
|
-
|
|
78
|
-
|
|
101
|
+
/// Triggers a plain re-render; used as `onselect`/`ondragenter` callbacks
|
|
102
|
+
/// from `ConfigSelector` after it mutates the view config.
|
|
103
|
+
Redraw,
|
|
79
104
|
HoverActiveIndex(Option<usize>),
|
|
80
|
-
|
|
81
|
-
DragEnd,
|
|
105
|
+
SetWidth(f64),
|
|
82
106
|
Drop((String, DragTarget, DragEffect, usize)),
|
|
83
107
|
}
|
|
84
108
|
|
|
@@ -87,10 +111,10 @@ use ColumnSelectorMsg::*;
|
|
|
87
111
|
/// A `ColumnSelector` controls the `columns` field of the `ViewConfig`,
|
|
88
112
|
/// deriving its options from the table columns and `ViewConfig` expressions.
|
|
89
113
|
pub struct ColumnSelector {
|
|
90
|
-
_subscriptions: [Subscription;
|
|
91
|
-
named_row_count: usize,
|
|
114
|
+
_subscriptions: [Subscription; 1],
|
|
92
115
|
drag_container: DragDropContainer,
|
|
93
116
|
column_dropdown: ColumnDropDownElement,
|
|
117
|
+
viewport_width: f64,
|
|
94
118
|
on_reset: Rc<PubSub<()>>,
|
|
95
119
|
}
|
|
96
120
|
|
|
@@ -100,44 +124,14 @@ impl Component for ColumnSelector {
|
|
|
100
124
|
|
|
101
125
|
fn create(ctx: &Context<Self>) -> Self {
|
|
102
126
|
let ColumnSelectorProps {
|
|
103
|
-
dragdrop,
|
|
104
|
-
renderer,
|
|
105
|
-
session,
|
|
106
|
-
..
|
|
127
|
+
dragdrop, session, ..
|
|
107
128
|
} = ctx.props();
|
|
108
|
-
let table_sub = {
|
|
109
|
-
let cb = ctx.link().callback(|_| ColumnSelectorMsg::TableLoaded);
|
|
110
|
-
session.table_loaded.add_listener(cb)
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
let view_sub = {
|
|
114
|
-
let cb = ctx.link().callback(|_| ColumnSelectorMsg::ViewCreated);
|
|
115
|
-
session.view_created.add_listener(cb)
|
|
116
|
-
};
|
|
117
129
|
|
|
118
130
|
let drop_sub = {
|
|
119
131
|
let cb = ctx.link().callback(ColumnSelectorMsg::Drop);
|
|
120
132
|
dragdrop.drop_received.add_listener(cb)
|
|
121
133
|
};
|
|
122
134
|
|
|
123
|
-
let drag_sub = {
|
|
124
|
-
let cb = ctx.link().callback(ColumnSelectorMsg::Drag);
|
|
125
|
-
dragdrop.dragstart_received.add_listener(cb)
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
let dragend_sub = {
|
|
129
|
-
let cb = ctx.link().callback(|_| ColumnSelectorMsg::DragEnd);
|
|
130
|
-
dragdrop.dragend_received.add_listener(cb)
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
let named = maybe! {
|
|
134
|
-
let plugin =
|
|
135
|
-
renderer.get_active_plugin().ok()?;
|
|
136
|
-
|
|
137
|
-
Some(plugin.config_column_names()?.length() as usize)
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
let named_row_count = named.unwrap_or_default();
|
|
141
135
|
let drag_container = DragDropContainer::new(|| {}, {
|
|
142
136
|
let link = ctx.link().clone();
|
|
143
137
|
move || link.send_message(ColumnSelectorMsg::HoverActiveIndex(None))
|
|
@@ -145,8 +139,8 @@ impl Component for ColumnSelector {
|
|
|
145
139
|
|
|
146
140
|
let column_dropdown = ColumnDropDownElement::new(session.clone());
|
|
147
141
|
Self {
|
|
148
|
-
_subscriptions: [
|
|
149
|
-
|
|
142
|
+
_subscriptions: [drop_sub],
|
|
143
|
+
viewport_width: 0f64,
|
|
150
144
|
drag_container,
|
|
151
145
|
column_dropdown,
|
|
152
146
|
on_reset: Default::default(),
|
|
@@ -155,18 +149,10 @@ impl Component for ColumnSelector {
|
|
|
155
149
|
|
|
156
150
|
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
157
151
|
match msg {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
let plugin =
|
|
163
|
-
ctx.props().renderer.get_active_plugin().ok()?;
|
|
164
|
-
|
|
165
|
-
Some(plugin.config_column_names()?.length() as usize)
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
self.named_row_count = named.unwrap_or_default();
|
|
169
|
-
true
|
|
152
|
+
Redraw => true,
|
|
153
|
+
SetWidth(w) => {
|
|
154
|
+
self.viewport_width = w;
|
|
155
|
+
false
|
|
170
156
|
},
|
|
171
157
|
HoverActiveIndex(Some(to_index)) => ctx
|
|
172
158
|
.props()
|
|
@@ -177,33 +163,77 @@ impl Component for ColumnSelector {
|
|
|
177
163
|
true
|
|
178
164
|
},
|
|
179
165
|
Drop((column, DragTarget::Active, DragEffect::Move(DragTarget::Active), index)) => {
|
|
180
|
-
|
|
181
|
-
let
|
|
166
|
+
let is_invalid = {
|
|
167
|
+
let config = &ctx.props().view_config;
|
|
168
|
+
let from_index = config
|
|
169
|
+
.columns
|
|
170
|
+
.iter()
|
|
171
|
+
.position(|x| x.as_ref() == Some(&column));
|
|
172
|
+
|
|
173
|
+
let min_cols = ctx.props().renderer.metadata().min;
|
|
174
|
+
let is_to_empty = !config
|
|
175
|
+
.columns
|
|
176
|
+
.get(index)
|
|
177
|
+
.map(|x| x.is_some())
|
|
178
|
+
.unwrap_or_default();
|
|
179
|
+
|
|
180
|
+
min_cols
|
|
181
|
+
.and_then(|x| from_index.map(|fi| fi < x))
|
|
182
|
+
.unwrap_or_default()
|
|
183
|
+
&& is_to_empty
|
|
184
|
+
};
|
|
185
|
+
if !is_invalid {
|
|
186
|
+
let col_type = ctx
|
|
187
|
+
.props()
|
|
188
|
+
.metadata
|
|
189
|
+
.get_column_table_type(column.as_str())
|
|
190
|
+
.unwrap();
|
|
191
|
+
|
|
192
|
+
let update = ctx.props().view_config.create_drag_drop_update(
|
|
182
193
|
column,
|
|
194
|
+
col_type,
|
|
183
195
|
index,
|
|
184
196
|
DragTarget::Active,
|
|
185
197
|
DragEffect::Move(DragTarget::Active),
|
|
186
198
|
&ctx.props().renderer.metadata(),
|
|
199
|
+
ctx.props().metadata.get_features().unwrap(),
|
|
187
200
|
);
|
|
188
201
|
|
|
189
|
-
|
|
190
|
-
|
|
202
|
+
let session = ctx.props().session.clone();
|
|
203
|
+
let renderer = ctx.props().renderer.clone();
|
|
204
|
+
if session.update_view_config(update).is_ok() {
|
|
205
|
+
ApiFuture::spawn(async move {
|
|
206
|
+
renderer.apply_pending_plugin()?;
|
|
207
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
208
|
+
});
|
|
191
209
|
}
|
|
192
210
|
}
|
|
193
211
|
|
|
194
212
|
true
|
|
195
213
|
},
|
|
196
214
|
Drop((column, DragTarget::Active, effect, index)) => {
|
|
197
|
-
let
|
|
215
|
+
let col_type = ctx
|
|
216
|
+
.props()
|
|
217
|
+
.metadata
|
|
218
|
+
.get_column_table_type(column.as_str())
|
|
219
|
+
.unwrap();
|
|
220
|
+
let update = ctx.props().view_config.create_drag_drop_update(
|
|
198
221
|
column,
|
|
222
|
+
col_type,
|
|
199
223
|
index,
|
|
200
224
|
DragTarget::Active,
|
|
201
225
|
effect,
|
|
202
226
|
&ctx.props().renderer.metadata(),
|
|
227
|
+
ctx.props().metadata.get_features().unwrap(),
|
|
203
228
|
);
|
|
204
229
|
|
|
205
|
-
|
|
206
|
-
|
|
230
|
+
let session = ctx.props().session.clone();
|
|
231
|
+
let renderer = ctx.props().renderer.clone();
|
|
232
|
+
if session.update_view_config(update).is_ok() {
|
|
233
|
+
ApiFuture::spawn(async move {
|
|
234
|
+
renderer.apply_pending_plugin()?;
|
|
235
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
236
|
+
});
|
|
207
237
|
}
|
|
208
238
|
|
|
209
239
|
true
|
|
@@ -220,10 +250,29 @@ impl Component for ColumnSelector {
|
|
|
220
250
|
dragdrop,
|
|
221
251
|
..
|
|
222
252
|
} = ctx.props();
|
|
223
|
-
let
|
|
253
|
+
let metadata = &ctx.props().metadata;
|
|
254
|
+
|
|
255
|
+
// When `config.columns` is empty but the table has columns (transient
|
|
256
|
+
// state during `load()` after `reset()` clears the config), fill in
|
|
257
|
+
// all table columns as active — matching `validate_view_config()`.
|
|
258
|
+
let prop_config = &ctx.props().view_config;
|
|
259
|
+
let config = if prop_config.columns.is_empty() {
|
|
260
|
+
if let Some(table_cols) = metadata.get_table_columns() {
|
|
261
|
+
ViewConfig {
|
|
262
|
+
columns: table_cols.iter().map(|c| Some(c.clone())).collect(),
|
|
263
|
+
..(**prop_config).clone()
|
|
264
|
+
}
|
|
265
|
+
.into()
|
|
266
|
+
} else {
|
|
267
|
+
prop_config.clone()
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
prop_config.clone()
|
|
271
|
+
};
|
|
272
|
+
|
|
224
273
|
let is_aggregated = config.is_aggregated();
|
|
225
|
-
let columns_iter =
|
|
226
|
-
let onselect = ctx.link().callback(|()|
|
|
274
|
+
let columns_iter = ColumnsIteratorSet::new(&config, metadata, renderer, dragdrop);
|
|
275
|
+
let onselect = ctx.link().callback(|()| Redraw);
|
|
227
276
|
let ondragenter = ctx.link().callback(HoverActiveIndex);
|
|
228
277
|
let ondragover = Callback::from(|_event: DragEvent| _event.prevent_default());
|
|
229
278
|
let ondrop = Callback::from({
|
|
@@ -236,8 +285,8 @@ impl Component for ColumnSelector {
|
|
|
236
285
|
move |_| dragdrop.notify_drag_end()
|
|
237
286
|
});
|
|
238
287
|
|
|
239
|
-
let mut active_classes = classes!();
|
|
240
|
-
if ctx.props().
|
|
288
|
+
let mut active_classes = classes!("scrollable");
|
|
289
|
+
if ctx.props().drag_column.is_some() {
|
|
241
290
|
active_classes.push("dragdrop-highlight");
|
|
242
291
|
};
|
|
243
292
|
|
|
@@ -250,8 +299,7 @@ impl Component for ColumnSelector {
|
|
|
250
299
|
+ config.split_by.len()
|
|
251
300
|
+ config.filter.len()
|
|
252
301
|
+ config.sort.len()) as f64,
|
|
253
|
-
|
|
254
|
-
.metadata()
|
|
302
|
+
metadata
|
|
255
303
|
.get_features()
|
|
256
304
|
.map(|x| {
|
|
257
305
|
let mut y = 0.0;
|
|
@@ -280,7 +328,11 @@ impl Component for ColumnSelector {
|
|
|
280
328
|
<ScrollPanelItem key="config_selector" {size_hint}>
|
|
281
329
|
<ConfigSelector
|
|
282
330
|
onselect={onselect.clone()}
|
|
283
|
-
ondragenter={ctx.link().callback(|()|
|
|
331
|
+
ondragenter={ctx.link().callback(|()| Redraw)}
|
|
332
|
+
view_config={ctx.props().view_config.clone()}
|
|
333
|
+
drag_column={ctx.props().drag_column.clone()}
|
|
334
|
+
metadata={metadata.clone()}
|
|
335
|
+
selected_theme={ctx.props().selected_theme.clone()}
|
|
284
336
|
{dragdrop}
|
|
285
337
|
{renderer}
|
|
286
338
|
{session}
|
|
@@ -288,11 +340,11 @@ impl Component for ColumnSelector {
|
|
|
288
340
|
</ScrollPanelItem>
|
|
289
341
|
};
|
|
290
342
|
|
|
291
|
-
let mut named_count =
|
|
343
|
+
let mut named_count = ctx.props().named_column_count;
|
|
292
344
|
let mut active_columns: Vec<_> = columns_iter
|
|
293
345
|
.active()
|
|
294
346
|
.enumerate()
|
|
295
|
-
.map(|(idx, name)| {
|
|
347
|
+
.map(|(idx, name): (usize, ActiveColumnState)| {
|
|
296
348
|
let ondragenter = ondragenter.reform(move |_| Some(idx));
|
|
297
349
|
let size_hint = if named_count > 0 { 50.0 } else { 28.0 };
|
|
298
350
|
named_count = named_count.saturating_sub(1);
|
|
@@ -307,6 +359,34 @@ impl Component for ColumnSelector {
|
|
|
307
359
|
Some(ColumnLocator::Table(x)) | Some(ColumnLocator::Expression(x))
|
|
308
360
|
if x == &key );
|
|
309
361
|
|
|
362
|
+
// Compute metadata-derived props here so that changes to
|
|
363
|
+
// session metadata propagate via prop diffing.
|
|
364
|
+
// For DragOver placeholders, resolve the type from the
|
|
365
|
+
// dragged column (since `get_name()` returns `None`).
|
|
366
|
+
let col_type = name
|
|
367
|
+
.get_name()
|
|
368
|
+
.and_then(|n| metadata.get_column_table_type(n))
|
|
369
|
+
.or_else(|| {
|
|
370
|
+
if matches!(name.state, ActiveColumnStateData::DragOver) {
|
|
371
|
+
dragdrop
|
|
372
|
+
.get_drag_column()
|
|
373
|
+
.and_then(|c| metadata.get_column_table_type(&c))
|
|
374
|
+
} else {
|
|
375
|
+
None
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
let is_expression = name
|
|
380
|
+
.get_name()
|
|
381
|
+
.map(|n| metadata.is_column_expression(n))
|
|
382
|
+
.unwrap_or(false);
|
|
383
|
+
|
|
384
|
+
let can_render_styles = name
|
|
385
|
+
.get_name()
|
|
386
|
+
.and_then(|n| can_render_column_styles(renderer, &config, metadata, n).ok())
|
|
387
|
+
.unwrap_or(false);
|
|
388
|
+
|
|
389
|
+
let show_edit_btn = is_expression || can_render_styles;
|
|
310
390
|
let on_open_expr_panel = &ctx.props().on_open_expr_panel;
|
|
311
391
|
html_nested! {
|
|
312
392
|
<ScrollPanelItem {key} {size_hint}>
|
|
@@ -315,6 +395,11 @@ impl Component for ColumnSelector {
|
|
|
315
395
|
{idx}
|
|
316
396
|
{is_aggregated}
|
|
317
397
|
{is_editing}
|
|
398
|
+
{is_expression}
|
|
399
|
+
{show_edit_btn}
|
|
400
|
+
{col_type}
|
|
401
|
+
view_config={config.clone()}
|
|
402
|
+
metadata={metadata.clone()}
|
|
318
403
|
{name}
|
|
319
404
|
{on_open_expr_panel}
|
|
320
405
|
{ondragenter}
|
|
@@ -336,6 +421,7 @@ impl Component for ColumnSelector {
|
|
|
336
421
|
.map(|(idx, vc)| {
|
|
337
422
|
let selected_column = ctx.props().selected_column.as_ref();
|
|
338
423
|
let is_editing = matches!(selected_column, Some(ColumnLocator::Expression(x)) if x.as_str() == vc.name);
|
|
424
|
+
let is_expression = metadata.is_column_expression(vc.name);
|
|
339
425
|
html_nested! {
|
|
340
426
|
<ScrollPanelItem key={vc.name} size_hint=28.0>
|
|
341
427
|
<InactiveColumn
|
|
@@ -343,6 +429,9 @@ impl Component for ColumnSelector {
|
|
|
343
429
|
visible={vc.is_visible}
|
|
344
430
|
name={vc.name.to_owned()}
|
|
345
431
|
{is_editing}
|
|
432
|
+
{is_expression}
|
|
433
|
+
view_config={config.clone()}
|
|
434
|
+
metadata={metadata.clone()}
|
|
346
435
|
onselect={&onselect}
|
|
347
436
|
ondragend={&ondragend}
|
|
348
437
|
on_open_expr_panel={&ctx.props().on_open_expr_panel}
|
|
@@ -355,20 +444,9 @@ impl Component for ColumnSelector {
|
|
|
355
444
|
})
|
|
356
445
|
.collect();
|
|
357
446
|
|
|
358
|
-
let size =
|
|
359
|
-
56.0
|
|
360
|
-
} else {
|
|
361
|
-
28.0
|
|
362
|
-
};
|
|
447
|
+
let size = 28.0;
|
|
363
448
|
|
|
364
|
-
let add_column = if
|
|
365
|
-
.props()
|
|
366
|
-
.session
|
|
367
|
-
.metadata()
|
|
368
|
-
.get_features()
|
|
369
|
-
.unwrap()
|
|
370
|
-
.expressions
|
|
371
|
-
{
|
|
449
|
+
let add_column = if metadata.get_features().unwrap().expressions {
|
|
372
450
|
html_nested! {
|
|
373
451
|
<ScrollPanelItem key="__add_expression__" size_hint={size}>
|
|
374
452
|
<AddExpressionButton
|
|
@@ -389,8 +467,8 @@ impl Component for ColumnSelector {
|
|
|
389
467
|
inactive_children.insert(0, add_column);
|
|
390
468
|
}
|
|
391
469
|
|
|
392
|
-
let selected_columns = html! {
|
|
393
|
-
<div id="selected-columns">
|
|
470
|
+
let mut selected_columns = vec![html! {
|
|
471
|
+
<div id="selected-columns" key="__active_columns__">
|
|
394
472
|
<ScrollPanel
|
|
395
473
|
id="active-columns"
|
|
396
474
|
class={active_classes}
|
|
@@ -398,13 +476,28 @@ impl Component for ColumnSelector {
|
|
|
398
476
|
dragenter={&self.drag_container.dragenter}
|
|
399
477
|
dragleave={&self.drag_container.dragleave}
|
|
400
478
|
viewport_ref={&self.drag_container.noderef}
|
|
479
|
+
initial_width={self.viewport_width}
|
|
480
|
+
on_auto_width={ctx.link().callback(ColumnSelectorMsg::SetWidth)}
|
|
401
481
|
drop={ondrop}
|
|
402
482
|
on_resize={&ctx.props().on_resize}
|
|
403
483
|
on_dimensions_reset={&self.on_reset}
|
|
404
484
|
children={std::iter::once(config_selector).chain(active_columns).collect::<Vec<_>>()}
|
|
405
485
|
/>
|
|
406
486
|
</div>
|
|
407
|
-
};
|
|
487
|
+
}];
|
|
488
|
+
|
|
489
|
+
if !inactive_children.is_empty() {
|
|
490
|
+
selected_columns.push(html! {
|
|
491
|
+
<ScrollPanel
|
|
492
|
+
id="sub-columns"
|
|
493
|
+
key="__sub_columns__"
|
|
494
|
+
class={classes!("scrollable")}
|
|
495
|
+
on_resize={&ctx.props().on_resize}
|
|
496
|
+
on_dimensions_reset={&self.on_reset}
|
|
497
|
+
children={inactive_children}
|
|
498
|
+
/>
|
|
499
|
+
})
|
|
500
|
+
}
|
|
408
501
|
|
|
409
502
|
html! {
|
|
410
503
|
<>
|
|
@@ -415,16 +508,12 @@ impl Component for ColumnSelector {
|
|
|
415
508
|
skip_empty=true
|
|
416
509
|
orientation={Orientation::Vertical}
|
|
417
510
|
>
|
|
418
|
-
{ selected_columns }
|
|
419
|
-
if !inactive_children.is_empty() {
|
|
420
|
-
<ScrollPanel
|
|
421
|
-
id="sub-columns"
|
|
422
|
-
on_resize={&ctx.props().on_resize}
|
|
423
|
-
on_dimensions_reset={&self.on_reset}
|
|
424
|
-
children={inactive_children}
|
|
425
|
-
/>
|
|
426
|
-
}
|
|
511
|
+
{ for selected_columns }
|
|
427
512
|
</SplitPanel>
|
|
513
|
+
<ColumnDropDownPortal
|
|
514
|
+
element={self.column_dropdown.clone()}
|
|
515
|
+
theme={ctx.props().selected_theme.clone().unwrap_or_default()}
|
|
516
|
+
/>
|
|
428
517
|
</>
|
|
429
518
|
}
|
|
430
519
|
}
|
|
@@ -18,8 +18,8 @@ use perspective_client::clone;
|
|
|
18
18
|
use yew::{Html, Properties, function_component, html};
|
|
19
19
|
|
|
20
20
|
use crate::components::empty_row::EmptyRow;
|
|
21
|
+
use crate::components::filter_dropdown::FilterDropDownElement;
|
|
21
22
|
use crate::config::SymbolKVPair;
|
|
22
|
-
use crate::custom_elements::FilterDropDownElement;
|
|
23
23
|
|
|
24
24
|
#[derive(Properties, PartialEq)]
|
|
25
25
|
pub struct RowSelectorProps {
|
|
@@ -16,10 +16,11 @@ use itertools::Itertools;
|
|
|
16
16
|
use yew::{Callback, Html, Properties, html};
|
|
17
17
|
|
|
18
18
|
use crate::components::column_settings_sidebar::style_tab::symbol::symbol_pairs_item::PairsListItem;
|
|
19
|
+
use crate::components::filter_dropdown::FilterDropDownElement;
|
|
19
20
|
use crate::components::style::LocalStyle;
|
|
20
21
|
use crate::config::SymbolKVPair;
|
|
21
22
|
use crate::css;
|
|
22
|
-
use crate::
|
|
23
|
+
use crate::utils::PtrEqRc;
|
|
23
24
|
|
|
24
25
|
#[derive(Properties, PartialEq)]
|
|
25
26
|
pub struct PairsListProps {
|
|
@@ -28,7 +29,7 @@ pub struct PairsListProps {
|
|
|
28
29
|
pub update_pairs: Callback<Vec<SymbolKVPair>>,
|
|
29
30
|
pub id: Option<String>,
|
|
30
31
|
pub row_dropdown: Rc<FilterDropDownElement>,
|
|
31
|
-
pub values:
|
|
32
|
+
pub values: PtrEqRc<Vec<String>>,
|
|
32
33
|
pub column_name: String,
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -16,8 +16,9 @@ use yew::{Callback, Html, Properties, html};
|
|
|
16
16
|
|
|
17
17
|
use crate::components::column_settings_sidebar::style_tab::symbol::row_selector::RowSelector;
|
|
18
18
|
use crate::components::column_settings_sidebar::style_tab::symbol::symbol_selector::SymbolSelector;
|
|
19
|
+
use crate::components::filter_dropdown::FilterDropDownElement;
|
|
19
20
|
use crate::config::SymbolKVPair;
|
|
20
|
-
use crate::
|
|
21
|
+
use crate::utils::PtrEqRc;
|
|
21
22
|
|
|
22
23
|
#[derive(Properties, PartialEq)]
|
|
23
24
|
pub struct PairsListItemProps {
|
|
@@ -26,7 +27,7 @@ pub struct PairsListItemProps {
|
|
|
26
27
|
pub pairs: Vec<SymbolKVPair>,
|
|
27
28
|
pub update_pairs: Callback<Vec<SymbolKVPair>>,
|
|
28
29
|
pub row_dropdown: Rc<FilterDropDownElement>,
|
|
29
|
-
pub values:
|
|
30
|
+
pub values: PtrEqRc<Vec<String>>,
|
|
30
31
|
pub focused: bool,
|
|
31
32
|
pub set_focused_index: Callback<Option<usize>>,
|
|
32
33
|
pub column_name: String,
|
|
@@ -10,18 +10,17 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
use std::rc::Rc;
|
|
14
|
-
|
|
15
13
|
use itertools::Itertools;
|
|
16
14
|
use yew::{Callback, Html, Properties, function_component, html};
|
|
17
15
|
|
|
18
16
|
use crate::components::containers::select::{Select, SelectItem};
|
|
17
|
+
use crate::utils::PtrEqRc;
|
|
19
18
|
|
|
20
19
|
#[derive(Properties, PartialEq)]
|
|
21
20
|
pub struct SymbolSelectorProps {
|
|
22
21
|
pub index: usize,
|
|
23
22
|
pub selected_value: Option<String>,
|
|
24
|
-
pub values:
|
|
23
|
+
pub values: PtrEqRc<Vec<String>>,
|
|
25
24
|
pub callback: Callback<String>,
|
|
26
25
|
}
|
|
27
26
|
|
|
@@ -23,10 +23,10 @@ use itertools::Itertools;
|
|
|
23
23
|
use yew::{Callback, Html, Properties, html};
|
|
24
24
|
|
|
25
25
|
use crate::components::column_settings_sidebar::style_tab::symbol::symbol_pairs::PairsList;
|
|
26
|
+
use crate::components::filter_dropdown::{FilterDropDownElement, FilterDropDownPortal};
|
|
26
27
|
use crate::components::style::LocalStyle;
|
|
27
28
|
use crate::config::{ColumnConfigValueUpdate, KeyValueOpts, SymbolKVPair};
|
|
28
29
|
use crate::css;
|
|
29
|
-
use crate::custom_elements::FilterDropDownElement;
|
|
30
30
|
use crate::session::Session;
|
|
31
31
|
|
|
32
32
|
#[derive(Properties, PartialEq, Clone)]
|
|
@@ -36,6 +36,8 @@ pub struct SymbolAttrProps {
|
|
|
36
36
|
pub restored_config: Option<HashMap<String, String>>,
|
|
37
37
|
pub on_change: Callback<ColumnConfigValueUpdate>,
|
|
38
38
|
pub default_config: KeyValueOpts,
|
|
39
|
+
/// Selected theme name, threaded for PortalModal consumers.
|
|
40
|
+
pub selected_theme: Option<String>,
|
|
39
41
|
}
|
|
40
42
|
impl SymbolAttrProps {
|
|
41
43
|
pub fn next_default_symbol(&self, pairs_len: usize) -> String {
|
|
@@ -125,6 +127,10 @@ impl yew::Component for SymbolStyle {
|
|
|
125
127
|
values={Rc::new(ctx.props().default_config.values.clone())}
|
|
126
128
|
{update_pairs}
|
|
127
129
|
/>
|
|
130
|
+
<FilterDropDownPortal
|
|
131
|
+
element={(*self.row_dropdown).clone()}
|
|
132
|
+
theme={ctx.props().selected_theme.clone().unwrap_or_default()}
|
|
133
|
+
/>
|
|
128
134
|
</>
|
|
129
135
|
}
|
|
130
136
|
}
|