@perspective-dev/viewer 4.3.0 → 4.4.1
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 -1
- package/dist/css/dracula.css +1 -1
- package/dist/css/gruvbox-dark.css +1 -1
- package/dist/css/gruvbox.css +1 -1
- package/dist/css/icons.css +1 -1
- package/dist/css/intl/de.css +1 -1
- package/dist/css/intl/es.css +1 -1
- package/dist/css/intl/fr.css +1 -1
- package/dist/css/intl/ja.css +1 -1
- package/dist/css/intl/pt.css +1 -1
- package/dist/css/intl/zh.css +1 -1
- package/dist/css/intl.css +1 -1
- package/dist/css/monokai.css +1 -1
- package/dist/css/phosphor.css +1 -0
- package/dist/css/pro-dark.css +1 -1
- package/dist/css/pro.css +1 -1
- package/dist/css/solarized-dark.css +1 -1
- package/dist/css/solarized.css +1 -1
- package/dist/css/themes.css +1 -1
- package/dist/css/vaporwave.css +1 -1
- package/dist/esm/extensions.d.ts +4 -0
- 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/plugin.d.ts +9 -9
- package/dist/esm/ts-rs/NumberForegroundMode.d.ts +1 -1
- package/dist/esm/ts-rs/ViewerConfig.d.ts +36 -0
- package/dist/wasm/perspective-viewer.d.ts +68 -59
- package/dist/wasm/perspective-viewer.js +216 -171
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +19 -20
- package/package.json +7 -5
- 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} +160 -158
- package/src/{less/column-settings-panel.less → css/column-settings-panel.css} +70 -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/{less/config-selector.less → css/config-selector.css} +151 -135
- 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} +157 -145
- 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 +315 -199
- 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 +11 -5
- package/src/rust/components/column_selector/sort_column.rs +23 -13
- package/src/rust/components/column_selector.rs +163 -84
- 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 +2 -1
- package/src/rust/components/containers/sidebar_close_button.rs +1 -1
- package/src/rust/components/containers/split_panel.rs +1 -0
- 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 +30 -7
- package/src/rust/components/plugin_selector.rs +34 -102
- 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 -114
- 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 -40
- package/src/rust/config/number_column_style.rs +5 -1
- package/src/rust/config/viewer_config.rs +2 -2
- package/src/rust/custom_elements/copy_dropdown.rs +102 -21
- package/src/rust/custom_elements/debug_plugin.rs +4 -4
- 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 +114 -39
- 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 +1 -1
- package/src/rust/lib.rs +10 -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.rs +93 -14
- package/src/rust/session/column_defaults_update.rs +1 -1
- package/src/rust/session/metadata.rs +23 -2
- package/src/rust/session/props.rs +178 -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 +19 -3
- 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}/restore_and_render.rs +4 -3
- 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/datagrid-select-row-tree.svg +13 -0
- 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 +157 -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 +107 -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/phosphor.css +184 -0
- package/src/themes/pro-dark.css +158 -0
- package/src/themes/{themes.less → pro.css} +17 -21
- package/src/themes/solarized-dark.css +135 -0
- package/src/themes/solarized.css +95 -0
- package/src/themes/themes.css +23 -0
- package/src/themes/vaporwave.css +256 -0
- package/src/ts/extensions.ts +8 -1
- package/src/ts/perspective-viewer.ts +1 -0
- package/src/ts/plugin.ts +9 -9
- package/src/ts/ts-rs/NumberForegroundMode.ts +1 -1
- package/src/ts/ts-rs/ViewerConfig.ts +15 -0
- package/dist/css/variables.css +0 -0
- package/src/less/column-dropdown.less +0 -95
- 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/botanical.less +0 -142
- 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-d729f682ba5c19df → perspective-viewer-d924246f0b4a3dce}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → perspective-viewer-d924246f0b4a3dce}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → perspective-viewer-d924246f0b4a3dce}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → perspective-viewer-d924246f0b4a3dce}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → perspective-viewer-d924246f0b4a3dce}/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}/update_and_render.rs +0 -0
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
use std::collections::HashSet;
|
|
14
14
|
use std::rc::Rc;
|
|
15
15
|
|
|
16
|
-
use perspective_client::config
|
|
17
|
-
use perspective_client::utils::PerspectiveResultExt;
|
|
16
|
+
use perspective_client::config::{ViewConfig, *};
|
|
18
17
|
use perspective_js::utils::ApiFuture;
|
|
19
18
|
use yew::prelude::*;
|
|
20
19
|
|
|
@@ -22,24 +21,38 @@ use super::InPlaceColumn;
|
|
|
22
21
|
use super::filter_column::*;
|
|
23
22
|
use super::pivot_column::*;
|
|
24
23
|
use super::sort_column::*;
|
|
24
|
+
use crate::components::column_dropdown::{ColumnDropDownElement, ColumnDropDownPortal};
|
|
25
25
|
use crate::components::containers::dragdrop_list::*;
|
|
26
26
|
use crate::components::containers::select::{Select, SelectItem};
|
|
27
|
+
use crate::components::filter_dropdown::{FilterDropDownElement, FilterDropDownPortal};
|
|
27
28
|
use crate::components::style::LocalStyle;
|
|
28
|
-
use crate::
|
|
29
|
+
use crate::css;
|
|
29
30
|
use crate::dragdrop::*;
|
|
30
|
-
use crate::model::*;
|
|
31
31
|
use crate::renderer::*;
|
|
32
|
+
use crate::session::drag_drop_update::*;
|
|
32
33
|
use crate::session::*;
|
|
33
34
|
use crate::utils::*;
|
|
34
|
-
use crate::{PerspectiveProperties, css};
|
|
35
35
|
|
|
36
|
-
#[derive(Clone, Properties
|
|
36
|
+
#[derive(Clone, Properties)]
|
|
37
37
|
pub struct ConfigSelectorProps {
|
|
38
38
|
pub onselect: Callback<()>,
|
|
39
39
|
|
|
40
40
|
#[prop_or_default]
|
|
41
41
|
pub ondragenter: Callback<()>,
|
|
42
42
|
|
|
43
|
+
/// Current view config threaded as a value prop so that config changes
|
|
44
|
+
/// (group_by, sort, filter, etc.) trigger re-renders via normal prop
|
|
45
|
+
/// diffing rather than a PubSub `view_created` subscription.
|
|
46
|
+
pub view_config: PtrEqRc<ViewConfig>,
|
|
47
|
+
/// Column currently being dragged — threaded to show `dragdrop-highlight`
|
|
48
|
+
/// without subscribing to `dragstart_received`/`dragend_received`.
|
|
49
|
+
pub drag_column: Option<String>,
|
|
50
|
+
/// Session metadata snapshot — threaded from `SessionProps`.
|
|
51
|
+
pub metadata: SessionMetadataRc,
|
|
52
|
+
|
|
53
|
+
/// Selected theme name, threaded for PortalModal consumers.
|
|
54
|
+
pub selected_theme: Option<String>,
|
|
55
|
+
|
|
43
56
|
// State
|
|
44
57
|
pub session: Session,
|
|
45
58
|
pub renderer: Renderer,
|
|
@@ -47,22 +60,22 @@ pub struct ConfigSelectorProps {
|
|
|
47
60
|
}
|
|
48
61
|
|
|
49
62
|
impl PartialEq for ConfigSelectorProps {
|
|
50
|
-
fn eq(&self,
|
|
51
|
-
|
|
63
|
+
fn eq(&self, other: &Self) -> bool {
|
|
64
|
+
self.view_config == other.view_config
|
|
65
|
+
&& self.drag_column == other.drag_column
|
|
66
|
+
&& self.metadata == other.metadata
|
|
67
|
+
&& self.selected_theme == other.selected_theme
|
|
52
68
|
}
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
#[derive(Debug)]
|
|
56
72
|
pub enum ConfigSelectorMsg {
|
|
57
|
-
DragStart,
|
|
58
|
-
DragEnd,
|
|
59
73
|
DragOver(usize, DragTarget),
|
|
60
74
|
DragLeave(DragTarget),
|
|
61
75
|
Drop(String, DragTarget, DragEffect, usize),
|
|
62
76
|
Close(usize, DragTarget),
|
|
63
77
|
SetFilterValue(usize, String),
|
|
64
78
|
TransposePivots,
|
|
65
|
-
ViewCreated,
|
|
66
79
|
New(DragTarget, InPlaceColumn),
|
|
67
80
|
UpdateGroupRollupMode(GroupRollupMode),
|
|
68
81
|
}
|
|
@@ -71,7 +84,7 @@ pub enum ConfigSelectorMsg {
|
|
|
71
84
|
pub struct ConfigSelector {
|
|
72
85
|
filter_dropdown: FilterDropDownElement,
|
|
73
86
|
column_dropdown: ColumnDropDownElement,
|
|
74
|
-
_subscriptions: [Rc<Subscription>;
|
|
87
|
+
_subscriptions: [Rc<Subscription>; 1],
|
|
75
88
|
}
|
|
76
89
|
|
|
77
90
|
impl Component for ConfigSelector {
|
|
@@ -79,12 +92,6 @@ impl Component for ConfigSelector {
|
|
|
79
92
|
type Properties = ConfigSelectorProps;
|
|
80
93
|
|
|
81
94
|
fn create(ctx: &Context<Self>) -> Self {
|
|
82
|
-
let cb = ctx.link().callback(|_| ConfigSelectorMsg::DragStart);
|
|
83
|
-
let drag_sub = Rc::new(ctx.props().dragdrop.dragstart_received.add_listener(cb));
|
|
84
|
-
|
|
85
|
-
let cb = ctx.link().callback(|_| ConfigSelectorMsg::DragEnd);
|
|
86
|
-
let dragend_sub = Rc::new(ctx.props().dragdrop.dragend_received.add_listener(cb));
|
|
87
|
-
|
|
88
95
|
let cb = ctx
|
|
89
96
|
.link()
|
|
90
97
|
.callback(|x: (String, DragTarget, DragEffect, usize)| {
|
|
@@ -92,12 +99,9 @@ impl Component for ConfigSelector {
|
|
|
92
99
|
});
|
|
93
100
|
let drop_sub = Rc::new(ctx.props().dragdrop.drop_received.add_listener(cb));
|
|
94
101
|
|
|
95
|
-
let cb = ctx.link().callback(|_| ConfigSelectorMsg::ViewCreated);
|
|
96
|
-
let view_sub = Rc::new(ctx.props().session.view_created.add_listener(cb));
|
|
97
|
-
|
|
98
102
|
let filter_dropdown = FilterDropDownElement::new(ctx.props().session.clone());
|
|
99
103
|
let column_dropdown = ColumnDropDownElement::new(ctx.props().session.clone());
|
|
100
|
-
let _subscriptions = [drop_sub
|
|
104
|
+
let _subscriptions = [drop_sub];
|
|
101
105
|
Self {
|
|
102
106
|
filter_dropdown,
|
|
103
107
|
column_dropdown,
|
|
@@ -107,8 +111,6 @@ impl Component for ConfigSelector {
|
|
|
107
111
|
|
|
108
112
|
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
109
113
|
match msg {
|
|
110
|
-
ConfigSelectorMsg::DragStart | ConfigSelectorMsg::ViewCreated => true,
|
|
111
|
-
ConfigSelectorMsg::DragEnd => true,
|
|
112
114
|
ConfigSelectorMsg::DragOver(index, action) => {
|
|
113
115
|
let should_render = ctx.props().dragdrop.notify_drag_enter(action, index);
|
|
114
116
|
if should_render {
|
|
@@ -121,7 +123,7 @@ impl Component for ConfigSelector {
|
|
|
121
123
|
true
|
|
122
124
|
},
|
|
123
125
|
ConfigSelectorMsg::Close(index, DragTarget::Sort) => {
|
|
124
|
-
let mut sort = ctx.props().
|
|
126
|
+
let mut sort = ctx.props().view_config.sort.clone();
|
|
125
127
|
sort.remove(index);
|
|
126
128
|
let sort = Some(sort);
|
|
127
129
|
let config = ViewConfigUpdate {
|
|
@@ -129,10 +131,16 @@ impl Component for ConfigSelector {
|
|
|
129
131
|
..ViewConfigUpdate::default()
|
|
130
132
|
};
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
.
|
|
134
|
-
.
|
|
135
|
-
.
|
|
134
|
+
{
|
|
135
|
+
let session = ctx.props().session.clone();
|
|
136
|
+
let renderer = ctx.props().renderer.clone();
|
|
137
|
+
if session.update_view_config(config).is_ok() {
|
|
138
|
+
ApiFuture::spawn(async move {
|
|
139
|
+
renderer.apply_pending_plugin()?;
|
|
140
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
136
144
|
|
|
137
145
|
ctx.props().onselect.emit(());
|
|
138
146
|
false
|
|
@@ -143,22 +151,26 @@ impl Component for ConfigSelector {
|
|
|
143
151
|
..ViewConfigUpdate::default()
|
|
144
152
|
};
|
|
145
153
|
|
|
146
|
-
|
|
147
|
-
.
|
|
148
|
-
.
|
|
149
|
-
.
|
|
154
|
+
{
|
|
155
|
+
let session = ctx.props().session.clone();
|
|
156
|
+
let renderer = ctx.props().renderer.clone();
|
|
157
|
+
if session.update_view_config(config).is_ok() {
|
|
158
|
+
ApiFuture::spawn(async move {
|
|
159
|
+
renderer.apply_pending_plugin()?;
|
|
160
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
150
164
|
|
|
151
165
|
false
|
|
152
166
|
},
|
|
153
167
|
ConfigSelectorMsg::Close(index, DragTarget::GroupBy) => {
|
|
154
|
-
if ctx.props().
|
|
155
|
-
{
|
|
168
|
+
if ctx.props().view_config.group_rollup_mode == GroupRollupMode::Total {
|
|
156
169
|
let requirements = ctx.props().renderer.metadata();
|
|
157
170
|
|
|
158
171
|
let rollup_features = ctx
|
|
159
172
|
.props()
|
|
160
|
-
.
|
|
161
|
-
.metadata()
|
|
173
|
+
.metadata
|
|
162
174
|
.get_features()
|
|
163
175
|
.map(|x| x.get_group_rollup_modes())
|
|
164
176
|
.unwrap();
|
|
@@ -171,51 +183,69 @@ impl Component for ConfigSelector {
|
|
|
171
183
|
));
|
|
172
184
|
false
|
|
173
185
|
} else {
|
|
174
|
-
let mut group_by = ctx.props().
|
|
186
|
+
let mut group_by = ctx.props().view_config.group_by.clone();
|
|
175
187
|
group_by.remove(index);
|
|
176
188
|
let config = ViewConfigUpdate {
|
|
177
189
|
group_by: Some(group_by),
|
|
178
190
|
..ViewConfigUpdate::default()
|
|
179
191
|
};
|
|
180
192
|
|
|
181
|
-
|
|
182
|
-
.
|
|
183
|
-
.
|
|
184
|
-
.
|
|
193
|
+
{
|
|
194
|
+
let session = ctx.props().session.clone();
|
|
195
|
+
let renderer = ctx.props().renderer.clone();
|
|
196
|
+
if session.update_view_config(config).is_ok() {
|
|
197
|
+
ApiFuture::spawn(async move {
|
|
198
|
+
renderer.apply_pending_plugin()?;
|
|
199
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
185
203
|
|
|
186
204
|
ctx.props().onselect.emit(());
|
|
187
205
|
false
|
|
188
206
|
}
|
|
189
207
|
},
|
|
190
208
|
ConfigSelectorMsg::Close(index, DragTarget::SplitBy) => {
|
|
191
|
-
let mut split_by = ctx.props().
|
|
209
|
+
let mut split_by = ctx.props().view_config.split_by.clone();
|
|
192
210
|
split_by.remove(index);
|
|
193
211
|
let config = ViewConfigUpdate {
|
|
194
212
|
split_by: Some(split_by),
|
|
195
213
|
..ViewConfigUpdate::default()
|
|
196
214
|
};
|
|
197
215
|
|
|
198
|
-
|
|
199
|
-
.
|
|
200
|
-
.
|
|
201
|
-
.
|
|
216
|
+
{
|
|
217
|
+
let session = ctx.props().session.clone();
|
|
218
|
+
let renderer = ctx.props().renderer.clone();
|
|
219
|
+
if session.update_view_config(config).is_ok() {
|
|
220
|
+
ApiFuture::spawn(async move {
|
|
221
|
+
renderer.apply_pending_plugin()?;
|
|
222
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
202
226
|
|
|
203
227
|
ctx.props().onselect.emit(());
|
|
204
228
|
false
|
|
205
229
|
},
|
|
206
230
|
ConfigSelectorMsg::Close(index, DragTarget::Filter) => {
|
|
207
231
|
self.filter_dropdown.hide().unwrap();
|
|
208
|
-
let mut filter = ctx.props().
|
|
232
|
+
let mut filter = ctx.props().view_config.filter.clone();
|
|
209
233
|
filter.remove(index);
|
|
210
234
|
let config = ViewConfigUpdate {
|
|
211
235
|
filter: Some(filter),
|
|
212
236
|
..ViewConfigUpdate::default()
|
|
213
237
|
};
|
|
214
238
|
|
|
215
|
-
|
|
216
|
-
.
|
|
217
|
-
.
|
|
218
|
-
.
|
|
239
|
+
{
|
|
240
|
+
let session = ctx.props().session.clone();
|
|
241
|
+
let renderer = ctx.props().renderer.clone();
|
|
242
|
+
if session.update_view_config(config).is_ok() {
|
|
243
|
+
ApiFuture::spawn(async move {
|
|
244
|
+
renderer.apply_pending_plugin()?;
|
|
245
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
219
249
|
|
|
220
250
|
ctx.props().onselect.emit(());
|
|
221
251
|
false
|
|
@@ -224,18 +254,31 @@ impl Component for ConfigSelector {
|
|
|
224
254
|
ConfigSelectorMsg::Drop(column, action, effect, index)
|
|
225
255
|
if action != DragTarget::Active =>
|
|
226
256
|
{
|
|
227
|
-
let
|
|
257
|
+
let col_type = ctx
|
|
258
|
+
.props()
|
|
259
|
+
.metadata
|
|
260
|
+
.get_column_table_type(column.as_str())
|
|
261
|
+
.unwrap();
|
|
262
|
+
let update = ctx.props().view_config.create_drag_drop_update(
|
|
228
263
|
column,
|
|
264
|
+
col_type,
|
|
229
265
|
index,
|
|
230
266
|
action,
|
|
231
267
|
effect,
|
|
232
268
|
&ctx.props().renderer.metadata(),
|
|
269
|
+
ctx.props().metadata.get_features().unwrap(),
|
|
233
270
|
);
|
|
234
271
|
|
|
235
|
-
|
|
236
|
-
.
|
|
237
|
-
.
|
|
238
|
-
.
|
|
272
|
+
{
|
|
273
|
+
let session = ctx.props().session.clone();
|
|
274
|
+
let renderer = ctx.props().renderer.clone();
|
|
275
|
+
if session.update_view_config(update).is_ok() {
|
|
276
|
+
ApiFuture::spawn(async move {
|
|
277
|
+
renderer.apply_pending_plugin()?;
|
|
278
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
239
282
|
|
|
240
283
|
ctx.props().onselect.emit(());
|
|
241
284
|
false
|
|
@@ -247,7 +290,7 @@ impl Component for ConfigSelector {
|
|
|
247
290
|
},
|
|
248
291
|
ConfigSelectorMsg::Drop(..) => false,
|
|
249
292
|
ConfigSelectorMsg::TransposePivots => {
|
|
250
|
-
let mut view_config = ctx.props().
|
|
293
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
251
294
|
std::mem::swap(&mut view_config.group_by, &mut view_config.split_by);
|
|
252
295
|
|
|
253
296
|
let update = ViewConfigUpdate {
|
|
@@ -256,16 +299,22 @@ impl Component for ConfigSelector {
|
|
|
256
299
|
..ViewConfigUpdate::default()
|
|
257
300
|
};
|
|
258
301
|
|
|
259
|
-
|
|
260
|
-
.
|
|
261
|
-
.
|
|
262
|
-
.
|
|
302
|
+
{
|
|
303
|
+
let session = ctx.props().session.clone();
|
|
304
|
+
let renderer = ctx.props().renderer.clone();
|
|
305
|
+
if session.update_view_config(update).is_ok() {
|
|
306
|
+
ApiFuture::spawn(async move {
|
|
307
|
+
renderer.apply_pending_plugin()?;
|
|
308
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
263
312
|
ctx.props().onselect.emit(());
|
|
264
313
|
false
|
|
265
314
|
},
|
|
266
315
|
|
|
267
316
|
ConfigSelectorMsg::SetFilterValue(index, input) => {
|
|
268
|
-
let mut filter = ctx.props().
|
|
317
|
+
let mut filter = ctx.props().view_config.filter.clone();
|
|
269
318
|
|
|
270
319
|
// TODO Can't special case these - need to make this part of the
|
|
271
320
|
// Features API.
|
|
@@ -295,47 +344,65 @@ impl Component for ConfigSelector {
|
|
|
295
344
|
}
|
|
296
345
|
};
|
|
297
346
|
|
|
298
|
-
|
|
299
|
-
.
|
|
300
|
-
.
|
|
301
|
-
.
|
|
347
|
+
{
|
|
348
|
+
let session = ctx.props().session.clone();
|
|
349
|
+
let renderer = ctx.props().renderer.clone();
|
|
350
|
+
if session.update_view_config(update).is_ok() {
|
|
351
|
+
ApiFuture::spawn(async move {
|
|
352
|
+
renderer.apply_pending_plugin()?;
|
|
353
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
302
357
|
|
|
303
358
|
false
|
|
304
359
|
},
|
|
305
360
|
ConfigSelectorMsg::New(DragTarget::GroupBy, InPlaceColumn::Column(col)) => {
|
|
306
|
-
let mut view_config = ctx.props().
|
|
361
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
307
362
|
view_config.group_by.push(col);
|
|
308
363
|
let update = ViewConfigUpdate {
|
|
309
364
|
group_by: Some(view_config.group_by),
|
|
310
365
|
..ViewConfigUpdate::default()
|
|
311
366
|
};
|
|
312
367
|
|
|
313
|
-
|
|
314
|
-
.
|
|
315
|
-
.
|
|
316
|
-
.
|
|
368
|
+
{
|
|
369
|
+
let session = ctx.props().session.clone();
|
|
370
|
+
let renderer = ctx.props().renderer.clone();
|
|
371
|
+
if session.update_view_config(update).is_ok() {
|
|
372
|
+
ApiFuture::spawn(async move {
|
|
373
|
+
renderer.apply_pending_plugin()?;
|
|
374
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
317
378
|
|
|
318
379
|
ctx.props().onselect.emit(());
|
|
319
380
|
false
|
|
320
381
|
},
|
|
321
382
|
ConfigSelectorMsg::New(DragTarget::SplitBy, InPlaceColumn::Column(col)) => {
|
|
322
|
-
let mut view_config = ctx.props().
|
|
383
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
323
384
|
view_config.split_by.push(col);
|
|
324
385
|
let update = ViewConfigUpdate {
|
|
325
386
|
split_by: Some(view_config.split_by),
|
|
326
387
|
..ViewConfigUpdate::default()
|
|
327
388
|
};
|
|
328
389
|
|
|
329
|
-
|
|
330
|
-
.
|
|
331
|
-
.
|
|
332
|
-
.
|
|
390
|
+
{
|
|
391
|
+
let session = ctx.props().session.clone();
|
|
392
|
+
let renderer = ctx.props().renderer.clone();
|
|
393
|
+
if session.update_view_config(update).is_ok() {
|
|
394
|
+
ApiFuture::spawn(async move {
|
|
395
|
+
renderer.apply_pending_plugin()?;
|
|
396
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
}
|
|
333
400
|
|
|
334
401
|
ctx.props().onselect.emit(());
|
|
335
402
|
false
|
|
336
403
|
},
|
|
337
404
|
ConfigSelectorMsg::New(DragTarget::Filter, InPlaceColumn::Column(column)) => {
|
|
338
|
-
let mut view_config = ctx.props().
|
|
405
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
339
406
|
let op = ctx.props().default_op(column.as_str()).unwrap_or_default();
|
|
340
407
|
view_config.filter.push(Filter::new(
|
|
341
408
|
&column,
|
|
@@ -348,32 +415,44 @@ impl Component for ConfigSelector {
|
|
|
348
415
|
..ViewConfigUpdate::default()
|
|
349
416
|
};
|
|
350
417
|
|
|
351
|
-
|
|
352
|
-
.
|
|
353
|
-
.
|
|
354
|
-
.
|
|
418
|
+
{
|
|
419
|
+
let session = ctx.props().session.clone();
|
|
420
|
+
let renderer = ctx.props().renderer.clone();
|
|
421
|
+
if session.update_view_config(update).is_ok() {
|
|
422
|
+
ApiFuture::spawn(async move {
|
|
423
|
+
renderer.apply_pending_plugin()?;
|
|
424
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
}
|
|
355
428
|
|
|
356
429
|
ctx.props().onselect.emit(());
|
|
357
430
|
false
|
|
358
431
|
},
|
|
359
432
|
ConfigSelectorMsg::New(DragTarget::Sort, InPlaceColumn::Column(col)) => {
|
|
360
|
-
let mut view_config = ctx.props().
|
|
433
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
361
434
|
view_config.sort.push(Sort(col, SortDir::Asc));
|
|
362
435
|
let update = ViewConfigUpdate {
|
|
363
436
|
sort: Some(view_config.sort),
|
|
364
437
|
..ViewConfigUpdate::default()
|
|
365
438
|
};
|
|
366
439
|
|
|
367
|
-
|
|
368
|
-
.
|
|
369
|
-
.
|
|
370
|
-
.
|
|
440
|
+
{
|
|
441
|
+
let session = ctx.props().session.clone();
|
|
442
|
+
let renderer = ctx.props().renderer.clone();
|
|
443
|
+
if session.update_view_config(update).is_ok() {
|
|
444
|
+
ApiFuture::spawn(async move {
|
|
445
|
+
renderer.apply_pending_plugin()?;
|
|
446
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
371
450
|
|
|
372
451
|
ctx.props().onselect.emit(());
|
|
373
452
|
false
|
|
374
453
|
},
|
|
375
454
|
ConfigSelectorMsg::New(DragTarget::GroupBy, InPlaceColumn::Expression(col)) => {
|
|
376
|
-
let mut view_config = ctx.props().
|
|
455
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
377
456
|
view_config.group_by.push(col.name.as_ref().to_owned());
|
|
378
457
|
view_config.expressions.insert(&col);
|
|
379
458
|
let update = ViewConfigUpdate {
|
|
@@ -382,16 +461,22 @@ impl Component for ConfigSelector {
|
|
|
382
461
|
..ViewConfigUpdate::default()
|
|
383
462
|
};
|
|
384
463
|
|
|
385
|
-
|
|
386
|
-
.
|
|
387
|
-
.
|
|
388
|
-
.
|
|
464
|
+
{
|
|
465
|
+
let session = ctx.props().session.clone();
|
|
466
|
+
let renderer = ctx.props().renderer.clone();
|
|
467
|
+
if session.update_view_config(update).is_ok() {
|
|
468
|
+
ApiFuture::spawn(async move {
|
|
469
|
+
renderer.apply_pending_plugin()?;
|
|
470
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
389
474
|
|
|
390
475
|
ctx.props().onselect.emit(());
|
|
391
476
|
false
|
|
392
477
|
},
|
|
393
478
|
ConfigSelectorMsg::New(DragTarget::SplitBy, InPlaceColumn::Expression(col)) => {
|
|
394
|
-
let mut view_config = ctx.props().
|
|
479
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
395
480
|
view_config.split_by.push(col.name.as_ref().to_owned());
|
|
396
481
|
view_config.expressions.insert(&col);
|
|
397
482
|
let update = ViewConfigUpdate {
|
|
@@ -400,16 +485,22 @@ impl Component for ConfigSelector {
|
|
|
400
485
|
..ViewConfigUpdate::default()
|
|
401
486
|
};
|
|
402
487
|
|
|
403
|
-
|
|
404
|
-
.
|
|
405
|
-
.
|
|
406
|
-
.
|
|
488
|
+
{
|
|
489
|
+
let session = ctx.props().session.clone();
|
|
490
|
+
let renderer = ctx.props().renderer.clone();
|
|
491
|
+
if session.update_view_config(update).is_ok() {
|
|
492
|
+
ApiFuture::spawn(async move {
|
|
493
|
+
renderer.apply_pending_plugin()?;
|
|
494
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
}
|
|
407
498
|
|
|
408
499
|
ctx.props().onselect.emit(());
|
|
409
500
|
false
|
|
410
501
|
},
|
|
411
502
|
ConfigSelectorMsg::New(DragTarget::Filter, InPlaceColumn::Expression(col)) => {
|
|
412
|
-
let mut view_config = ctx.props().
|
|
503
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
413
504
|
let column = col.name.as_ref();
|
|
414
505
|
view_config.filter.push(Filter::new(
|
|
415
506
|
column,
|
|
@@ -426,16 +517,22 @@ impl Component for ConfigSelector {
|
|
|
426
517
|
..ViewConfigUpdate::default()
|
|
427
518
|
};
|
|
428
519
|
|
|
429
|
-
|
|
430
|
-
.
|
|
431
|
-
.
|
|
432
|
-
.
|
|
520
|
+
{
|
|
521
|
+
let session = ctx.props().session.clone();
|
|
522
|
+
let renderer = ctx.props().renderer.clone();
|
|
523
|
+
if session.update_view_config(update).is_ok() {
|
|
524
|
+
ApiFuture::spawn(async move {
|
|
525
|
+
renderer.apply_pending_plugin()?;
|
|
526
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}
|
|
433
530
|
|
|
434
531
|
ctx.props().onselect.emit(());
|
|
435
532
|
false
|
|
436
533
|
},
|
|
437
534
|
ConfigSelectorMsg::New(DragTarget::Sort, InPlaceColumn::Expression(col)) => {
|
|
438
|
-
let mut view_config = ctx.props().
|
|
535
|
+
let mut view_config = (*ctx.props().view_config).clone();
|
|
439
536
|
view_config
|
|
440
537
|
.sort
|
|
441
538
|
.push(Sort(col.name.as_ref().to_owned(), SortDir::Asc));
|
|
@@ -446,10 +543,16 @@ impl Component for ConfigSelector {
|
|
|
446
543
|
..ViewConfigUpdate::default()
|
|
447
544
|
};
|
|
448
545
|
|
|
449
|
-
|
|
450
|
-
.
|
|
451
|
-
.
|
|
452
|
-
.
|
|
546
|
+
{
|
|
547
|
+
let session = ctx.props().session.clone();
|
|
548
|
+
let renderer = ctx.props().renderer.clone();
|
|
549
|
+
if session.update_view_config(update).is_ok() {
|
|
550
|
+
ApiFuture::spawn(async move {
|
|
551
|
+
renderer.apply_pending_plugin()?;
|
|
552
|
+
renderer.draw(session.validate().await?.create_view()).await
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
453
556
|
|
|
454
557
|
ctx.props().onselect.emit(());
|
|
455
558
|
false
|
|
@@ -471,12 +574,12 @@ impl Component for ConfigSelector {
|
|
|
471
574
|
session,
|
|
472
575
|
..
|
|
473
576
|
} = ctx.props();
|
|
474
|
-
let config =
|
|
577
|
+
let config = &ctx.props().view_config;
|
|
475
578
|
let transpose = ctx.link().callback(|_| ConfigSelectorMsg::TransposePivots);
|
|
476
579
|
let column_dropdown = self.column_dropdown.clone();
|
|
477
580
|
let mut class = classes!();
|
|
478
581
|
|
|
479
|
-
if
|
|
582
|
+
if ctx.props().drag_column.is_some() {
|
|
480
583
|
class.push("dragdrop-highlight");
|
|
481
584
|
}
|
|
482
585
|
|
|
@@ -489,17 +592,14 @@ impl Component for ConfigSelector {
|
|
|
489
592
|
move |_event| dragdrop.notify_drag_end()
|
|
490
593
|
});
|
|
491
594
|
|
|
492
|
-
let metadata =
|
|
595
|
+
let metadata = &ctx.props().metadata;
|
|
493
596
|
let features = metadata.get_features().unwrap();
|
|
494
597
|
let requirements = renderer.metadata();
|
|
495
598
|
let on_group_rollup_mode = ctx
|
|
496
599
|
.link()
|
|
497
600
|
.callback(ConfigSelectorMsg::UpdateGroupRollupMode);
|
|
498
601
|
|
|
499
|
-
let rollup_features =
|
|
500
|
-
.props()
|
|
501
|
-
.session
|
|
502
|
-
.metadata()
|
|
602
|
+
let rollup_features = metadata
|
|
503
603
|
.get_features()
|
|
504
604
|
.map(|x| x.get_group_rollup_modes())
|
|
505
605
|
.unwrap();
|
|
@@ -507,124 +607,130 @@ impl Component for ConfigSelector {
|
|
|
507
607
|
let group_rollups = requirements.get_group_rollups(&rollup_features);
|
|
508
608
|
|
|
509
609
|
html! {
|
|
510
|
-
|
|
511
|
-
<
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
610
|
+
<>
|
|
611
|
+
<div slot="top_panel" id="top_panel" {class} ondragend={dragend}>
|
|
612
|
+
<LocalStyle href={css!("config-selector")} />
|
|
613
|
+
<div class="pivot_controls">
|
|
614
|
+
if group_rollups.len() > 1 {
|
|
615
|
+
<Select<GroupRollupMode>
|
|
616
|
+
id="group_rollup_mode_selector"
|
|
617
|
+
wrapper_class="group_rollup_wrapper"
|
|
618
|
+
is_autosize=true
|
|
619
|
+
values={Rc::new(
|
|
518
620
|
group_rollups
|
|
519
621
|
.iter()
|
|
520
622
|
.map(|x| SelectItem::Option(*x))
|
|
521
623
|
.collect(),
|
|
522
624
|
)}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
625
|
+
selected={config.group_rollup_mode}
|
|
626
|
+
on_select={on_group_rollup_mode}
|
|
627
|
+
/>
|
|
628
|
+
}
|
|
629
|
+
if !config.group_by.is_empty() && config.split_by.is_empty() {
|
|
630
|
+
<span
|
|
631
|
+
id="transpose_button"
|
|
632
|
+
class="rrow centered"
|
|
633
|
+
title="Transpose Pivots"
|
|
634
|
+
onmousedown={transpose.clone()}
|
|
635
|
+
/>
|
|
636
|
+
}
|
|
637
|
+
</div>
|
|
638
|
+
if features.group_by {
|
|
639
|
+
<GroupBySelector
|
|
640
|
+
name="group_by"
|
|
641
|
+
disabled={config.group_rollup_mode == GroupRollupMode::Total}
|
|
642
|
+
parent={ctx.link().clone()}
|
|
643
|
+
column_dropdown={column_dropdown.clone()}
|
|
644
|
+
exclude={config.group_by.iter().cloned().collect::<HashSet<_>>()}
|
|
645
|
+
is_dragover={ctx.props().dragdrop.is_dragover(DragTarget::GroupBy)}
|
|
646
|
+
{dragdrop}
|
|
647
|
+
>
|
|
648
|
+
{ for config.group_by.iter().map(|group_by| {
|
|
547
649
|
html_nested! {
|
|
548
650
|
<PivotColumn
|
|
549
651
|
action={DragTarget::GroupBy}
|
|
550
652
|
column={group_by.clone()}
|
|
653
|
+
metadata={metadata.clone()}
|
|
551
654
|
{dragdrop}
|
|
552
655
|
opt_session={session}
|
|
553
656
|
>
|
|
554
657
|
</PivotColumn>
|
|
555
658
|
}
|
|
556
659
|
}) }
|
|
557
|
-
|
|
558
|
-
}
|
|
559
|
-
if features.split_by {
|
|
560
|
-
if !config.split_by.is_empty() {
|
|
561
|
-
<div class="pivot_controls">
|
|
562
|
-
<span
|
|
563
|
-
id="transpose_button"
|
|
564
|
-
class="rrow centered"
|
|
565
|
-
title="Transpose Pivots"
|
|
566
|
-
onmousedown={transpose}
|
|
567
|
-
/>
|
|
568
|
-
</div>
|
|
660
|
+
</GroupBySelector>
|
|
569
661
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
662
|
+
if features.split_by {
|
|
663
|
+
if !config.split_by.is_empty() {
|
|
664
|
+
<div class="pivot_controls">
|
|
665
|
+
<span
|
|
666
|
+
id="transpose_button"
|
|
667
|
+
class="rrow centered"
|
|
668
|
+
title="Transpose Pivots"
|
|
669
|
+
onmousedown={transpose}
|
|
670
|
+
/>
|
|
671
|
+
</div>
|
|
672
|
+
}
|
|
673
|
+
<SplitBySelector
|
|
674
|
+
name="split_by"
|
|
675
|
+
parent={ctx.link().clone()}
|
|
676
|
+
column_dropdown={column_dropdown.clone()}
|
|
677
|
+
exclude={config.split_by.iter().cloned().collect::<HashSet<_>>()}
|
|
678
|
+
is_dragover={dragdrop.is_dragover(DragTarget::SplitBy)}
|
|
679
|
+
{dragdrop}
|
|
680
|
+
>
|
|
681
|
+
{ for config.split_by.iter().map(|split_by| {
|
|
579
682
|
html_nested! {
|
|
580
683
|
<PivotColumn
|
|
581
684
|
action={ DragTarget::SplitBy }
|
|
582
685
|
column={ split_by.clone() }
|
|
686
|
+
metadata={metadata.clone()}
|
|
583
687
|
{dragdrop}
|
|
584
688
|
opt_session={session}>
|
|
585
689
|
</PivotColumn>
|
|
586
690
|
}
|
|
587
691
|
}) }
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
692
|
+
</SplitBySelector>
|
|
693
|
+
}
|
|
694
|
+
if features.sort {
|
|
695
|
+
<SortSelector
|
|
696
|
+
name="sort"
|
|
697
|
+
allow_duplicates=true
|
|
698
|
+
parent={ctx.link().clone()}
|
|
699
|
+
column_dropdown={column_dropdown.clone()}
|
|
700
|
+
exclude={config.sort.iter().map(|x| x.0.clone()).collect::<HashSet<_>>()}
|
|
701
|
+
is_dragover={dragdrop.is_dragover(DragTarget::Sort).map(|(index, name)| {
|
|
598
702
|
(index, Sort(name, SortDir::Asc))
|
|
599
703
|
})}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
704
|
+
{dragdrop}
|
|
705
|
+
>
|
|
706
|
+
{ for config.sort.iter().enumerate().map(|(idx, sort)| {
|
|
603
707
|
html_nested! {
|
|
604
708
|
<SortColumn
|
|
605
709
|
idx={ idx }
|
|
606
710
|
sort={ sort.clone() }
|
|
711
|
+
view_config={config.clone()}
|
|
712
|
+
metadata={metadata.clone()}
|
|
607
713
|
{dragdrop}
|
|
608
714
|
{renderer}
|
|
609
715
|
{session}>
|
|
610
716
|
</SortColumn>
|
|
611
717
|
}
|
|
612
718
|
}) }
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
719
|
+
</SortSelector>
|
|
720
|
+
}
|
|
721
|
+
if !features.filter_ops.is_empty() {
|
|
722
|
+
<FilterSelector
|
|
723
|
+
name="filter"
|
|
724
|
+
allow_duplicates=true
|
|
725
|
+
parent={ctx.link().clone()}
|
|
726
|
+
{column_dropdown}
|
|
727
|
+
exclude={config.filter.iter().map(|x| x.column().to_string()).collect::<HashSet<_>>()}
|
|
728
|
+
is_dragover={dragdrop.is_dragover(DragTarget::Filter).map(|(index, name)| {
|
|
623
729
|
(index, Filter::new(&name, "", FilterTerm::Scalar(Scalar::Null)))
|
|
624
730
|
})}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
731
|
+
{dragdrop}
|
|
732
|
+
>
|
|
733
|
+
{ for config.filter.iter().enumerate().map(|(idx, filter)| {
|
|
628
734
|
let filter_keydown = ctx.link()
|
|
629
735
|
.callback(move |txt| ConfigSelectorMsg::SetFilterValue(idx, txt));
|
|
630
736
|
|
|
@@ -634,24 +740,34 @@ impl Component for ConfigSelector {
|
|
|
634
740
|
filter_dropdown={ &self.filter_dropdown }
|
|
635
741
|
filter={ filter.clone() }
|
|
636
742
|
on_keydown={ filter_keydown }
|
|
743
|
+
view_config={config.clone()}
|
|
744
|
+
metadata={metadata.clone()}
|
|
637
745
|
{dragdrop}
|
|
638
746
|
{renderer}
|
|
639
747
|
{session}>
|
|
640
748
|
</FilterColumn>
|
|
641
749
|
}
|
|
642
750
|
}) }
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
751
|
+
</FilterSelector>
|
|
752
|
+
}
|
|
753
|
+
</div>
|
|
754
|
+
<ColumnDropDownPortal
|
|
755
|
+
element={self.column_dropdown.clone()}
|
|
756
|
+
theme={ctx.props().selected_theme.clone().unwrap_or_default()}
|
|
757
|
+
/>
|
|
758
|
+
<FilterDropDownPortal
|
|
759
|
+
element={self.filter_dropdown.clone()}
|
|
760
|
+
theme={ctx.props().selected_theme.clone().unwrap_or_default()}
|
|
761
|
+
/>
|
|
762
|
+
</>
|
|
646
763
|
}
|
|
647
764
|
}
|
|
648
765
|
}
|
|
649
766
|
|
|
650
767
|
impl ConfigSelectorProps {
|
|
651
768
|
fn default_op(&self, column: &str) -> Option<String> {
|
|
652
|
-
let
|
|
653
|
-
let
|
|
654
|
-
let col_type = metadata.get_column_table_type(column)?;
|
|
769
|
+
let features = self.metadata.get_features()?;
|
|
770
|
+
let col_type = self.metadata.get_column_table_type(column)?;
|
|
655
771
|
let first = features.default_op(col_type)?;
|
|
656
772
|
Some(first.to_string())
|
|
657
773
|
}
|