@perspective-dev/viewer 4.4.0 → 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 -0
- package/dist/css/pro-dark.css +1 -1
- package/dist/css/pro.css +1 -1
- package/dist/css/solarized-dark.css +1 -1
- package/dist/css/solarized.css +1 -1
- package/dist/css/themes.css +1 -1
- package/dist/css/vaporwave.css +1 -1
- package/dist/esm/bootstrap.d.ts +2 -1
- package/dist/esm/column-format.d.ts +51 -0
- package/dist/esm/extensions.d.ts +6 -0
- package/dist/esm/perspective-viewer.d.ts +4 -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 +21 -77
- 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 +39 -0
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +7 -4
- package/dist/wasm/perspective-viewer.d.ts +88 -24
- package/dist/wasm/perspective-viewer.js +320 -151
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +22 -17
- package/package.json +24 -2
- package/src/css/column-selector.css +3 -2
- package/src/css/column-settings-panel.css +36 -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/status-bar.css +1 -1
- 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 -132
- 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 +7 -8
- package/src/rust/custom_elements/copy_dropdown.rs +30 -18
- package/src/rust/custom_elements/debug_plugin.rs +5 -7
- package/src/rust/custom_elements/export_dropdown.rs +26 -18
- package/src/rust/custom_elements/viewer.rs +77 -77
- package/src/rust/custom_events.rs +181 -224
- package/src/rust/js/plugin.rs +45 -117
- package/src/rust/lib.rs +39 -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 +649 -55
- 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 -89
- 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/datagrid-select-row-tree.svg +13 -0
- 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 +42 -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 +4 -18
- 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 +175 -0
- 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/themes.css +1 -0
- 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 +12 -1
- package/src/ts/perspective-viewer.ts +10 -1
- package/src/{rust/components/column_settings_sidebar/style_tab/stub.rs → ts/perspective-viewer.worker.ts} +2 -22
- package/src/ts/plugin.ts +29 -105
- 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 +14 -0
- 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 -483
- package/src/rust/config/number_column_style.rs +0 -132
- 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-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → perspective-viewer-39ab7da3ca157861}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-68fef752754ffbc6 → 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
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
use std::collections::HashSet;
|
|
14
|
+
|
|
15
|
+
use serde::{Deserialize, Serialize};
|
|
16
|
+
use serde_json::Value;
|
|
17
|
+
|
|
18
|
+
use super::{KeyValueOpts, NumberSeriesStyleDefaultConfig};
|
|
19
|
+
|
|
20
|
+
/// The full schema for one column at one point in time. Plugins may return
|
|
21
|
+
/// different schemas for the same column based on the column's current
|
|
22
|
+
/// stored value (e.g. to hide dependent fields), so this is re-queried on
|
|
23
|
+
/// every field update.
|
|
24
|
+
///
|
|
25
|
+
/// Each entry is a [`ControlSpec`]. Primitive variants carry their own
|
|
26
|
+
/// `key` (JSON storage key) inline; the sidebar UI label is supplied by
|
|
27
|
+
/// CSS via `--psp-label--<key>--content`. Composite variants render a
|
|
28
|
+
/// self-contained Yew component that supplies its own labels and owns a
|
|
29
|
+
/// fixed key namespace via [`ControlSpec::serialized_keys`].
|
|
30
|
+
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
31
|
+
pub struct ColumnConfigSchema {
|
|
32
|
+
pub fields: Vec<ControlSpec>,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
impl ColumnConfigSchema {
|
|
36
|
+
/// Union of every JSON key any control in this schema knows how to
|
|
37
|
+
/// read or write. Used to build the schema-filtered view of
|
|
38
|
+
/// `columns_config` passed to `plugin.restore()` — keys not in this
|
|
39
|
+
/// set are "ghost" state from a different plugin and stay invisible
|
|
40
|
+
/// to the active one.
|
|
41
|
+
pub fn active_keys(&self) -> HashSet<String> {
|
|
42
|
+
let mut out = HashSet::new();
|
|
43
|
+
for spec in &self.fields {
|
|
44
|
+
for k in spec.serialized_keys() {
|
|
45
|
+
out.insert(k.to_string());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
out
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// Discriminated union of widget kinds the viewer can render. Composite
|
|
53
|
+
/// variants wrap an existing rich Yew component and carry only the
|
|
54
|
+
/// component's `*DefaultConfig`. Primitive variants render generic scalar
|
|
55
|
+
/// widgets and carry their own `key` inline; the visible label is
|
|
56
|
+
/// resolved at CSS time via `--psp-label--<key>--content`.
|
|
57
|
+
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
58
|
+
#[serde(tag = "kind")]
|
|
59
|
+
pub enum ControlSpec {
|
|
60
|
+
Enum {
|
|
61
|
+
key: String,
|
|
62
|
+
variants: Vec<EnumVariant>,
|
|
63
|
+
default: String,
|
|
64
|
+
},
|
|
65
|
+
Bool {
|
|
66
|
+
key: String,
|
|
67
|
+
default: bool,
|
|
68
|
+
},
|
|
69
|
+
Number {
|
|
70
|
+
key: String,
|
|
71
|
+
default: f64,
|
|
72
|
+
|
|
73
|
+
/// If `true`, always serialize this values even if it is the default.
|
|
74
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
75
|
+
include: Option<bool>,
|
|
76
|
+
|
|
77
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
78
|
+
min: Option<f64>,
|
|
79
|
+
|
|
80
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
81
|
+
max: Option<f64>,
|
|
82
|
+
|
|
83
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
84
|
+
step: Option<f64>,
|
|
85
|
+
},
|
|
86
|
+
String {
|
|
87
|
+
key: String,
|
|
88
|
+
default: String,
|
|
89
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
90
|
+
placeholder: Option<String>,
|
|
91
|
+
},
|
|
92
|
+
Color {
|
|
93
|
+
key: String,
|
|
94
|
+
default: String,
|
|
95
|
+
},
|
|
96
|
+
/// Paired pos/neg color picker rendered as a single horizontal
|
|
97
|
+
/// gradient/range bar. Used to expose the existing
|
|
98
|
+
/// [`crate::components::form::color_range_selector::ColorRangeSelector`]
|
|
99
|
+
/// widget at primitive granularity. Owns two top-level keys
|
|
100
|
+
/// (`key_pos` + `key_neg`); the visible label is derived from
|
|
101
|
+
/// `key_pos`.
|
|
102
|
+
ColorRange {
|
|
103
|
+
key_pos: String,
|
|
104
|
+
key_neg: String,
|
|
105
|
+
default_pos: String,
|
|
106
|
+
default_neg: String,
|
|
107
|
+
/// When `true`, the bar renders as a continuous gradient
|
|
108
|
+
/// (e.g. for `gradient` color modes); when `false`, the bar
|
|
109
|
+
/// renders as a hard pos/neg split. Currently only changes the
|
|
110
|
+
/// visual; pos/neg semantics are unchanged.
|
|
111
|
+
#[serde(default)]
|
|
112
|
+
is_gradient: bool,
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
/// Residual format-only widget for datetime columns — owns
|
|
116
|
+
/// `date_format` only. Pair with primitive `Enum` and `Color` fields
|
|
117
|
+
/// for `datetime_color_mode` + `color` to fully decompose datetime
|
|
118
|
+
/// styling.
|
|
119
|
+
DatetimeFormat,
|
|
120
|
+
/// Residual format-only widget for string columns — owns `format`
|
|
121
|
+
/// only. Pair with primitive `Enum` and `Color` fields for
|
|
122
|
+
/// `string_color_mode` + `color` to fully decompose string styling.
|
|
123
|
+
StringFormat,
|
|
124
|
+
NumberSeriesStyle {
|
|
125
|
+
default: NumberSeriesStyleDefaultConfig,
|
|
126
|
+
},
|
|
127
|
+
Symbols {
|
|
128
|
+
default: KeyValueOpts,
|
|
129
|
+
},
|
|
130
|
+
NumberFormat,
|
|
131
|
+
AggregateDepth,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
|
135
|
+
pub struct EnumVariant {
|
|
136
|
+
pub value: String,
|
|
137
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
138
|
+
pub label: Option<String>,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
impl ControlSpec {
|
|
142
|
+
/// Top-level JSON keys this control owns when its value is serialized
|
|
143
|
+
/// into a column's config map. For primitives this is just `[key]`;
|
|
144
|
+
/// for composites it's the set of fields the wrapped sub-struct
|
|
145
|
+
/// flattens. Used by [`ColumnConfigSchema::active_keys`] to filter the
|
|
146
|
+
/// `columns_config` blob passed to `plugin.restore()`.
|
|
147
|
+
pub fn serialized_keys(&self) -> Vec<&str> {
|
|
148
|
+
match self {
|
|
149
|
+
ControlSpec::DatetimeFormat => vec!["date_format"],
|
|
150
|
+
ControlSpec::StringFormat => vec!["format"],
|
|
151
|
+
ControlSpec::NumberSeriesStyle { .. } => vec!["chart_type", "stack"],
|
|
152
|
+
ControlSpec::Symbols { .. } => vec!["symbols"],
|
|
153
|
+
ControlSpec::NumberFormat => vec!["number_format"],
|
|
154
|
+
ControlSpec::AggregateDepth => vec!["aggregate_depth"],
|
|
155
|
+
ControlSpec::ColorRange {
|
|
156
|
+
key_pos, key_neg, ..
|
|
157
|
+
} => vec![key_pos.as_str(), key_neg.as_str()],
|
|
158
|
+
ControlSpec::Enum { key, .. }
|
|
159
|
+
| ControlSpec::Bool { key, .. }
|
|
160
|
+
| ControlSpec::Number { key, .. }
|
|
161
|
+
| ControlSpec::String { key, .. }
|
|
162
|
+
| ControlSpec::Color { key, .. } => vec![key.as_str()],
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/// One UI-emitted change to a single schema field. The emitting widget
|
|
168
|
+
/// declares which top-level keys the update is allowed to write
|
|
169
|
+
/// (`keys` — equivalent to the field's [`ControlSpec::serialized_keys`])
|
|
170
|
+
/// and a partial new sub-state (`value`).
|
|
171
|
+
///
|
|
172
|
+
/// Apply semantics: keys in `keys` are *cleared* from the column's config
|
|
173
|
+
/// map, then keys present in `value` are *inserted*. Defaults are
|
|
174
|
+
/// pre-stripped by the caller (typically via `skip_serializing_if`), so
|
|
175
|
+
/// "no value set for key K" means the schema default applies and K is
|
|
176
|
+
/// not serialized.
|
|
177
|
+
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
178
|
+
pub struct ColumnConfigFieldUpdate {
|
|
179
|
+
pub keys: Vec<String>,
|
|
180
|
+
pub value: serde_json::Map<String, Value>,
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/// Filter a per-column config map to only the keys advertised by the
|
|
184
|
+
/// active plugin's schema. Foreign keys (left over from a previous plugin)
|
|
185
|
+
/// stay in the unfiltered presentation state but never reach `restore()`.
|
|
186
|
+
pub fn filter_to_schema(
|
|
187
|
+
config: &serde_json::Map<String, Value>,
|
|
188
|
+
active_keys: &HashSet<String>,
|
|
189
|
+
) -> serde_json::Map<String, Value> {
|
|
190
|
+
config
|
|
191
|
+
.iter()
|
|
192
|
+
.filter(|(k, _)| active_keys.contains(k.as_str()))
|
|
193
|
+
.map(|(k, v)| (k.clone(), v.clone()))
|
|
194
|
+
.collect()
|
|
195
|
+
}
|
|
@@ -10,105 +10,12 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
//! Auxiliary types used by `ColumnConfigSchema`'s composite control
|
|
14
|
+
//! variants. Per-column persisted state itself is opaque
|
|
15
|
+
//! `serde_json::Map<String, serde_json::Value>`; see
|
|
16
|
+
//! [`crate::presentation::ColumnConfigMap`].
|
|
14
17
|
|
|
15
18
|
use serde::{Deserialize, Serialize};
|
|
16
|
-
use ts_rs::TS;
|
|
17
|
-
|
|
18
|
-
use super::{
|
|
19
|
-
CustomNumberFormatConfig, DatetimeColumnStyleConfig, DatetimeColumnStyleDefaultConfig,
|
|
20
|
-
NumberColumnStyleConfig, NumberColumnStyleDefaultConfig, StringColumnStyleConfig,
|
|
21
|
-
StringColumnStyleDefaultConfig,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
fn is_zero(x: &u32) -> bool {
|
|
25
|
-
x == &0
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/// The value de/serialized and stored in the viewer config.
|
|
29
|
-
/// Also passed to the plugin via `plugin.save()`.
|
|
30
|
-
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize, TS)]
|
|
31
|
-
pub struct ColumnConfigValues {
|
|
32
|
-
#[serde(default)]
|
|
33
|
-
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
|
34
|
-
pub symbols: HashMap<String, String>,
|
|
35
|
-
|
|
36
|
-
#[serde(flatten)]
|
|
37
|
-
pub datagrid_number_style: NumberColumnStyleConfig,
|
|
38
|
-
|
|
39
|
-
#[serde(flatten)]
|
|
40
|
-
pub datagrid_string_style: StringColumnStyleConfig,
|
|
41
|
-
|
|
42
|
-
#[serde(flatten)]
|
|
43
|
-
pub datagrid_datetime_style: DatetimeColumnStyleConfig,
|
|
44
|
-
|
|
45
|
-
#[serde(default)]
|
|
46
|
-
#[serde(skip_serializing_if = "Option::is_none")]
|
|
47
|
-
pub number_format: Option<CustomNumberFormatConfig>,
|
|
48
|
-
|
|
49
|
-
#[serde(default)]
|
|
50
|
-
#[serde(skip_serializing_if = "is_zero")]
|
|
51
|
-
pub aggregate_depth: u32,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
#[derive(Debug)]
|
|
55
|
-
pub enum ColumnConfigValueUpdate {
|
|
56
|
-
DatagridNumberStyle(Option<NumberColumnStyleConfig>),
|
|
57
|
-
DatagridStringStyle(Option<StringColumnStyleConfig>),
|
|
58
|
-
DatagridDatetimeStyle(Option<DatetimeColumnStyleConfig>),
|
|
59
|
-
Symbols(Option<HashMap<String, String>>),
|
|
60
|
-
CustomNumberStringFormat(Option<CustomNumberFormatConfig>),
|
|
61
|
-
AggregateDepth(u32),
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
impl ColumnConfigValues {
|
|
65
|
-
pub fn update(self, update: ColumnConfigValueUpdate) -> Self {
|
|
66
|
-
match update {
|
|
67
|
-
ColumnConfigValueUpdate::DatagridNumberStyle(update) => Self {
|
|
68
|
-
datagrid_number_style: update.unwrap_or_default(),
|
|
69
|
-
..self
|
|
70
|
-
},
|
|
71
|
-
ColumnConfigValueUpdate::DatagridStringStyle(update) => Self {
|
|
72
|
-
datagrid_string_style: update.unwrap_or_default(),
|
|
73
|
-
..self
|
|
74
|
-
},
|
|
75
|
-
ColumnConfigValueUpdate::DatagridDatetimeStyle(update) => Self {
|
|
76
|
-
datagrid_datetime_style: update.unwrap_or_default(),
|
|
77
|
-
..self
|
|
78
|
-
},
|
|
79
|
-
ColumnConfigValueUpdate::Symbols(update) => Self {
|
|
80
|
-
symbols: update.unwrap_or_default(),
|
|
81
|
-
..self
|
|
82
|
-
},
|
|
83
|
-
ColumnConfigValueUpdate::CustomNumberStringFormat(update) => Self {
|
|
84
|
-
number_format: update.filter(|x| x != &CustomNumberFormatConfig::default()),
|
|
85
|
-
..self
|
|
86
|
-
},
|
|
87
|
-
ColumnConfigValueUpdate::AggregateDepth(aggregate_depth) => Self {
|
|
88
|
-
aggregate_depth,
|
|
89
|
-
..self
|
|
90
|
-
},
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
pub fn is_empty(&self) -> bool {
|
|
95
|
-
self == &Self::default()
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/// The controls returned by plugin.column_style_controls.
|
|
100
|
-
///
|
|
101
|
-
/// This is a way to fill out default values for the given controls.
|
|
102
|
-
/// If a control is not given, it will not be rendered. I would like to
|
|
103
|
-
/// eventually show these as inactive values.
|
|
104
|
-
#[derive(Serialize, Deserialize, PartialEq, Debug, Default)]
|
|
105
|
-
pub struct ColumnStyleOpts {
|
|
106
|
-
pub datagrid_number_style: Option<NumberColumnStyleDefaultConfig>,
|
|
107
|
-
pub datagrid_string_style: Option<StringColumnStyleDefaultConfig>,
|
|
108
|
-
pub datagrid_datetime_style: Option<DatetimeColumnStyleDefaultConfig>,
|
|
109
|
-
pub symbols: Option<KeyValueOpts>,
|
|
110
|
-
pub number_string_format: Option<bool>,
|
|
111
|
-
}
|
|
112
19
|
|
|
113
20
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)]
|
|
114
21
|
#[serde(rename_all = "snake_case")]
|
package/src/rust/config/mod.rs
CHANGED
|
@@ -13,19 +13,25 @@
|
|
|
13
13
|
//! A collection of (de-)serializable structs which capture the application
|
|
14
14
|
//! state, suitable for persistence, history, etc. features.
|
|
15
15
|
|
|
16
|
+
mod column_config_schema;
|
|
16
17
|
mod columns_config;
|
|
17
18
|
mod datetime_column_style;
|
|
19
|
+
mod export_method;
|
|
18
20
|
mod kvpair;
|
|
19
|
-
mod
|
|
21
|
+
mod number_series_style;
|
|
20
22
|
mod number_string_format;
|
|
23
|
+
mod plugin_static_config;
|
|
21
24
|
mod string_column_style;
|
|
22
25
|
pub mod view_config;
|
|
23
26
|
mod viewer_config;
|
|
24
27
|
|
|
28
|
+
pub use column_config_schema::*;
|
|
25
29
|
pub use columns_config::*;
|
|
26
30
|
pub use datetime_column_style::*;
|
|
27
|
-
pub use
|
|
31
|
+
pub use export_method::*;
|
|
32
|
+
pub use number_series_style::*;
|
|
28
33
|
pub use number_string_format::*;
|
|
34
|
+
pub use plugin_static_config::*;
|
|
29
35
|
pub use string_column_style::*;
|
|
30
36
|
pub use view_config::*;
|
|
31
37
|
pub use viewer_config::*;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
use serde::{Deserialize, Serialize};
|
|
14
|
+
use strum::{Display, EnumIter};
|
|
15
|
+
use ts_rs::TS;
|
|
16
|
+
|
|
17
|
+
/// Render glyph for a numeric aggregate in the Y Bar plugin. Serialized as
|
|
18
|
+
/// a lowercase string to match the plugin's runtime lookup (which does a
|
|
19
|
+
/// case-insensitive `chart_type` match against the same literal set).
|
|
20
|
+
#[derive(
|
|
21
|
+
Clone, Copy, Debug, Default, Deserialize, Display, EnumIter, Eq, PartialEq, Serialize, TS,
|
|
22
|
+
)]
|
|
23
|
+
pub enum ChartType {
|
|
24
|
+
#[default]
|
|
25
|
+
#[serde(rename = "bar")]
|
|
26
|
+
Bar,
|
|
27
|
+
|
|
28
|
+
#[serde(rename = "line")]
|
|
29
|
+
Line,
|
|
30
|
+
|
|
31
|
+
#[serde(rename = "scatter")]
|
|
32
|
+
Scatter,
|
|
33
|
+
|
|
34
|
+
#[serde(rename = "area")]
|
|
35
|
+
Area,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
impl ChartType {
|
|
39
|
+
pub fn is_default(&self) -> bool {
|
|
40
|
+
*self == Self::Bar
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// Glyphs for which `stack` is a meaningful option. Line/Scatter never
|
|
44
|
+
/// stack; Bar/Area stack by default but can be opted out per column.
|
|
45
|
+
pub fn supports_stack(&self) -> bool {
|
|
46
|
+
matches!(self, Self::Bar | Self::Area)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Per-column render-style config for numeric aggregates in series charts
|
|
51
|
+
/// (currently Y Bar). Stored flat in the column's
|
|
52
|
+
/// `serde_json::Map<String, serde_json::Value>`, so the JSON shape at the
|
|
53
|
+
/// viewer boundary is `{ "chart_type": "line", "stack": false }`.
|
|
54
|
+
///
|
|
55
|
+
/// Default `Bar` + `None` stack serializes as an empty object so plugins
|
|
56
|
+
/// that never touch these fields don't pay any JSON overhead.
|
|
57
|
+
#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, TS)]
|
|
58
|
+
pub struct NumberSeriesStyleConfig {
|
|
59
|
+
#[serde(default)]
|
|
60
|
+
#[serde(skip_serializing_if = "ChartType::is_default")]
|
|
61
|
+
pub chart_type: ChartType,
|
|
62
|
+
|
|
63
|
+
/// Stack override. `None` means "use the glyph default"
|
|
64
|
+
/// (Bar/Area stack, Line/Scatter don't). `Some(false)` on a Bar/Area
|
|
65
|
+
/// forces non-stacking.
|
|
66
|
+
#[serde(default)]
|
|
67
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
68
|
+
pub stack: Option<bool>,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// Defaults-only shape carried by `ControlSpec::NumberSeriesStyle`. The
|
|
72
|
+
/// presence of this control in a plugin's `column_config_schema` is the
|
|
73
|
+
/// signal for the sidebar to render the chart-type picker.
|
|
74
|
+
#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)]
|
|
75
|
+
pub struct NumberSeriesStyleDefaultConfig {
|
|
76
|
+
pub chart_type: ChartType,
|
|
77
|
+
#[serde(default)]
|
|
78
|
+
pub stack: Option<bool>,
|
|
79
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
use perspective_client::config::GroupRollupMode;
|
|
14
|
+
use serde::Deserialize;
|
|
15
|
+
use ts_rs::TS;
|
|
16
|
+
|
|
17
|
+
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, TS)]
|
|
18
|
+
#[serde(rename_all = "camelCase")]
|
|
19
|
+
pub enum ColumnSelectMode {
|
|
20
|
+
#[default]
|
|
21
|
+
Toggle,
|
|
22
|
+
Select,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
impl ColumnSelectMode {
|
|
26
|
+
pub fn css(&self) -> yew::Classes {
|
|
27
|
+
match self {
|
|
28
|
+
Self::Toggle => yew::classes!("toggle-mode", "is_column_active"),
|
|
29
|
+
Self::Select => yew::classes!("select-mode", "is_column_active"),
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// Static, immutable configuration for a plugin.
|
|
35
|
+
///
|
|
36
|
+
/// Returned once per plugin from `get_static_config()` at registration
|
|
37
|
+
/// time and cached in [`crate::renderer::PluginRecord`]. Consumers
|
|
38
|
+
/// (renderer, session, queries, components) read these fields off the
|
|
39
|
+
/// renderer's active-plugin metadata rather than calling back into JS.
|
|
40
|
+
///
|
|
41
|
+
/// `<perspective-viewer>` reads this exactly once per plugin (at
|
|
42
|
+
/// `registerPlugin` time) and caches it for the lifetime of the
|
|
43
|
+
/// application. The result must be stable; do not mutate any field
|
|
44
|
+
/// after registration.
|
|
45
|
+
#[derive(Clone, Debug, Default, Deserialize, PartialEq, TS)]
|
|
46
|
+
pub struct PluginStaticConfig {
|
|
47
|
+
/// The unique key for this plugin. Used as the `plugin` field in a
|
|
48
|
+
/// `ViewerConfig` and as the display name key in the
|
|
49
|
+
/// `<perspective-viewer>` UI.
|
|
50
|
+
pub name: String,
|
|
51
|
+
|
|
52
|
+
/// Category in the plugin picker menu.
|
|
53
|
+
#[serde(default)]
|
|
54
|
+
#[ts(as = "Option<_>")]
|
|
55
|
+
#[ts(optional)]
|
|
56
|
+
pub category: Option<String>,
|
|
57
|
+
|
|
58
|
+
/// Soft limit on the number of columns the plugin will render.
|
|
59
|
+
/// Triggers the "Rendering N of M" warning when the view exceeds
|
|
60
|
+
/// this value (until dismissed).
|
|
61
|
+
#[serde(default)]
|
|
62
|
+
#[ts(as = "Option<_>")]
|
|
63
|
+
#[ts(optional)]
|
|
64
|
+
pub max_columns: Option<usize>,
|
|
65
|
+
|
|
66
|
+
/// Soft limit on the number of cells (rows × columns) the plugin
|
|
67
|
+
/// will render. Triggers the "Rendering N of M" warning when the view
|
|
68
|
+
/// exceeds this value (until dismissed).
|
|
69
|
+
#[serde(default)]
|
|
70
|
+
#[ts(as = "Option<_>")]
|
|
71
|
+
#[ts(optional)]
|
|
72
|
+
pub max_cells: Option<usize>,
|
|
73
|
+
|
|
74
|
+
/// Column add/remove behavior. `"select"` exclusively selects the
|
|
75
|
+
/// added column, removing other columns. `"toggle"` toggles the
|
|
76
|
+
/// column on or off based on its current state, leaving other
|
|
77
|
+
/// columns alone.
|
|
78
|
+
#[serde(default)]
|
|
79
|
+
#[ts(as = "Option<_>")]
|
|
80
|
+
#[ts(optional)]
|
|
81
|
+
pub select_mode: ColumnSelectMode,
|
|
82
|
+
|
|
83
|
+
/// Minimum number of columns the plugin requires to render. Mostly
|
|
84
|
+
/// affects drag/drop and column-remove button behavior. `undefined`
|
|
85
|
+
/// is treated identically to `1`.
|
|
86
|
+
#[serde(default)]
|
|
87
|
+
#[ts(as = "Option<_>")]
|
|
88
|
+
#[ts(optional)]
|
|
89
|
+
pub min_config_columns: Option<usize>,
|
|
90
|
+
|
|
91
|
+
/// Named column slots. Named columns have replace/swap behavior in
|
|
92
|
+
/// drag/drop rather than insert. The length must be at least
|
|
93
|
+
/// `min_config_columns`.
|
|
94
|
+
#[serde(default)]
|
|
95
|
+
#[ts(as = "Option<_>")]
|
|
96
|
+
#[ts(optional)]
|
|
97
|
+
pub config_column_names: Vec<String>,
|
|
98
|
+
|
|
99
|
+
/// Group-rollup modes the plugin accepts, in preference order.
|
|
100
|
+
/// The first entry that matches a feature flag becomes the default.
|
|
101
|
+
#[serde(default)]
|
|
102
|
+
#[ts(as = "Option<_>")]
|
|
103
|
+
#[ts(optional)]
|
|
104
|
+
pub group_rollup_modes: Option<Vec<GroupRollupMode>>,
|
|
105
|
+
|
|
106
|
+
/// Plugin load priority. Higher numbers win; ties resolve in
|
|
107
|
+
/// registration order. The highest-priority plugin is loaded by
|
|
108
|
+
/// default unless `restore({ plugin })` overrides it.
|
|
109
|
+
#[serde(default)]
|
|
110
|
+
#[ts(as = "Option<_>")]
|
|
111
|
+
#[ts(optional)]
|
|
112
|
+
pub priority: Option<i32>,
|
|
113
|
+
|
|
114
|
+
/// Whether this plugin opts into per-column style controls in the
|
|
115
|
+
/// settings sidebar. When `true`, the StyleTab is shown for active
|
|
116
|
+
/// columns and the plugin's `column_config_schema` is queried for
|
|
117
|
+
/// the per-column field set. When `false` or omitted, no StyleTab
|
|
118
|
+
/// is shown.
|
|
119
|
+
#[serde(default)]
|
|
120
|
+
#[ts(as = "Option<_>")]
|
|
121
|
+
#[ts(optional)]
|
|
122
|
+
pub can_render_column_styles: bool,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
impl PluginStaticConfig {
|
|
126
|
+
/// `true` if dropping a column at `index` should swap with the
|
|
127
|
+
/// column already there rather than insert. Only the named slots
|
|
128
|
+
/// (`config_column_names[..len()-1]`) participate in swap behaviour;
|
|
129
|
+
/// the trailing unnamed tail inserts.
|
|
130
|
+
pub fn is_swap(&self, index: usize) -> bool {
|
|
131
|
+
!self.config_column_names.is_empty() && index < self.config_column_names.len() - 1
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
pub fn get_group_rollups(&self, rollup_features: &[GroupRollupMode]) -> Vec<GroupRollupMode> {
|
|
135
|
+
self.group_rollup_modes
|
|
136
|
+
.clone()
|
|
137
|
+
.map(|x| {
|
|
138
|
+
x.into_iter()
|
|
139
|
+
.filter(|y| rollup_features.is_empty() || rollup_features.contains(y))
|
|
140
|
+
.collect()
|
|
141
|
+
})
|
|
142
|
+
.unwrap_or_default()
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
use std::collections::HashMap;
|
|
14
13
|
use std::ops::Deref;
|
|
15
14
|
use std::sync::LazyLock;
|
|
16
15
|
|
|
@@ -21,18 +20,17 @@ use serde_json::Value;
|
|
|
21
20
|
use ts_rs::TS;
|
|
22
21
|
use wasm_bindgen::prelude::*;
|
|
23
22
|
|
|
24
|
-
use
|
|
25
|
-
use crate::presentation::ColumnConfigMap;
|
|
23
|
+
use crate::renderer::ColumnConfigMap;
|
|
26
24
|
|
|
27
25
|
/// The state of an entire `custom_elements::PerspectiveViewerElement` component
|
|
28
26
|
/// and its `Plugin`.
|
|
29
|
-
#[derive(Debug, Default, Serialize, PartialEq)]
|
|
27
|
+
#[derive(Debug, Default, Serialize, PartialEq, TS)]
|
|
30
28
|
#[serde(deny_unknown_fields)]
|
|
31
|
-
pub struct ViewerConfig<V = String> {
|
|
29
|
+
pub struct ViewerConfig<V: TS = String> {
|
|
32
30
|
pub version: V,
|
|
33
31
|
pub columns_config: ColumnConfigMap,
|
|
34
32
|
pub plugin: String,
|
|
35
|
-
pub plugin_config: Value
|
|
33
|
+
pub plugin_config: serde_json::Map<String, Value>,
|
|
36
34
|
pub settings: bool,
|
|
37
35
|
pub table: Option<String>,
|
|
38
36
|
pub theme: Option<String>,
|
|
@@ -106,7 +104,7 @@ pub struct ViewerConfigUpdate {
|
|
|
106
104
|
#[serde(default)]
|
|
107
105
|
#[ts(as = "Option<_>")]
|
|
108
106
|
#[ts(optional)]
|
|
109
|
-
pub plugin_config:
|
|
107
|
+
pub plugin_config: PluginConfigUpdate,
|
|
110
108
|
|
|
111
109
|
#[serde(default)]
|
|
112
110
|
#[ts(as = "Option<_>")]
|
|
@@ -162,7 +160,8 @@ pub type ThemeUpdate = OptionalUpdate<String>;
|
|
|
162
160
|
pub type TitleUpdate = OptionalUpdate<String>;
|
|
163
161
|
pub type TableUpdate = OptionalUpdate<String>;
|
|
164
162
|
pub type VersionUpdate = OptionalUpdate<String>;
|
|
165
|
-
pub type ColumnConfigUpdate = OptionalUpdate<
|
|
163
|
+
pub type ColumnConfigUpdate = OptionalUpdate<ColumnConfigMap>;
|
|
164
|
+
pub type PluginConfigUpdate = OptionalUpdate<serde_json::Map<String, Value>>;
|
|
166
165
|
|
|
167
166
|
/// Handles `{}` when included as a field with `#[serde(default)]`.
|
|
168
167
|
impl<T: Clone> Default for OptionalUpdate<T> {
|