@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
|
@@ -26,18 +26,30 @@ use crate::components::number_column_style::NumberColumnStyle;
|
|
|
26
26
|
use crate::components::string_column_style::StringColumnStyle;
|
|
27
27
|
use crate::components::style_controls::CustomNumberFormat;
|
|
28
28
|
use crate::custom_events::CustomEvents;
|
|
29
|
-
use crate::model::*;
|
|
30
29
|
use crate::presentation::Presentation;
|
|
31
30
|
use crate::renderer::Renderer;
|
|
32
31
|
use crate::session::Session;
|
|
33
|
-
use crate
|
|
32
|
+
use crate::tasks::{
|
|
33
|
+
HasCustomEvents, HasPresentation, HasRenderer, HasSession, SendPluginConfig,
|
|
34
|
+
get_column_style_control_options,
|
|
35
|
+
};
|
|
36
|
+
use crate::utils::PtrEqRc;
|
|
34
37
|
|
|
35
|
-
#[derive(Clone, PartialEq, Properties
|
|
38
|
+
#[derive(Clone, PartialEq, Properties)]
|
|
36
39
|
pub struct StyleTabProps {
|
|
37
40
|
pub ty: Option<ColumnType>,
|
|
38
41
|
pub column_name: String,
|
|
39
42
|
pub group_by_depth: u32,
|
|
40
43
|
|
|
44
|
+
/// View config snapshot — threaded from parent.
|
|
45
|
+
pub view_config: PtrEqRc<perspective_client::config::ViewConfig>,
|
|
46
|
+
|
|
47
|
+
/// Session metadata snapshot — threaded from parent.
|
|
48
|
+
pub metadata: PtrEqRc<crate::session::SessionMetadata>,
|
|
49
|
+
|
|
50
|
+
/// Selected theme name, threaded for PortalModal consumers.
|
|
51
|
+
pub selected_theme: Option<String>,
|
|
52
|
+
|
|
41
53
|
// State
|
|
42
54
|
pub custom_events: CustomEvents,
|
|
43
55
|
pub presentation: Presentation,
|
|
@@ -45,123 +57,152 @@ pub struct StyleTabProps {
|
|
|
45
57
|
pub session: Session,
|
|
46
58
|
}
|
|
47
59
|
|
|
60
|
+
impl HasCustomEvents for StyleTabProps {
|
|
61
|
+
fn custom_events(&self) -> &CustomEvents {
|
|
62
|
+
&self.custom_events
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
impl HasPresentation for StyleTabProps {
|
|
67
|
+
fn presentation(&self) -> &Presentation {
|
|
68
|
+
&self.presentation
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
impl HasRenderer for StyleTabProps {
|
|
73
|
+
fn renderer(&self) -> &Renderer {
|
|
74
|
+
&self.renderer
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
impl HasSession for StyleTabProps {
|
|
79
|
+
fn session(&self) -> &Session {
|
|
80
|
+
&self.session
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
48
84
|
#[function_component]
|
|
49
85
|
pub fn StyleTab(props: &StyleTabProps) -> Html {
|
|
50
|
-
let config = props.presentation
|
|
86
|
+
let config = props.presentation.get_columns_config(&props.column_name);
|
|
51
87
|
let on_change = yew::use_callback(
|
|
52
|
-
(props.
|
|
88
|
+
(props.clone(), props.column_name.clone()),
|
|
53
89
|
|config, (state, column_name)| {
|
|
54
90
|
state.send_plugin_config(column_name, config);
|
|
55
91
|
},
|
|
56
92
|
);
|
|
57
93
|
|
|
58
|
-
let components =
|
|
59
|
-
|
|
60
|
-
.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
94
|
+
let components = get_column_style_control_options(
|
|
95
|
+
&props.renderer,
|
|
96
|
+
&props.view_config,
|
|
97
|
+
&props.metadata,
|
|
98
|
+
&props.column_name,
|
|
99
|
+
)
|
|
100
|
+
.map(|opts| {
|
|
101
|
+
let mut components = vec![];
|
|
102
|
+
if !props.view_config.group_by.is_empty() {
|
|
103
|
+
let aggregate_depth = config.as_ref().map(|x| x.aggregate_depth as f64);
|
|
104
|
+
components.push(("Aggregate Depth", html! {
|
|
105
|
+
<AggregateDepthSelector
|
|
106
|
+
group_by_depth={props.group_by_depth}
|
|
107
|
+
on_change={on_change.clone()}
|
|
108
|
+
column_name={props.column_name.to_owned()}
|
|
109
|
+
value={aggregate_depth.unwrap_or_default() as u32}
|
|
110
|
+
/>
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if let Some(default_config) = opts.datagrid_number_style {
|
|
115
|
+
let config = config
|
|
116
|
+
.as_ref()
|
|
117
|
+
.map(|config| config.datagrid_number_style.clone());
|
|
118
|
+
|
|
119
|
+
components.push(("Number Styles", html! {
|
|
120
|
+
<NumberColumnStyle
|
|
121
|
+
column_name={props.column_name.clone()}
|
|
122
|
+
{config}
|
|
123
|
+
{default_config}
|
|
124
|
+
on_change={on_change.clone()}
|
|
125
|
+
session={props.session.clone()}
|
|
126
|
+
/>
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
if let Some(default_config) = opts.datagrid_string_style {
|
|
130
|
+
let config = config
|
|
131
|
+
.as_ref()
|
|
132
|
+
.map(|config| config.datagrid_string_style.clone());
|
|
133
|
+
|
|
134
|
+
components.push(("String Styles", html! {
|
|
135
|
+
<StringColumnStyle {config} {default_config} on_change={on_change.clone()} />
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if let Some(default_config) = opts.datagrid_datetime_style {
|
|
140
|
+
let config = config
|
|
141
|
+
.as_ref()
|
|
142
|
+
.map(|config| config.datagrid_datetime_style.clone());
|
|
143
|
+
|
|
144
|
+
let enable_time_config = props.ty.unwrap() == ColumnType::Datetime;
|
|
145
|
+
components.push(("Datetime Styles", html! {
|
|
146
|
+
<DatetimeColumnStyle
|
|
147
|
+
{enable_time_config}
|
|
148
|
+
{config}
|
|
149
|
+
{default_config}
|
|
150
|
+
on_change={on_change.clone()}
|
|
151
|
+
/>
|
|
152
|
+
}))
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if let Some(default_config) = opts.symbols {
|
|
156
|
+
let restored_config = config
|
|
157
|
+
.as_ref()
|
|
158
|
+
.map(|config| config.symbols.clone())
|
|
159
|
+
.unwrap_or_default();
|
|
160
|
+
|
|
161
|
+
components.push(("Symbols", html! {
|
|
162
|
+
<SymbolStyle
|
|
163
|
+
{default_config}
|
|
164
|
+
{restored_config}
|
|
165
|
+
on_change={on_change.clone()}
|
|
166
|
+
column_name={props.column_name.clone()}
|
|
167
|
+
selected_theme={props.selected_theme.clone()}
|
|
168
|
+
session={props.session.clone()}
|
|
169
|
+
/>
|
|
170
|
+
}))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if opts.number_string_format.unwrap_or_default() {
|
|
174
|
+
let restored_config = config
|
|
175
|
+
.as_ref()
|
|
176
|
+
.and_then(|config| config.number_format.clone())
|
|
177
|
+
.unwrap_or_default();
|
|
178
|
+
|
|
179
|
+
components.push(("Number Formatting", html! {
|
|
180
|
+
<CustomNumberFormat
|
|
181
|
+
{restored_config}
|
|
182
|
+
on_change={on_change.clone()}
|
|
183
|
+
view_type={props.ty.unwrap()}
|
|
184
|
+
column_name={props.column_name.clone()}
|
|
185
|
+
/>
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
components
|
|
190
|
+
.into_iter()
|
|
191
|
+
.map(|(_title, component)| {
|
|
192
|
+
html! {
|
|
193
|
+
<fieldset class="style-control">
|
|
194
|
+
// <legend >{ title }</legend>
|
|
195
|
+
{ component }
|
|
196
|
+
</fieldset>
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
.collect_vec()
|
|
200
|
+
})
|
|
201
|
+
.unwrap_or_else(|error| {
|
|
202
|
+
vec![html! {
|
|
203
|
+
<Stub message="Could not render column styles" error={Some(format!("{error:?}"))} />
|
|
204
|
+
}]
|
|
205
|
+
});
|
|
165
206
|
|
|
166
207
|
html! {
|
|
167
208
|
<div id="style-tab">
|
|
@@ -18,7 +18,7 @@ use std::rc::Rc;
|
|
|
18
18
|
|
|
19
19
|
use derivative::Derivative;
|
|
20
20
|
use itertools::Itertools;
|
|
21
|
-
use perspective_client::config::{ColumnType, Expression};
|
|
21
|
+
use perspective_client::config::{ColumnType, Expression, ViewConfig};
|
|
22
22
|
use perspective_client::utils::PerspectiveResultExt;
|
|
23
23
|
use yew::{Callback, Component, Html, Properties, html, props};
|
|
24
24
|
|
|
@@ -34,14 +34,17 @@ use crate::components::expression_editor::ExpressionEditorProps;
|
|
|
34
34
|
use crate::components::style::LocalStyle;
|
|
35
35
|
use crate::components::type_icon::TypeIconType;
|
|
36
36
|
use crate::custom_events::CustomEvents;
|
|
37
|
-
use crate::model::*;
|
|
38
37
|
use crate::presentation::{ColumnLocator, ColumnSettingsTab, Presentation};
|
|
39
38
|
use crate::renderer::Renderer;
|
|
40
|
-
use crate::session::Session;
|
|
41
|
-
use crate::
|
|
39
|
+
use crate::session::{Session, SessionMetadataRc};
|
|
40
|
+
use crate::tasks::{
|
|
41
|
+
EditExpression, HasCustomEvents, HasPresentation, HasRenderer, HasSession,
|
|
42
|
+
can_render_column_styles, locator_name_or_default, locator_view_type,
|
|
43
|
+
};
|
|
44
|
+
use crate::utils::PtrEqRc;
|
|
42
45
|
use crate::*;
|
|
43
46
|
|
|
44
|
-
#[derive(Clone, Derivative, Properties
|
|
47
|
+
#[derive(Clone, Derivative, Properties)]
|
|
45
48
|
#[derivative(Debug)]
|
|
46
49
|
pub struct ColumnSettingsPanelProps {
|
|
47
50
|
pub selected_column: ColumnLocator,
|
|
@@ -50,6 +53,20 @@ pub struct ColumnSettingsPanelProps {
|
|
|
50
53
|
pub width_override: Option<i32>,
|
|
51
54
|
pub on_select_tab: Callback<ColumnSettingsTab>,
|
|
52
55
|
|
|
56
|
+
/// Active plugin name threaded as a value prop so that plugin changes
|
|
57
|
+
/// trigger re-initialization via `changed()` rather than a PubSub
|
|
58
|
+
/// `render_limits_changed` subscription.
|
|
59
|
+
pub plugin_name: Option<String>,
|
|
60
|
+
|
|
61
|
+
/// Session metadata snapshot — threaded from `SessionProps`.
|
|
62
|
+
pub metadata: SessionMetadataRc,
|
|
63
|
+
|
|
64
|
+
/// View config snapshot — threaded from `SessionProps`.
|
|
65
|
+
pub view_config: PtrEqRc<ViewConfig>,
|
|
66
|
+
|
|
67
|
+
/// Selected theme name, threaded for PortalModal consumers.
|
|
68
|
+
pub selected_theme: Option<String>,
|
|
69
|
+
|
|
53
70
|
// State
|
|
54
71
|
#[derivative(Debug = "ignore")]
|
|
55
72
|
pub custom_events: CustomEvents,
|
|
@@ -66,7 +83,36 @@ pub struct ColumnSettingsPanelProps {
|
|
|
66
83
|
|
|
67
84
|
impl PartialEq for ColumnSettingsPanelProps {
|
|
68
85
|
fn eq(&self, other: &Self) -> bool {
|
|
69
|
-
self.selected_column == other.selected_column
|
|
86
|
+
self.selected_column == other.selected_column
|
|
87
|
+
&& self.selected_tab == other.selected_tab
|
|
88
|
+
&& self.plugin_name == other.plugin_name
|
|
89
|
+
&& self.metadata == other.metadata
|
|
90
|
+
&& self.view_config == other.view_config
|
|
91
|
+
&& self.selected_theme == other.selected_theme
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
impl HasCustomEvents for ColumnSettingsPanelProps {
|
|
96
|
+
fn custom_events(&self) -> &CustomEvents {
|
|
97
|
+
&self.custom_events
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
impl HasPresentation for ColumnSettingsPanelProps {
|
|
102
|
+
fn presentation(&self) -> &Presentation {
|
|
103
|
+
&self.presentation
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
impl HasRenderer for ColumnSettingsPanelProps {
|
|
108
|
+
fn renderer(&self) -> &Renderer {
|
|
109
|
+
&self.renderer
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
impl HasSession for ColumnSettingsPanelProps {
|
|
114
|
+
fn session(&self) -> &Session {
|
|
115
|
+
&self.session
|
|
70
116
|
}
|
|
71
117
|
}
|
|
72
118
|
|
|
@@ -80,7 +126,6 @@ pub enum ColumnSettingsPanelMsg {
|
|
|
80
126
|
OnSaveAttributes(()),
|
|
81
127
|
OnResetAttributes(()),
|
|
82
128
|
OnDelete(()),
|
|
83
|
-
SessionUpdated(bool),
|
|
84
129
|
}
|
|
85
130
|
|
|
86
131
|
#[derive(Derivative)]
|
|
@@ -102,9 +147,6 @@ pub struct ColumnSettingsPanel {
|
|
|
102
147
|
save_count: u8,
|
|
103
148
|
save_enabled: bool,
|
|
104
149
|
tabs: Vec<ColumnSettingsTab>,
|
|
105
|
-
|
|
106
|
-
#[derivative(Debug = "ignore")]
|
|
107
|
-
_session_sub: Option<Subscription>,
|
|
108
150
|
}
|
|
109
151
|
|
|
110
152
|
impl Component for ColumnSettingsPanel {
|
|
@@ -112,18 +154,7 @@ impl Component for ColumnSettingsPanel {
|
|
|
112
154
|
type Properties = ColumnSettingsPanelProps;
|
|
113
155
|
|
|
114
156
|
fn create(ctx: &yew::prelude::Context<Self>) -> Self {
|
|
115
|
-
let session_cb = ctx
|
|
116
|
-
.link()
|
|
117
|
-
.callback(|(is_update, _)| ColumnSettingsPanelMsg::SessionUpdated(is_update));
|
|
118
|
-
|
|
119
|
-
let session_sub = ctx
|
|
120
|
-
.props()
|
|
121
|
-
.renderer
|
|
122
|
-
.render_limits_changed
|
|
123
|
-
.add_listener(session_cb);
|
|
124
|
-
|
|
125
157
|
let mut this = Self {
|
|
126
|
-
_session_sub: Some(session_sub),
|
|
127
158
|
initial_expr_value: Rc::default(),
|
|
128
159
|
expr_value: Rc::default(),
|
|
129
160
|
expr_valid: false,
|
|
@@ -233,14 +264,6 @@ impl Component for ColumnSettingsPanel {
|
|
|
233
264
|
ctx.props().on_close.emit(());
|
|
234
265
|
true
|
|
235
266
|
},
|
|
236
|
-
ColumnSettingsPanelMsg::SessionUpdated(is_update) => {
|
|
237
|
-
if !is_update {
|
|
238
|
-
self.initialize(ctx);
|
|
239
|
-
true
|
|
240
|
-
} else {
|
|
241
|
-
false
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
267
|
}
|
|
245
268
|
}
|
|
246
269
|
|
|
@@ -264,6 +287,7 @@ impl Component for ColumnSettingsPanel {
|
|
|
264
287
|
ColumnSettingsPanelMsg::SetHeaderValid(valid),
|
|
265
288
|
]
|
|
266
289
|
}),
|
|
290
|
+
metadata: ctx.props().metadata.clone(),
|
|
267
291
|
session: &ctx.props().session
|
|
268
292
|
});
|
|
269
293
|
|
|
@@ -274,13 +298,28 @@ impl Component for ColumnSettingsPanel {
|
|
|
274
298
|
alias: ctx.props().selected_column.name().cloned(),
|
|
275
299
|
disabled: !ctx.props().selected_column.is_expr(),
|
|
276
300
|
reset_count: self.reset_count,
|
|
301
|
+
metadata: ctx.props().metadata.clone(),
|
|
302
|
+
selected_theme: ctx.props().selected_theme.clone(),
|
|
277
303
|
session: &ctx.props().session
|
|
278
304
|
});
|
|
279
305
|
|
|
280
306
|
let disable_delete = ctx
|
|
281
307
|
.props()
|
|
282
|
-
.
|
|
283
|
-
.
|
|
308
|
+
.selected_column
|
|
309
|
+
.name()
|
|
310
|
+
.map(|name| {
|
|
311
|
+
let config = &ctx.props().view_config;
|
|
312
|
+
config.columns.iter().any(|maybe_col| {
|
|
313
|
+
maybe_col
|
|
314
|
+
.as_ref()
|
|
315
|
+
.map(|col| col == name)
|
|
316
|
+
.unwrap_or_default()
|
|
317
|
+
}) || config.group_by.iter().any(|col| col == name)
|
|
318
|
+
|| config.split_by.iter().any(|col| col == name)
|
|
319
|
+
|| config.filter.iter().any(|col| col.column() == name)
|
|
320
|
+
|| config.sort.iter().any(|col| &col.0 == name)
|
|
321
|
+
})
|
|
322
|
+
.unwrap_or_default();
|
|
284
323
|
|
|
285
324
|
let save_section = SaveSettingsProps {
|
|
286
325
|
save_enabled: self.save_enabled,
|
|
@@ -302,15 +341,18 @@ impl Component for ColumnSettingsPanel {
|
|
|
302
341
|
save_section,
|
|
303
342
|
};
|
|
304
343
|
|
|
305
|
-
let style_tab =
|
|
344
|
+
let style_tab = StyleTabProps {
|
|
306
345
|
ty: self.maybe_ty,
|
|
307
346
|
column_name: self.column_name.clone(),
|
|
308
|
-
group_by_depth: ctx.props().
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
347
|
+
group_by_depth: ctx.props().view_config.group_by.len() as u32,
|
|
348
|
+
view_config: ctx.props().view_config.clone(),
|
|
349
|
+
metadata: ctx.props().metadata.clone(),
|
|
350
|
+
selected_theme: ctx.props().selected_theme.clone(),
|
|
351
|
+
custom_events: ctx.props().custom_events.clone(),
|
|
352
|
+
presentation: ctx.props().presentation.clone(),
|
|
353
|
+
renderer: ctx.props().renderer.clone(),
|
|
354
|
+
session: ctx.props().session.clone(),
|
|
355
|
+
};
|
|
314
356
|
|
|
315
357
|
let tab_children = self.tabs.iter().map(|tab| match tab {
|
|
316
358
|
ColumnSettingsTab::Attributes => html! { <AttributesTab ..attrs_tab.clone() /> },
|
|
@@ -356,15 +398,12 @@ impl ColumnSettingsPanel {
|
|
|
356
398
|
}
|
|
357
399
|
|
|
358
400
|
fn initialize(&mut self, ctx: &yew::prelude::Context<Self>) {
|
|
359
|
-
let column_name =
|
|
360
|
-
.props()
|
|
361
|
-
.session
|
|
362
|
-
.locator_name_or_default(&ctx.props().selected_column);
|
|
401
|
+
let column_name =
|
|
402
|
+
locator_name_or_default(&ctx.props().metadata, &ctx.props().selected_column);
|
|
363
403
|
|
|
364
404
|
let initial_expr_value = ctx
|
|
365
405
|
.props()
|
|
366
|
-
.
|
|
367
|
-
.metadata()
|
|
406
|
+
.metadata
|
|
368
407
|
.get_expression_by_alias(&column_name)
|
|
369
408
|
.unwrap_or_default();
|
|
370
409
|
|
|
@@ -372,19 +411,19 @@ impl ColumnSettingsPanel {
|
|
|
372
411
|
let initial_header_value =
|
|
373
412
|
(*initial_expr_value != column_name).then_some(column_name.clone());
|
|
374
413
|
|
|
375
|
-
let maybe_ty = ctx
|
|
376
|
-
.props()
|
|
377
|
-
.session()
|
|
378
|
-
.locator_view_type(&ctx.props().selected_column);
|
|
414
|
+
let maybe_ty = locator_view_type(&ctx.props().metadata, &ctx.props().selected_column);
|
|
379
415
|
|
|
380
416
|
let tabs = {
|
|
381
417
|
let mut tabs = vec![];
|
|
382
418
|
let is_new_expr = ctx.props().selected_column.is_new_expr();
|
|
383
419
|
let show_styles = !is_new_expr
|
|
384
|
-
&&
|
|
385
|
-
.props()
|
|
386
|
-
.
|
|
387
|
-
.
|
|
420
|
+
&& can_render_column_styles(
|
|
421
|
+
&ctx.props().renderer,
|
|
422
|
+
&ctx.props().view_config,
|
|
423
|
+
&ctx.props().metadata,
|
|
424
|
+
&column_name,
|
|
425
|
+
)
|
|
426
|
+
.unwrap_or_default();
|
|
388
427
|
|
|
389
428
|
if !is_new_expr && show_styles {
|
|
390
429
|
tabs.push(ColumnSettingsTab::Style);
|
|
@@ -414,7 +453,6 @@ impl ColumnSettingsPanel {
|
|
|
414
453
|
on_input,
|
|
415
454
|
on_save,
|
|
416
455
|
on_validate,
|
|
417
|
-
_session_sub: self._session_sub.take(),
|
|
418
456
|
..*self
|
|
419
457
|
}
|
|
420
458
|
}
|
|
@@ -14,12 +14,14 @@ use std::collections::HashSet;
|
|
|
14
14
|
use std::marker::PhantomData;
|
|
15
15
|
|
|
16
16
|
use derivative::Derivative;
|
|
17
|
+
use perspective_client::proto::ColumnType;
|
|
17
18
|
use web_sys::*;
|
|
18
19
|
use yew::html::Scope;
|
|
19
20
|
use yew::prelude::*;
|
|
20
21
|
|
|
22
|
+
use crate::components::column_dropdown::ColumnDropDownElement;
|
|
21
23
|
use crate::components::column_selector::{EmptyColumn, InPlaceColumn, InvalidColumn};
|
|
22
|
-
use crate::
|
|
24
|
+
use crate::components::type_icon::TypeIcon;
|
|
23
25
|
use crate::dragdrop::*;
|
|
24
26
|
use crate::utils::DragTarget;
|
|
25
27
|
|
|
@@ -32,12 +34,16 @@ where
|
|
|
32
34
|
<U as Component>::Properties: DragDropListItemProps,
|
|
33
35
|
{
|
|
34
36
|
pub parent: Scope<T>,
|
|
37
|
+
|
|
35
38
|
pub dragdrop: DragDrop,
|
|
36
39
|
pub name: &'static str,
|
|
37
40
|
pub column_dropdown: ColumnDropDownElement,
|
|
38
41
|
pub exclude: HashSet<String>,
|
|
39
42
|
pub children: ChildrenWithProps<U>,
|
|
40
43
|
|
|
44
|
+
#[prop_or_default]
|
|
45
|
+
pub disabled: bool,
|
|
46
|
+
|
|
41
47
|
#[prop_or_default]
|
|
42
48
|
pub is_dragover: Option<(
|
|
43
49
|
usize,
|
|
@@ -59,6 +65,7 @@ where
|
|
|
59
65
|
&& self.children == other.children
|
|
60
66
|
&& self.allow_duplicates == other.allow_duplicates
|
|
61
67
|
&& self.is_dragover == other.is_dragover
|
|
68
|
+
&& self.disabled == other.disabled
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
|
|
@@ -283,20 +290,35 @@ where
|
|
|
283
290
|
let column_dropdown = ctx.props().column_dropdown.clone();
|
|
284
291
|
let exclude = ctx.props().exclude.clone();
|
|
285
292
|
let on_select = ctx.props().parent.callback(V::create);
|
|
293
|
+
let class = classes!("rrow");
|
|
294
|
+
let is_enabled = true;
|
|
295
|
+
|
|
286
296
|
html! {
|
|
287
|
-
<div ref={&self.elem} class
|
|
297
|
+
<div ref={&self.elem} {class}>
|
|
288
298
|
<div
|
|
289
299
|
id={ctx.props().name}
|
|
290
|
-
ondragover={dragover}
|
|
291
|
-
ondragenter={drag_container.dragenter}
|
|
292
|
-
ondragleave={drag_container.dragleave}
|
|
300
|
+
ondragover={is_enabled.then_some(dragover)}
|
|
301
|
+
ondragenter={is_enabled.then_some(drag_container.dragenter)}
|
|
302
|
+
ondragleave={is_enabled.then_some(drag_container.dragleave)}
|
|
293
303
|
ref={drag_container.noderef}
|
|
294
|
-
ondrop={drop}
|
|
304
|
+
ondrop={is_enabled.then_some(drop)}
|
|
295
305
|
>
|
|
296
306
|
<div class="psp-text-field">
|
|
297
307
|
<ul class="psp-text-field__input" for={ctx.props().name}>
|
|
298
308
|
{ columns_html }
|
|
299
|
-
if ctx.props().is_dragover.is_none()
|
|
309
|
+
if ctx.props().disabled && ctx.props().is_dragover.is_none() {
|
|
310
|
+
<div class="pivot-column">
|
|
311
|
+
<div class="pivot-column-border pivot-column-total">
|
|
312
|
+
<span class="drag-handle icon" />
|
|
313
|
+
<TypeIcon ty={ColumnType::Integer} />
|
|
314
|
+
<span class="column_name">{ "TOTAL" }</span>
|
|
315
|
+
</div>
|
|
316
|
+
<span
|
|
317
|
+
class="toggle-mode is_column_active"
|
|
318
|
+
onmousedown={ctx.props().parent.callback(move |_| V::close(0))}
|
|
319
|
+
/>
|
|
320
|
+
</div>
|
|
321
|
+
} else if ctx.props().is_dragover.is_none() | (!invalid_drag && valid_duplicate_drag) {
|
|
300
322
|
<EmptyColumn {column_dropdown} {exclude} {on_select} />
|
|
301
323
|
} else if invalid_drag {
|
|
302
324
|
<InvalidColumn />
|
|
@@ -34,6 +34,9 @@ pub struct ScrollPanelProps {
|
|
|
34
34
|
#[prop_or_default]
|
|
35
35
|
pub viewport_ref: Option<NodeRef>,
|
|
36
36
|
|
|
37
|
+
#[prop_or_default]
|
|
38
|
+
pub initial_width: Option<f64>,
|
|
39
|
+
|
|
37
40
|
#[prop_or_default]
|
|
38
41
|
pub class: Classes,
|
|
39
42
|
|
|
@@ -52,6 +55,9 @@ pub struct ScrollPanelProps {
|
|
|
52
55
|
#[prop_or_default]
|
|
53
56
|
pub on_resize: Option<Rc<PubSub<()>>>,
|
|
54
57
|
|
|
58
|
+
#[prop_or_default]
|
|
59
|
+
pub on_auto_width: Callback<f64>,
|
|
60
|
+
|
|
55
61
|
#[prop_or_default]
|
|
56
62
|
pub on_dimensions_reset: Option<Rc<PubSub<()>>>,
|
|
57
63
|
|
|
@@ -125,7 +131,7 @@ impl Component for ScrollPanel {
|
|
|
125
131
|
Self {
|
|
126
132
|
viewport_ref: Default::default(),
|
|
127
133
|
viewport_height: 0f64,
|
|
128
|
-
viewport_width:
|
|
134
|
+
viewport_width: ctx.props().initial_width.unwrap_or_default(),
|
|
129
135
|
content_window: None,
|
|
130
136
|
needs_rerender: true,
|
|
131
137
|
total_height,
|
|
@@ -150,6 +156,7 @@ impl Component for ScrollPanel {
|
|
|
150
156
|
|
|
151
157
|
self.viewport_height = rect.height() - 8.0;
|
|
152
158
|
self.viewport_width = self.viewport_width.max(rect.width() - 6.0);
|
|
159
|
+
ctx.props().on_auto_width.emit(self.viewport_width);
|
|
153
160
|
re_render
|
|
154
161
|
},
|
|
155
162
|
ScrollPanelMsg::CalculateWindowContent => self.calculate_window_content(ctx),
|