@perspective-dev/viewer 4.4.1 → 4.5.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 +1 -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 -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/bootstrap.d.ts +2 -1
- package/dist/esm/column-format.d.ts +51 -0
- package/dist/esm/extensions.d.ts +2 -0
- package/dist/esm/perspective-viewer.d.ts +3 -1
- package/dist/esm/perspective-viewer.inline.js +1 -2
- package/dist/esm/perspective-viewer.inline.js.map +4 -4
- package/dist/esm/perspective-viewer.js +1 -2
- package/dist/esm/perspective-viewer.js.map +4 -4
- package/dist/esm/perspective-viewer.worker.d.ts +2 -0
- package/dist/esm/plugin.d.ts +16 -72
- package/dist/esm/ts-rs/ColumnSelectMode.d.ts +1 -0
- package/dist/esm/ts-rs/PluginStaticConfig.d.ts +77 -0
- package/dist/esm/ts-rs/ViewerConfig.d.ts +6 -3
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +7 -4
- package/dist/wasm/perspective-viewer.d.ts +77 -18
- package/dist/wasm/perspective-viewer.js +293 -144
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +20 -15
- package/package.json +24 -2
- package/src/css/column-selector.css +3 -2
- package/src/css/column-settings-panel.css +35 -6
- package/src/css/column-style.css +27 -2
- package/src/css/containers/scroll-panel.css +2 -1
- package/src/css/containers/tabs.css +8 -52
- package/src/css/dom/checkbox.css +0 -4
- package/src/css/form/code-editor.css +1 -0
- package/src/css/form/debug.css +3 -10
- package/src/css/plugin-selector.css +33 -0
- package/src/css/plugin-settings-panel.css +99 -0
- package/src/css/viewer.css +65 -3
- package/src/rust/components/column_dropdown.rs +3 -1
- package/src/rust/components/column_selector/active_column.rs +13 -19
- package/src/rust/components/column_selector/config_selector.rs +20 -20
- package/src/rust/components/column_selector/filter_column.rs +14 -14
- package/src/rust/components/column_selector/inactive_column.rs +9 -15
- package/src/rust/components/column_selector/pivot_column.rs +7 -7
- package/src/rust/components/column_selector/sort_column.rs +7 -7
- package/src/rust/components/column_selector.rs +55 -37
- package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +15 -7
- package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +394 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +15 -6
- package/src/rust/components/column_settings_sidebar/style_tab.rs +267 -136
- package/src/rust/components/column_settings_sidebar.rs +43 -49
- package/src/rust/components/containers/dragdrop_list.rs +5 -5
- package/src/rust/components/containers/mod.rs +0 -1
- package/src/rust/components/containers/scroll_panel.rs +21 -7
- package/src/rust/components/containers/sidebar.rs +8 -6
- package/src/rust/components/containers/split_panel.rs +3 -3
- package/src/rust/components/containers/tab_list.rs +3 -9
- package/src/rust/components/copy_dropdown.rs +2 -3
- package/src/rust/components/datetime_column_style.rs +19 -81
- package/src/rust/components/editable_header.rs +2 -3
- package/src/rust/components/export_dropdown.rs +2 -3
- package/src/rust/components/expression_editor.rs +29 -17
- package/src/rust/components/filter_dropdown.rs +2 -1
- package/src/rust/components/form/color_range_selector.rs +14 -7
- package/src/rust/components/form/debug.rs +47 -37
- package/src/rust/components/main_panel.rs +24 -65
- package/src/rust/components/mod.rs +2 -1
- package/src/rust/components/number_series_style.rs +161 -0
- package/src/rust/components/plugin_tab.rs +221 -0
- package/src/rust/components/settings_panel.rs +181 -59
- package/src/rust/components/status_bar.rs +140 -173
- package/src/rust/components/status_indicator.rs +15 -22
- package/src/rust/components/string_column_style.rs +20 -82
- package/src/rust/components/style_controls/number_string_format.rs +14 -30
- package/src/rust/components/viewer.rs +92 -131
- package/src/rust/config/column_config_schema.rs +195 -0
- package/src/rust/config/columns_config.rs +4 -97
- package/src/rust/config/datetime_column_style.rs +0 -5
- package/src/rust/config/mod.rs +8 -2
- package/src/rust/config/number_series_style.rs +79 -0
- package/src/rust/config/plugin_static_config.rs +144 -0
- package/src/rust/config/string_column_style.rs +0 -5
- package/src/rust/config/viewer_config.rs +5 -6
- package/src/rust/custom_elements/copy_dropdown.rs +30 -18
- package/src/rust/custom_elements/debug_plugin.rs +1 -3
- package/src/rust/custom_elements/export_dropdown.rs +26 -18
- package/src/rust/custom_elements/viewer.rs +62 -73
- package/src/rust/custom_events.rs +181 -224
- package/src/rust/js/plugin.rs +45 -117
- package/src/rust/lib.rs +34 -5
- package/src/rust/presentation/drag_helpers.rs +206 -0
- package/src/rust/presentation/props.rs +8 -0
- package/src/rust/presentation.rs +256 -41
- package/src/rust/{tasks → queries}/column_locator.rs +17 -73
- package/src/rust/queries/column_values.rs +59 -0
- package/src/rust/{tasks → queries}/columns_iter_set.rs +11 -18
- package/src/rust/queries/exports.rs +96 -0
- package/src/rust/queries/fetch_column_stats.rs +94 -0
- package/src/rust/queries/get_viewer_config.rs +54 -0
- package/src/rust/queries/mod.rs +44 -0
- package/src/rust/queries/plugin_column_styles.rs +101 -0
- package/src/rust/{engines.rs → queries/validate_expression.rs} +26 -15
- package/src/rust/renderer/activate.rs +1 -0
- package/src/rust/renderer/limits.rs +9 -4
- package/src/rust/renderer/plugin_store.rs +12 -0
- package/src/rust/renderer/props.rs +28 -3
- package/src/rust/renderer/registry.rs +40 -15
- package/src/rust/renderer.rs +640 -51
- package/src/rust/session/column_defaults_update.rs +20 -28
- package/src/rust/session/drag_drop_update.rs +10 -10
- package/src/rust/session/metadata.rs +31 -16
- package/src/rust/session/props.rs +15 -6
- package/src/rust/session/view_subscription.rs +10 -0
- package/src/rust/session.rs +109 -147
- package/src/rust/tasks/copy_export.rs +178 -158
- package/src/rust/tasks/{structural.rs → dismiss_render_warning.rs} +20 -40
- package/src/rust/tasks/edit_expression.rs +68 -88
- package/src/rust/tasks/eject.rs +25 -22
- package/src/rust/tasks/intersection_observer.rs +8 -21
- package/src/rust/tasks/mod.rs +19 -21
- package/src/rust/tasks/reset_all.rs +78 -0
- package/src/rust/tasks/resize_observer.rs +11 -33
- package/src/rust/tasks/restore_and_render.rs +117 -90
- package/src/rust/tasks/{get_viewer_config.rs → send_column_config.rs} +38 -35
- package/src/rust/tasks/send_plugin_config.rs +32 -33
- package/src/rust/tasks/update_and_render.rs +66 -47
- package/src/rust/{components/containers/trap_door_panel.rs → tasks/update_theme.rs} +34 -33
- package/src/rust/tasks/validate_expression.rs +61 -0
- package/src/rust/utils/browser/selection.rs +4 -4
- package/src/rust/utils/mod.rs +0 -63
- package/src/svg/mega-menu-icons-density.svg +23 -0
- package/src/svg/mega-menu-icons-map-density.svg +24 -0
- package/src/svg/mega-menu-icons-map-line.svg +19 -0
- package/src/themes/botanical.css +27 -53
- package/src/themes/defaults.css +24 -36
- package/src/themes/dracula.css +36 -54
- package/src/themes/gruvbox-dark.css +39 -59
- package/src/themes/gruvbox.css +16 -28
- package/src/themes/icons.css +3 -0
- package/src/themes/intl/de.css +42 -6
- package/src/themes/intl/es.css +42 -6
- package/src/themes/intl/fr.css +42 -6
- package/src/themes/intl/ja.css +42 -6
- package/src/themes/intl/pt.css +42 -6
- package/src/themes/intl/zh.css +42 -6
- package/src/themes/intl.css +37 -4
- package/src/themes/monokai.css +45 -61
- package/src/themes/phosphor.css +20 -29
- package/src/themes/pro-dark.css +25 -34
- package/src/themes/solarized-dark.css +21 -36
- package/src/themes/solarized.css +13 -23
- package/src/themes/vaporwave.css +40 -74
- package/src/ts/bootstrap.ts +14 -3
- package/src/ts/column-format.ts +162 -0
- package/src/ts/extensions.ts +4 -0
- package/src/ts/perspective-viewer.ts +9 -1
- package/src/{rust/components/column_settings_sidebar/style_tab/stub.rs → ts/perspective-viewer.worker.ts} +2 -22
- package/src/ts/plugin.ts +25 -101
- package/src/ts/ts-rs/{FormatUnit.ts → ColumnSelectMode.ts} +1 -1
- package/src/ts/ts-rs/PluginStaticConfig.ts +78 -0
- package/src/ts/ts-rs/ViewerConfig.ts +1 -2
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +2 -3
- package/dist/esm/ts-rs/ColumnConfigValues.d.ts +0 -31
- package/dist/esm/ts-rs/CustomDatetimeFormat.d.ts +0 -1
- package/dist/esm/ts-rs/CustomDatetimeStyleConfig.d.ts +0 -15
- package/dist/esm/ts-rs/CustomNumberFormatConfig.d.ts +0 -18
- package/dist/esm/ts-rs/DatetimeColorMode.d.ts +0 -1
- package/dist/esm/ts-rs/DatetimeFormatType.d.ts +0 -6
- package/dist/esm/ts-rs/FormatMode.d.ts +0 -1
- package/dist/esm/ts-rs/FormatUnit.d.ts +0 -1
- package/dist/esm/ts-rs/NumberBackgroundMode.d.ts +0 -1
- package/dist/esm/ts-rs/NumberForegroundMode.d.ts +0 -1
- package/dist/esm/ts-rs/PluginConfig.d.ts +0 -2
- package/dist/esm/ts-rs/RoundingMode.d.ts +0 -1
- package/dist/esm/ts-rs/RoundingPriority.d.ts +0 -1
- package/dist/esm/ts-rs/SignDisplay.d.ts +0 -1
- package/dist/esm/ts-rs/SimpleDatetimeFormat.d.ts +0 -1
- package/dist/esm/ts-rs/SimpleDatetimeStyleConfig.d.ts +0 -6
- package/dist/esm/ts-rs/StringColorMode.d.ts +0 -1
- package/dist/esm/ts-rs/TrailingZeroDisplay.d.ts +0 -1
- package/dist/esm/ts-rs/UseGrouping.d.ts +0 -1
- package/src/rust/components/number_column_style.rs +0 -491
- package/src/rust/config/number_column_style.rs +0 -136
- package/src/rust/dragdrop.rs +0 -481
- package/src/rust/tasks/plugin_column_styles.rs +0 -98
- package/src/ts/ts-rs/ColumnConfigValues.ts +0 -14
- package/src/ts/ts-rs/CustomDatetimeFormat.ts +0 -3
- package/src/ts/ts-rs/CustomDatetimeStyleConfig.ts +0 -5
- package/src/ts/ts-rs/CustomNumberFormatConfig.ts +0 -8
- package/src/ts/ts-rs/DatetimeColorMode.ts +0 -3
- package/src/ts/ts-rs/DatetimeFormatType.ts +0 -8
- package/src/ts/ts-rs/FormatMode.ts +0 -3
- package/src/ts/ts-rs/NumberBackgroundMode.ts +0 -3
- package/src/ts/ts-rs/NumberForegroundMode.ts +0 -3
- package/src/ts/ts-rs/PluginConfig.ts +0 -4
- package/src/ts/ts-rs/RoundingMode.ts +0 -3
- package/src/ts/ts-rs/RoundingPriority.ts +0 -3
- package/src/ts/ts-rs/SignDisplay.ts +0 -3
- package/src/ts/ts-rs/SimpleDatetimeFormat.ts +0 -3
- package/src/ts/ts-rs/SimpleDatetimeStyleConfig.ts +0 -4
- package/src/ts/ts-rs/StringColorMode.ts +0 -3
- package/src/ts/ts-rs/TrailingZeroDisplay.ts +0 -3
- package/src/ts/ts-rs/UseGrouping.ts +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-d924246f0b4a3dce → perspective-viewer-39ab7da3ca157861}/inline4.js +0 -0
- /package/src/rust/{tasks → config}/export_method.rs +0 -0
- /package/src/rust/{tasks → queries}/export_app.rs +0 -0
- /package/src/rust/{tasks → queries}/is_invalid_drop.rs +0 -0
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
mod attributes_tab;
|
|
13
13
|
|
|
14
14
|
mod save_settings;
|
|
15
|
-
mod style_tab;
|
|
15
|
+
pub(crate) mod style_tab;
|
|
16
16
|
|
|
17
17
|
use std::rc::Rc;
|
|
18
18
|
|
|
@@ -33,14 +33,10 @@ use crate::components::editable_header::EditableHeaderProps;
|
|
|
33
33
|
use crate::components::expression_editor::ExpressionEditorProps;
|
|
34
34
|
use crate::components::style::LocalStyle;
|
|
35
35
|
use crate::components::type_icon::TypeIconType;
|
|
36
|
-
use crate::custom_events::CustomEvents;
|
|
37
36
|
use crate::presentation::{ColumnLocator, ColumnSettingsTab, Presentation};
|
|
38
37
|
use crate::renderer::Renderer;
|
|
39
38
|
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
|
-
};
|
|
39
|
+
use crate::tasks::{delete_expr, save_expr, update_expr};
|
|
44
40
|
use crate::utils::PtrEqRc;
|
|
45
41
|
use crate::*;
|
|
46
42
|
|
|
@@ -64,13 +60,13 @@ pub struct ColumnSettingsPanelProps {
|
|
|
64
60
|
/// View config snapshot — threaded from `SessionProps`.
|
|
65
61
|
pub view_config: PtrEqRc<ViewConfig>,
|
|
66
62
|
|
|
63
|
+
/// Per-column stats snapshot — threaded from `SessionProps`.
|
|
64
|
+
pub column_stats: PtrEqRc<std::collections::HashMap<String, crate::session::ColumnStats>>,
|
|
65
|
+
|
|
67
66
|
/// Selected theme name, threaded for PortalModal consumers.
|
|
68
67
|
pub selected_theme: Option<String>,
|
|
69
68
|
|
|
70
69
|
// State
|
|
71
|
-
#[derivative(Debug = "ignore")]
|
|
72
|
-
pub custom_events: CustomEvents,
|
|
73
|
-
|
|
74
70
|
#[derivative(Debug = "ignore")]
|
|
75
71
|
pub presentation: Presentation,
|
|
76
72
|
|
|
@@ -88,34 +84,11 @@ impl PartialEq for ColumnSettingsPanelProps {
|
|
|
88
84
|
&& self.plugin_name == other.plugin_name
|
|
89
85
|
&& self.metadata == other.metadata
|
|
90
86
|
&& self.view_config == other.view_config
|
|
87
|
+
&& self.column_stats == other.column_stats
|
|
91
88
|
&& self.selected_theme == other.selected_theme
|
|
92
89
|
}
|
|
93
90
|
}
|
|
94
91
|
|
|
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
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
92
|
#[derive(Debug)]
|
|
120
93
|
pub enum ColumnSettingsPanelMsg {
|
|
121
94
|
SetExprValue(Rc<String>),
|
|
@@ -239,11 +212,20 @@ impl Component for ColumnSettingsPanel {
|
|
|
239
212
|
ColumnLocator::Table(_) => {
|
|
240
213
|
tracing::error!("Tried to save non-expression column!")
|
|
241
214
|
},
|
|
242
|
-
ColumnLocator::Expression(name) =>
|
|
243
|
-
ctx.props().
|
|
244
|
-
|
|
215
|
+
ColumnLocator::Expression(name) => update_expr(
|
|
216
|
+
&ctx.props().session,
|
|
217
|
+
&ctx.props().renderer,
|
|
218
|
+
&ctx.props().presentation,
|
|
219
|
+
name.clone(),
|
|
220
|
+
new_expr,
|
|
221
|
+
),
|
|
245
222
|
ColumnLocator::NewExpression => {
|
|
246
|
-
if let Err(err) =
|
|
223
|
+
if let Err(err) = save_expr(
|
|
224
|
+
&ctx.props().session,
|
|
225
|
+
&ctx.props().renderer,
|
|
226
|
+
&ctx.props().presentation,
|
|
227
|
+
new_expr,
|
|
228
|
+
) {
|
|
247
229
|
tracing::warn!("{}", err);
|
|
248
230
|
}
|
|
249
231
|
},
|
|
@@ -258,7 +240,12 @@ impl Component for ColumnSettingsPanel {
|
|
|
258
240
|
},
|
|
259
241
|
ColumnSettingsPanelMsg::OnDelete(()) => {
|
|
260
242
|
if ctx.props().selected_column.is_saved_expr() {
|
|
261
|
-
|
|
243
|
+
delete_expr(
|
|
244
|
+
&ctx.props().session,
|
|
245
|
+
&ctx.props().renderer,
|
|
246
|
+
&self.column_name,
|
|
247
|
+
)
|
|
248
|
+
.unwrap_or_log();
|
|
262
249
|
}
|
|
263
250
|
|
|
264
251
|
ctx.props().on_close.emit(());
|
|
@@ -347,8 +334,8 @@ impl Component for ColumnSettingsPanel {
|
|
|
347
334
|
group_by_depth: ctx.props().view_config.group_by.len() as u32,
|
|
348
335
|
view_config: ctx.props().view_config.clone(),
|
|
349
336
|
metadata: ctx.props().metadata.clone(),
|
|
337
|
+
column_stats: ctx.props().column_stats.clone(),
|
|
350
338
|
selected_theme: ctx.props().selected_theme.clone(),
|
|
351
|
-
custom_events: ctx.props().custom_events.clone(),
|
|
352
339
|
presentation: ctx.props().presentation.clone(),
|
|
353
340
|
renderer: ctx.props().renderer.clone(),
|
|
354
341
|
session: ctx.props().session.clone(),
|
|
@@ -398,8 +385,10 @@ impl ColumnSettingsPanel {
|
|
|
398
385
|
}
|
|
399
386
|
|
|
400
387
|
fn initialize(&mut self, ctx: &yew::prelude::Context<Self>) {
|
|
401
|
-
let column_name =
|
|
402
|
-
|
|
388
|
+
let column_name = ctx
|
|
389
|
+
.props()
|
|
390
|
+
.metadata
|
|
391
|
+
.locator_name_or_default(&ctx.props().selected_column);
|
|
403
392
|
|
|
404
393
|
let initial_expr_value = ctx
|
|
405
394
|
.props()
|
|
@@ -411,19 +400,23 @@ impl ColumnSettingsPanel {
|
|
|
411
400
|
let initial_header_value =
|
|
412
401
|
(*initial_expr_value != column_name).then_some(column_name.clone());
|
|
413
402
|
|
|
414
|
-
let maybe_ty =
|
|
403
|
+
let maybe_ty = ctx
|
|
404
|
+
.props()
|
|
405
|
+
.metadata
|
|
406
|
+
.locator_view_type(&ctx.props().selected_column);
|
|
415
407
|
|
|
416
408
|
let tabs = {
|
|
417
409
|
let mut tabs = vec![];
|
|
418
410
|
let is_new_expr = ctx.props().selected_column.is_new_expr();
|
|
419
411
|
let show_styles = !is_new_expr
|
|
420
|
-
&& can_render_column_styles(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
412
|
+
&& ctx.props().renderer.can_render_column_styles()
|
|
413
|
+
&& ctx.props().view_config.columns.contains(&Some(
|
|
414
|
+
ctx.props()
|
|
415
|
+
.selected_column
|
|
416
|
+
.name()
|
|
417
|
+
.map(|x| x.to_string())
|
|
418
|
+
.unwrap_or_default(),
|
|
419
|
+
));
|
|
427
420
|
|
|
428
421
|
if !is_new_expr && show_styles {
|
|
429
422
|
tabs.push(ColumnSettingsTab::Style);
|
|
@@ -432,6 +425,7 @@ impl ColumnSettingsPanel {
|
|
|
432
425
|
if ctx.props().selected_column.is_expr() {
|
|
433
426
|
tabs.push(ColumnSettingsTab::Attributes);
|
|
434
427
|
}
|
|
428
|
+
|
|
435
429
|
tabs
|
|
436
430
|
};
|
|
437
431
|
|
|
@@ -22,7 +22,7 @@ use yew::prelude::*;
|
|
|
22
22
|
use crate::components::column_dropdown::ColumnDropDownElement;
|
|
23
23
|
use crate::components::column_selector::{EmptyColumn, InPlaceColumn, InvalidColumn};
|
|
24
24
|
use crate::components::type_icon::TypeIcon;
|
|
25
|
-
use crate::
|
|
25
|
+
use crate::presentation::{DragDropContainer, Presentation};
|
|
26
26
|
use crate::utils::DragTarget;
|
|
27
27
|
|
|
28
28
|
#[derive(Properties, Derivative)]
|
|
@@ -35,7 +35,7 @@ where
|
|
|
35
35
|
{
|
|
36
36
|
pub parent: Scope<T>,
|
|
37
37
|
|
|
38
|
-
pub
|
|
38
|
+
pub presentation: Presentation,
|
|
39
39
|
pub name: &'static str,
|
|
40
40
|
pub column_dropdown: ColumnDropDownElement,
|
|
41
41
|
pub exclude: HashSet<String>,
|
|
@@ -185,11 +185,11 @@ where
|
|
|
185
185
|
);
|
|
186
186
|
|
|
187
187
|
let drop = Callback::from({
|
|
188
|
-
let
|
|
188
|
+
let presentation = ctx.props().presentation.clone();
|
|
189
189
|
let link = ctx.link().clone();
|
|
190
190
|
move |event| {
|
|
191
191
|
link.send_message(DragDropListMsg::Freeze(false));
|
|
192
|
-
|
|
192
|
+
presentation.notify_drop(&event);
|
|
193
193
|
}
|
|
194
194
|
});
|
|
195
195
|
|
|
@@ -210,7 +210,7 @@ where
|
|
|
210
210
|
let is_append = index == columns.len();
|
|
211
211
|
let is_self_move = ctx
|
|
212
212
|
.props()
|
|
213
|
-
.
|
|
213
|
+
.presentation
|
|
214
214
|
.get_drag_target()
|
|
215
215
|
.map(|x| V::is_self_move(x))
|
|
216
216
|
.unwrap_or_default();
|
|
@@ -63,6 +63,9 @@ pub struct ScrollPanelProps {
|
|
|
63
63
|
|
|
64
64
|
#[prop_or_default]
|
|
65
65
|
pub drop: Callback<DragEvent>,
|
|
66
|
+
|
|
67
|
+
#[prop_or_default]
|
|
68
|
+
pub omit_autosize_div: bool,
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
impl ScrollPanelProps {
|
|
@@ -146,16 +149,25 @@ impl Component for ScrollPanel {
|
|
|
146
149
|
self.viewport_width = 0.0;
|
|
147
150
|
self.calculate_window_content(ctx)
|
|
148
151
|
},
|
|
152
|
+
|
|
153
|
+
// TODO don't hardcode pixel offsets - fix the CSS container to not
|
|
154
|
+
// require pixel offsets to work.
|
|
149
155
|
ScrollPanelMsg::UpdateViewportDimensions => {
|
|
150
156
|
let viewport = self.viewport_elem(ctx);
|
|
151
157
|
let rect = viewport.get_bounding_client_rect();
|
|
152
158
|
let viewport_height = rect.height() - 8.0;
|
|
153
|
-
let
|
|
159
|
+
let scroll_offset = if ctx.props().omit_autosize_div {
|
|
160
|
+
0.0
|
|
161
|
+
} else {
|
|
162
|
+
6.0
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
let viewport_width = self.viewport_width.max(rect.width() - scroll_offset);
|
|
154
166
|
let re_render = self.viewport_height != viewport_height
|
|
155
167
|
|| self.viewport_width != viewport_width;
|
|
156
168
|
|
|
157
169
|
self.viewport_height = rect.height() - 8.0;
|
|
158
|
-
self.viewport_width = self.viewport_width.max(rect.width() -
|
|
170
|
+
self.viewport_width = self.viewport_width.max(rect.width() - scroll_offset);
|
|
159
171
|
ctx.props().on_auto_width.emit(self.viewport_width);
|
|
160
172
|
re_render
|
|
161
173
|
},
|
|
@@ -218,11 +230,13 @@ impl Component for ScrollPanel {
|
|
|
218
230
|
>
|
|
219
231
|
<div class="scroll-panel-container" style={window_style}>
|
|
220
232
|
{ for windowed_items.iter().cloned().map(Html::from) }
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
233
|
+
if !ctx.props().omit_autosize_div {
|
|
234
|
+
<div
|
|
235
|
+
key="__scroll-panel-auto-width__"
|
|
236
|
+
class="scroll-panel-auto-width"
|
|
237
|
+
style={width_style}
|
|
238
|
+
/>
|
|
239
|
+
}
|
|
226
240
|
</div>
|
|
227
241
|
<div class="scroll-panel-content" style={content_style} />
|
|
228
242
|
</div>
|
|
@@ -62,12 +62,14 @@ pub fn Sidebar(p: &SidebarProps) -> Html {
|
|
|
62
62
|
|
|
63
63
|
let width_style = format!("min-width: 200px; width: {}px", *auto_width);
|
|
64
64
|
html! {
|
|
65
|
-
|
|
65
|
+
<>
|
|
66
66
|
<SidebarCloseButton id={format!("{id}_close_button")} on_close_sidebar={&p.on_close} />
|
|
67
|
-
<div class="
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
<div class="sidebar_column" id={format!("{id}_sidebar")} ref={noderef}>
|
|
68
|
+
<div class="sidebar_header"><EditableHeader ..p.header_props.clone() /></div>
|
|
69
|
+
<div class="sidebar_border" id={format!("{id}_border")} />
|
|
70
|
+
{ p.children.iter().collect::<Html>() }
|
|
71
|
+
<div class="sidebar-auto-width" style={width_style} />
|
|
72
|
+
</div>
|
|
73
|
+
</>
|
|
72
74
|
}
|
|
73
75
|
}
|
|
@@ -20,7 +20,7 @@ use yew::html::Scope;
|
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
22
|
use crate::components::style::LocalStyle;
|
|
23
|
-
use crate::
|
|
23
|
+
use crate::css;
|
|
24
24
|
|
|
25
25
|
#[derive(Properties, Default)]
|
|
26
26
|
pub struct SplitPanelProps {
|
|
@@ -359,14 +359,14 @@ impl Drop for ResizingState {
|
|
|
359
359
|
/// `body`. Without this, the `Closure` objects would not leak, but the
|
|
360
360
|
/// document will continue to call them, causing runtime exceptions.
|
|
361
361
|
fn drop(&mut self) {
|
|
362
|
-
let result: ApiResult<()> =
|
|
362
|
+
let result: ApiResult<()> = (|| {
|
|
363
363
|
let mousemove = self.mousemove.as_ref().unchecked_ref();
|
|
364
364
|
global::body().remove_event_listener_with_callback("mousemove", mousemove)?;
|
|
365
365
|
let mouseup = self.mouseup.as_ref().unchecked_ref();
|
|
366
366
|
global::body().remove_event_listener_with_callback("mouseup", mouseup)?;
|
|
367
367
|
self.release_cursor()?;
|
|
368
368
|
Ok(())
|
|
369
|
-
};
|
|
369
|
+
})();
|
|
370
370
|
|
|
371
371
|
result.expect("Drop failed")
|
|
372
372
|
}
|
|
@@ -71,9 +71,9 @@ impl<T: ColumnTab> Component for TabList<T> {
|
|
|
71
71
|
fn view(&self, ctx: &yew::Context<Self>) -> Html {
|
|
72
72
|
let p = ctx.props();
|
|
73
73
|
let gutter_tabs = p.tabs.iter().enumerate().map(|(idx, tab)| {
|
|
74
|
-
let mut class = classes!("
|
|
74
|
+
let mut class = classes!("settings_tab");
|
|
75
75
|
if idx == self.selected_idx {
|
|
76
|
-
class.push("
|
|
76
|
+
class.push("selected_tab");
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
let onclick = ctx.link().callback(move |_| TabListMsg::SetSelected(idx));
|
|
@@ -88,13 +88,7 @@ impl<T: ColumnTab> Component for TabList<T> {
|
|
|
88
88
|
html! {
|
|
89
89
|
<>
|
|
90
90
|
<LocalStyle href={css!("containers/tabs")} />
|
|
91
|
-
<div
|
|
92
|
-
{ for gutter_tabs }
|
|
93
|
-
<span class="tab tab-padding">
|
|
94
|
-
<div class="tab-title">{ "\u{00a0}" }</div>
|
|
95
|
-
<div class="tab-border" />
|
|
96
|
-
</span>
|
|
97
|
-
</div>
|
|
91
|
+
<div id="settings_tab_bar">{ for gutter_tabs }</div>
|
|
98
92
|
<div id="format-tab" class="tab-content scrollable">
|
|
99
93
|
{ ctx.props().children.iter().nth(self.selected_idx) }
|
|
100
94
|
</div>
|
|
@@ -15,8 +15,8 @@ use std::rc::Rc;
|
|
|
15
15
|
use yew::prelude::*;
|
|
16
16
|
|
|
17
17
|
use super::containers::dropdown_menu::*;
|
|
18
|
+
use crate::config::*;
|
|
18
19
|
use crate::renderer::*;
|
|
19
|
-
use crate::tasks::*;
|
|
20
20
|
|
|
21
21
|
type CopyDropDownMenuItem = DropDownMenuItem<ExportFile>;
|
|
22
22
|
|
|
@@ -41,8 +41,7 @@ impl Component for CopyDropDownMenu {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
fn view(&self, ctx: &Context<Self>) -> yew::virtual_dom::VNode {
|
|
44
|
-
let
|
|
45
|
-
let is_chart = plugin.name().as_str() != "Datagrid";
|
|
44
|
+
let is_chart = ctx.props().renderer.is_chart();
|
|
46
45
|
let has_selection = ctx.props().renderer.get_selection().is_some();
|
|
47
46
|
html! {
|
|
48
47
|
<>
|
|
@@ -21,28 +21,30 @@ use perspective_js::json;
|
|
|
21
21
|
use perspective_js::utils::global::navigator;
|
|
22
22
|
use wasm_bindgen::prelude::*;
|
|
23
23
|
use yew::prelude::*;
|
|
24
|
-
use yew::*;
|
|
25
24
|
|
|
26
|
-
use super::form::color_selector::*;
|
|
27
25
|
use super::modal::{ModalLink, SetModalLink};
|
|
28
26
|
use super::style::LocalStyle;
|
|
29
27
|
use crate::components::datetime_column_style::custom::DatetimeStyleCustom;
|
|
30
28
|
use crate::components::datetime_column_style::simple::DatetimeStyleSimple;
|
|
31
|
-
use crate::components::form::select_enum_field::SelectEnumField;
|
|
32
29
|
use crate::components::form::select_value_field::SelectValueField;
|
|
33
30
|
use crate::config::*;
|
|
34
31
|
use crate::css;
|
|
35
32
|
use crate::utils::WeakScope;
|
|
36
33
|
|
|
34
|
+
/// Format-only widget for `datetime` columns. Renders the `date_format`
|
|
35
|
+
/// hierarchy (Simple|Custom + timezone); color/color-mode UI is provided
|
|
36
|
+
/// externally as primitive `Enum` + `Color` schema fields.
|
|
37
37
|
#[derive(Properties, Derivative)]
|
|
38
38
|
#[derivative(Debug)]
|
|
39
39
|
pub struct DatetimeColumnStyleProps {
|
|
40
40
|
pub enable_time_config: bool,
|
|
41
41
|
pub config: Option<DatetimeColumnStyleConfig>,
|
|
42
|
-
pub default_config: DatetimeColumnStyleDefaultConfig,
|
|
43
42
|
|
|
44
43
|
#[prop_or_default]
|
|
45
|
-
pub on_change: Callback<
|
|
44
|
+
pub on_change: Callback<ColumnConfigFieldUpdate>,
|
|
45
|
+
|
|
46
|
+
#[prop_or_default]
|
|
47
|
+
pub keys: Vec<String>,
|
|
46
48
|
|
|
47
49
|
#[prop_or_default]
|
|
48
50
|
#[derivative(Debug = "ignore")]
|
|
@@ -57,9 +59,7 @@ impl ModalLink<DatetimeColumnStyle> for DatetimeColumnStyleProps {
|
|
|
57
59
|
|
|
58
60
|
impl PartialEq for DatetimeColumnStyleProps {
|
|
59
61
|
fn eq(&self, other: &Self) -> bool {
|
|
60
|
-
self.enable_time_config == other.enable_time_config
|
|
61
|
-
&& self.config == other.config
|
|
62
|
-
&& self.default_config == other.default_config
|
|
62
|
+
self.enable_time_config == other.enable_time_config && self.config == other.config
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -67,16 +67,11 @@ pub enum DatetimeColumnStyleMsg {
|
|
|
67
67
|
SimpleDatetimeStyleConfigChanged(SimpleDatetimeStyleConfig),
|
|
68
68
|
CustomDatetimeStyleConfigChanged(CustomDatetimeStyleConfig),
|
|
69
69
|
TimezoneChanged(Option<String>),
|
|
70
|
-
ColorModeChanged(Option<DatetimeColorMode>),
|
|
71
|
-
ColorChanged(String),
|
|
72
|
-
ColorReset,
|
|
73
70
|
}
|
|
74
71
|
|
|
75
|
-
/// Column style controls for the `datetime` type.
|
|
76
72
|
#[derive(Debug)]
|
|
77
73
|
pub struct DatetimeColumnStyle {
|
|
78
74
|
config: DatetimeColumnStyleConfig,
|
|
79
|
-
default_config: DatetimeColumnStyleDefaultConfig,
|
|
80
75
|
}
|
|
81
76
|
|
|
82
77
|
impl Component for DatetimeColumnStyle {
|
|
@@ -87,11 +82,9 @@ impl Component for DatetimeColumnStyle {
|
|
|
87
82
|
ctx.set_modal_link();
|
|
88
83
|
Self {
|
|
89
84
|
config: ctx.props().config.clone().unwrap_or_default(),
|
|
90
|
-
default_config: ctx.props().default_config.clone(),
|
|
91
85
|
}
|
|
92
86
|
}
|
|
93
87
|
|
|
94
|
-
// Always re-render when config changes.
|
|
95
88
|
fn changed(&mut self, ctx: &Context<Self>, old: &Self::Properties) -> bool {
|
|
96
89
|
let mut rerender = false;
|
|
97
90
|
let mut new_config = ctx.props().config.clone().unwrap_or_default();
|
|
@@ -105,7 +98,6 @@ impl Component for DatetimeColumnStyle {
|
|
|
105
98
|
rerender
|
|
106
99
|
}
|
|
107
100
|
|
|
108
|
-
// TODO could be more conservative here with re-rendering
|
|
109
101
|
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
110
102
|
match msg {
|
|
111
103
|
DatetimeColumnStyleMsg::TimezoneChanged(val) => {
|
|
@@ -118,17 +110,6 @@ impl Component for DatetimeColumnStyle {
|
|
|
118
110
|
self.dispatch_config(ctx);
|
|
119
111
|
true
|
|
120
112
|
},
|
|
121
|
-
DatetimeColumnStyleMsg::ColorModeChanged(mode) => {
|
|
122
|
-
self.config.datetime_color_mode = mode.unwrap_or_default();
|
|
123
|
-
self.dispatch_config(ctx);
|
|
124
|
-
true
|
|
125
|
-
},
|
|
126
|
-
DatetimeColumnStyleMsg::ColorChanged(color) => {
|
|
127
|
-
self.config.color = Some(color);
|
|
128
|
-
self.dispatch_config(ctx);
|
|
129
|
-
true
|
|
130
|
-
},
|
|
131
|
-
|
|
132
113
|
DatetimeColumnStyleMsg::SimpleDatetimeStyleConfigChanged(simple) => {
|
|
133
114
|
self.config.date_format = DatetimeFormatType::Simple(simple);
|
|
134
115
|
self.dispatch_config(ctx);
|
|
@@ -139,40 +120,14 @@ impl Component for DatetimeColumnStyle {
|
|
|
139
120
|
self.dispatch_config(ctx);
|
|
140
121
|
true
|
|
141
122
|
},
|
|
142
|
-
DatetimeColumnStyleMsg::ColorReset => {
|
|
143
|
-
self.config.color = Some(self.default_config.color.clone());
|
|
144
|
-
self.dispatch_config(ctx);
|
|
145
|
-
true
|
|
146
|
-
},
|
|
147
123
|
}
|
|
148
124
|
}
|
|
149
125
|
|
|
150
126
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
151
|
-
let selected_color_mode = self.config.datetime_color_mode;
|
|
152
|
-
let color_mode_changed = ctx
|
|
153
|
-
.link()
|
|
154
|
-
.callback(DatetimeColumnStyleMsg::ColorModeChanged);
|
|
155
|
-
|
|
156
|
-
let color_controls = match selected_color_mode {
|
|
157
|
-
DatetimeColorMode::None => html! {},
|
|
158
|
-
DatetimeColorMode::Foreground => {
|
|
159
|
-
self.color_select_row(ctx, &DatetimeColorMode::Foreground, "foreground-label")
|
|
160
|
-
},
|
|
161
|
-
DatetimeColorMode::Background => {
|
|
162
|
-
self.color_select_row(ctx, &DatetimeColorMode::Background, "background-label")
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
|
|
166
127
|
html! {
|
|
167
128
|
<>
|
|
168
129
|
<LocalStyle href={css!("column-style")} />
|
|
169
130
|
<div id="column-style-container" class="datetime-column-style-container">
|
|
170
|
-
<SelectEnumField<DatetimeColorMode>
|
|
171
|
-
label="color"
|
|
172
|
-
on_change={color_mode_changed}
|
|
173
|
-
current_value={selected_color_mode}
|
|
174
|
-
/>
|
|
175
|
-
{ color_controls }
|
|
176
131
|
if ctx.props().enable_time_config {
|
|
177
132
|
<SelectValueField<String>
|
|
178
133
|
label="timezone"
|
|
@@ -251,35 +206,18 @@ static USER_TIMEZONE: LazyLock<String> = LazyLock::new(|| {
|
|
|
251
206
|
impl DatetimeColumnStyle {
|
|
252
207
|
/// When this config has changed, we must signal the wrapper element.
|
|
253
208
|
fn dispatch_config(&self, ctx: &Context<Self>) {
|
|
254
|
-
let
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
/// variant.
|
|
263
|
-
fn color_select_row(&self, ctx: &Context<Self>, mode: &DatetimeColorMode, title: &str) -> Html {
|
|
264
|
-
let on_color = ctx.link().callback(DatetimeColumnStyleMsg::ColorChanged);
|
|
265
|
-
let color = self
|
|
266
|
-
.config
|
|
267
|
-
.color
|
|
268
|
-
.clone()
|
|
269
|
-
.unwrap_or_else(|| self.default_config.color.to_owned());
|
|
209
|
+
let value = if self.config == DatetimeColumnStyleConfig::default() {
|
|
210
|
+
serde_json::Map::new()
|
|
211
|
+
} else {
|
|
212
|
+
match serde_json::to_value(&self.config) {
|
|
213
|
+
Ok(serde_json::Value::Object(m)) => m,
|
|
214
|
+
_ => serde_json::Map::new(),
|
|
215
|
+
}
|
|
216
|
+
};
|
|
270
217
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
is_modified: color != self.default_config.color,
|
|
275
|
-
color,
|
|
276
|
-
on_reset: ctx.link().callback(|_| DatetimeColumnStyleMsg::ColorReset)
|
|
218
|
+
ctx.props().on_change.emit(ColumnConfigFieldUpdate {
|
|
219
|
+
keys: ctx.props().keys.clone(),
|
|
220
|
+
value,
|
|
277
221
|
});
|
|
278
|
-
|
|
279
|
-
if &self.config.datetime_color_mode == mode {
|
|
280
|
-
html! { <div class="row"><ColorSelector ..color_props /></div> }
|
|
281
|
-
} else {
|
|
282
|
-
html! {}
|
|
283
|
-
}
|
|
284
222
|
}
|
|
285
223
|
}
|
|
@@ -18,7 +18,6 @@ use yew::{Callback, Component, Html, NodeRef, Properties, TargetCast, classes, h
|
|
|
18
18
|
|
|
19
19
|
use super::type_icon::TypeIconType;
|
|
20
20
|
use crate::components::type_icon::TypeIcon;
|
|
21
|
-
use crate::maybe;
|
|
22
21
|
use crate::session::{Session, SessionMetadataRc};
|
|
23
22
|
|
|
24
23
|
#[derive(Clone, PartialEq, Properties)]
|
|
@@ -103,7 +102,7 @@ impl Component for EditableHeader {
|
|
|
103
102
|
let maybe_value = (!new_value.is_empty()).then_some(new_value.clone());
|
|
104
103
|
self.edited = ctx.props().initial_value != maybe_value;
|
|
105
104
|
|
|
106
|
-
self.valid =
|
|
105
|
+
self.valid = (|| -> Option<bool> {
|
|
107
106
|
if maybe_value
|
|
108
107
|
.as_ref()
|
|
109
108
|
.map(|v| v == &self.placeholder)
|
|
@@ -122,7 +121,7 @@ impl Component for EditableHeader {
|
|
|
122
121
|
.chain(expressions)
|
|
123
122
|
.contains(&new_value);
|
|
124
123
|
Some(!found)
|
|
125
|
-
})
|
|
124
|
+
})()
|
|
126
125
|
.unwrap_or(true);
|
|
127
126
|
|
|
128
127
|
self.value.clone_from(&maybe_value);
|
|
@@ -15,9 +15,9 @@ use std::rc::Rc;
|
|
|
15
15
|
use yew::prelude::*;
|
|
16
16
|
|
|
17
17
|
use super::containers::dropdown_menu::*;
|
|
18
|
+
use crate::config::*;
|
|
18
19
|
use crate::renderer::*;
|
|
19
20
|
use crate::session::Session;
|
|
20
|
-
use crate::tasks::*;
|
|
21
21
|
|
|
22
22
|
pub type ExportDropDownMenuItem = DropDownMenuItem<ExportFile>;
|
|
23
23
|
|
|
@@ -45,8 +45,7 @@ impl Component for ExportDropDownMenu {
|
|
|
45
45
|
|
|
46
46
|
fn view(&self, ctx: &Context<Self>) -> yew::virtual_dom::VNode {
|
|
47
47
|
let callback = ctx.link().callback(|_| ExportDropDownMenuMsg::TitleChange);
|
|
48
|
-
let
|
|
49
|
-
let is_chart = plugin.name().as_str() != "Datagrid";
|
|
48
|
+
let is_chart = ctx.props().renderer.is_chart();
|
|
50
49
|
html! {
|
|
51
50
|
<>
|
|
52
51
|
<span class="dropdown-group-label">{ "Save as" }</span>
|