@perspective-dev/viewer 4.3.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 -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/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/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/wasm/perspective-viewer.d.ts +57 -53
- package/dist/wasm/perspective-viewer.js +190 -165
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +17 -18
- 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} +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/{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} +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 +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 +22 -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 -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 +1 -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.rs +83 -9
- 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}/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 -21
- 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/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-68fef752754ffbc6}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → perspective-viewer-68fef752754ffbc6}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → perspective-viewer-68fef752754ffbc6}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → perspective-viewer-68fef752754ffbc6}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d729f682ba5c19df → 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
|
}
|
|
@@ -19,9 +19,9 @@ use web_sys::*;
|
|
|
19
19
|
use yew::html::Scope;
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
|
+
use crate::components::column_dropdown::ColumnDropDownElement;
|
|
22
23
|
use crate::components::column_selector::{EmptyColumn, InPlaceColumn, InvalidColumn};
|
|
23
24
|
use crate::components::type_icon::TypeIcon;
|
|
24
|
-
use crate::custom_elements::ColumnDropDownElement;
|
|
25
25
|
use crate::dragdrop::*;
|
|
26
26
|
use crate::utils::DragTarget;
|
|
27
27
|
|
|
@@ -309,6 +309,7 @@ where
|
|
|
309
309
|
if ctx.props().disabled && ctx.props().is_dragover.is_none() {
|
|
310
310
|
<div class="pivot-column">
|
|
311
311
|
<div class="pivot-column-border pivot-column-total">
|
|
312
|
+
<span class="drag-handle icon" />
|
|
312
313
|
<TypeIcon ty={ColumnType::Integer} />
|
|
313
314
|
<span class="column_name">{ "TOTAL" }</span>
|
|
314
315
|
</div>
|
|
@@ -24,7 +24,7 @@ pub fn SidebarCloseButton(p: &SidebarCloseButtonProps) -> Html {
|
|
|
24
24
|
let id = &p.id;
|
|
25
25
|
html! {
|
|
26
26
|
<div {onclick} {id} class="sidebar_close_button">
|
|
27
|
-
<div class="sidebar_close_button_inner"
|
|
27
|
+
<div class="sidebar_close_button_inner"><span class="icon" /></div>
|
|
28
28
|
</div>
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -95,7 +95,7 @@ impl<T: ColumnTab> Component for TabList<T> {
|
|
|
95
95
|
<div class="tab-border" />
|
|
96
96
|
</span>
|
|
97
97
|
</div>
|
|
98
|
-
<div id="format-tab" class="tab-content">
|
|
98
|
+
<div id="format-tab" class="tab-content scrollable">
|
|
99
99
|
{ ctx.props().children.iter().nth(self.selected_idx) }
|
|
100
100
|
</div>
|
|
101
101
|
</>
|
|
@@ -15,47 +15,25 @@ use std::rc::Rc;
|
|
|
15
15
|
use yew::prelude::*;
|
|
16
16
|
|
|
17
17
|
use super::containers::dropdown_menu::*;
|
|
18
|
-
use super::modal::*;
|
|
19
|
-
use super::style::StyleProvider;
|
|
20
|
-
use crate::model::*;
|
|
21
18
|
use crate::renderer::*;
|
|
22
|
-
use crate::
|
|
19
|
+
use crate::tasks::*;
|
|
23
20
|
|
|
24
21
|
type CopyDropDownMenuItem = DropDownMenuItem<ExportFile>;
|
|
25
22
|
|
|
26
23
|
#[derive(Properties, PartialEq)]
|
|
27
24
|
pub struct CopyDropDownMenuProps {
|
|
28
25
|
pub callback: Callback<ExportFile>,
|
|
29
|
-
pub root: web_sys::HtmlElement,
|
|
30
26
|
pub renderer: Renderer,
|
|
31
|
-
|
|
32
|
-
#[prop_or_default]
|
|
33
|
-
weak_link: WeakScope<CopyDropDownMenu>,
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
impl ModalLink<CopyDropDownMenu> for CopyDropDownMenuProps {
|
|
37
|
-
fn weak_link(&self) -> &'_ WeakScope<CopyDropDownMenu> {
|
|
38
|
-
&self.weak_link
|
|
39
|
-
}
|
|
40
27
|
}
|
|
41
28
|
|
|
42
|
-
pub struct CopyDropDownMenu {
|
|
43
|
-
_sub: Subscription,
|
|
44
|
-
}
|
|
29
|
+
pub struct CopyDropDownMenu {}
|
|
45
30
|
|
|
46
31
|
impl Component for CopyDropDownMenu {
|
|
47
32
|
type Message = ();
|
|
48
33
|
type Properties = CopyDropDownMenuProps;
|
|
49
34
|
|
|
50
|
-
fn create(
|
|
51
|
-
|
|
52
|
-
let _sub = ctx
|
|
53
|
-
.props()
|
|
54
|
-
.renderer
|
|
55
|
-
.plugin_changed
|
|
56
|
-
.add_listener(ctx.link().callback(|_| ()));
|
|
57
|
-
|
|
58
|
-
Self { _sub }
|
|
35
|
+
fn create(_ctx: &Context<Self>) -> Self {
|
|
36
|
+
Self {}
|
|
59
37
|
}
|
|
60
38
|
|
|
61
39
|
fn update(&mut self, _ctx: &Context<Self>, _msg: Self::Message) -> bool {
|
|
@@ -67,12 +45,13 @@ impl Component for CopyDropDownMenu {
|
|
|
67
45
|
let is_chart = plugin.name().as_str() != "Datagrid";
|
|
68
46
|
let has_selection = ctx.props().renderer.get_selection().is_some();
|
|
69
47
|
html! {
|
|
70
|
-
|
|
48
|
+
<>
|
|
49
|
+
<div id="test" />
|
|
71
50
|
<DropDownMenu<ExportFile>
|
|
72
51
|
values={Rc::new(get_menu_items(is_chart, has_selection))}
|
|
73
52
|
callback={&ctx.props().callback}
|
|
74
53
|
/>
|
|
75
|
-
|
|
54
|
+
</>
|
|
76
55
|
}
|
|
77
56
|
}
|
|
78
57
|
}
|