@perspective-dev/viewer 5.2.0 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/perspective-viewer.js +8 -8
- package/dist/cdn/perspective-viewer.js.map +3 -3
- package/dist/css/blueprint.css +1 -0
- package/dist/css/botanical.css +1 -1
- package/dist/css/dracula.css +1 -1
- package/dist/css/eggplant.css +1 -0
- 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/ledger.css +1 -0
- package/dist/css/monokai.css +1 -1
- package/dist/css/nord.css +1 -0
- 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/css/velvet.css +1 -0
- package/dist/docs/perspective-docs.json +1 -1
- package/dist/esm/column-format.d.ts +16 -3
- package/dist/esm/perspective-viewer.d.ts +1 -0
- package/dist/esm/perspective-viewer.inline.js +9 -9
- package/dist/esm/perspective-viewer.inline.js.map +3 -3
- package/dist/esm/perspective-viewer.js +8 -8
- package/dist/esm/perspective-viewer.js.map +3 -3
- package/dist/esm/plugin.d.ts +10 -0
- package/dist/esm/ts-rs/PanelViewerConfig.d.ts +1 -1
- package/dist/esm/ts-rs/SaveWorkspaceOptions.d.ts +10 -0
- package/dist/esm/ts-rs/ViewerConfig.d.ts +1 -1
- package/dist/esm/ts-rs/WorkspaceConfig.d.ts +9 -1
- package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +13 -3
- package/dist/wasm/perspective-viewer.d.ts +43 -36
- package/dist/wasm/perspective-viewer.js +198 -136
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +19 -17
- package/package.json +1 -1
- package/src/css/column-settings-panel.css +28 -5
- package/src/css/column-style.css +291 -31
- package/src/css/containers/tabs.css +13 -3
- package/src/css/dom/select.css +21 -9
- package/src/css/form/code-editor.css +4 -4
- package/src/css/plugin-selector.css +1 -0
- package/src/css/plugin-settings-panel.css +72 -0
- package/src/css/viewer.css +0 -5
- package/src/rust/agent/tools.rs +53 -19
- package/src/rust/components/column_selector/active_column.rs +2 -2
- package/src/rust/components/column_selector/add_expression_button.rs +3 -3
- package/src/rust/components/column_selector/aggregate_selector.rs +2 -3
- package/src/rust/components/column_selector/config_selector.rs +8 -0
- package/src/rust/components/column_selector/expr_edit_button.rs +4 -10
- package/src/rust/components/column_selector/inactive_column.rs +2 -2
- package/src/rust/components/column_selector.rs +48 -4
- package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +293 -126
- package/src/rust/components/column_settings_sidebar/style_tab.rs +330 -234
- package/src/rust/components/column_settings_sidebar.rs +88 -69
- package/src/rust/components/containers/control_group.rs +91 -0
- package/src/rust/components/containers/mod.rs +1 -0
- package/src/rust/components/containers/select.rs +8 -2
- package/src/rust/components/datetime_column_style/simple.rs +15 -4
- package/src/rust/components/datetime_column_style.rs +50 -10
- package/src/rust/components/editable_header.rs +85 -144
- package/src/rust/components/expression_editor.rs +9 -16
- package/src/rust/components/form/code_editor.rs +16 -6
- package/src/rust/components/form/debug.rs +1 -0
- package/src/rust/components/form/mod.rs +3 -1
- package/src/rust/components/form/multi_stop_gradient_selector.rs +476 -0
- package/src/rust/components/form/named_value_picker.rs +86 -0
- package/src/rust/components/form/palette_selector.rs +440 -0
- package/src/rust/components/main_panel/msg.rs +2 -2
- package/src/rust/components/main_panel/reconcile.rs +4 -4
- package/src/rust/components/plugin_tab.rs +126 -112
- package/src/rust/components/settings_panel.rs +26 -20
- package/src/rust/components/status_bar.rs +0 -1
- package/src/rust/components/style_controls/number_string_format/digits_section.rs +22 -10
- package/src/rust/components/style_controls/number_string_format/misc_section.rs +6 -2
- package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -0
- package/src/rust/components/style_controls/number_string_format/types.rs +24 -0
- package/src/rust/components/style_controls/number_string_format.rs +37 -14
- package/src/rust/components/viewer/msg.rs +46 -7
- package/src/rust/components/viewer/panels.rs +11 -9
- package/src/rust/components/viewer/render.rs +8 -3
- package/src/rust/components/viewer/settings.rs +163 -23
- package/src/rust/components/viewer/snapshots.rs +46 -21
- package/src/rust/components/viewer/wiring.rs +14 -25
- package/src/rust/components/viewer.rs +12 -8
- package/src/rust/config/column_config_schema.rs +435 -45
- package/src/rust/config/css_scale.rs +882 -0
- package/src/rust/config/datetime_column_style.rs +4 -21
- package/src/rust/config/mod.rs +2 -0
- package/src/rust/config/number_string_format.rs +211 -18
- package/src/rust/config/options.rs +10 -0
- package/src/rust/config/viewer_config.rs +49 -55
- package/src/rust/config/workspace_config.rs +132 -5
- package/src/rust/custom_elements/viewer.rs +214 -155
- package/src/rust/custom_events.rs +14 -1
- package/src/rust/js/regular_layout.rs +3 -3
- package/src/rust/lib.rs +2 -0
- package/src/rust/presentation/column_locator.rs +19 -5
- package/src/rust/presentation.rs +209 -36
- package/src/rust/queries/column_locator.rs +74 -44
- package/src/rust/queries/get_viewer_config.rs +0 -3
- package/src/rust/queries/mod.rs +2 -0
- package/src/rust/queries/palette_set.rs +82 -0
- package/src/rust/queries/plugin_column_styles.rs +6 -2
- package/src/rust/renderer/dispatch.rs +50 -12
- package/src/rust/renderer/plugin_config.rs +362 -53
- package/src/rust/renderer.rs +15 -42
- package/src/rust/session/column_defaults_update.rs +15 -8
- package/src/rust/session/metadata.rs +5 -1
- package/src/rust/session/props.rs +1 -0
- package/src/rust/session.rs +9 -6
- package/src/rust/tasks/create_panel.rs +44 -57
- package/src/rust/tasks/edit_expression.rs +19 -23
- package/src/rust/tasks/edit_window.rs +8 -10
- package/src/rust/tasks/eject.rs +4 -1
- package/src/rust/tasks/pipeline.rs +2 -2
- package/src/rust/tasks/presize_panels.rs +44 -5
- package/src/rust/tasks/reset_all.rs +4 -4
- package/src/rust/tasks/restore_and_render.rs +17 -44
- package/src/rust/tasks/restore_panel.rs +11 -13
- package/src/rust/tasks/set_edit_mode.rs +3 -1
- package/src/rust/tasks/sync_update_panels.rs +11 -1
- package/src/rust/tasks/update_theme.rs +23 -18
- package/src/rust/utils/css_vars.rs +26 -0
- package/src/rust/utils/mod.rs +2 -0
- package/src/rust/utils/spawn.rs +1 -1
- package/src/rust/workspace.rs +435 -272
- package/src/svg/lock.svg +7 -0
- package/src/themes/blueprint.css +190 -0
- package/src/themes/botanical.css +14 -17
- package/src/themes/defaults.css +4 -110
- package/src/themes/dracula.css +19 -14
- package/src/themes/eggplant.css +189 -0
- package/src/themes/gruvbox-dark.css +23 -15
- package/src/themes/gruvbox.css +11 -1
- package/src/themes/icons.css +2 -2
- package/src/themes/intl/de.css +23 -1
- package/src/themes/intl/es.css +23 -1
- package/src/themes/intl/fr.css +23 -1
- package/src/themes/intl/ja.css +23 -1
- package/src/themes/intl/pt.css +23 -1
- package/src/themes/intl/zh.css +23 -1
- package/src/themes/intl.css +26 -4
- package/src/themes/ledger.css +195 -0
- package/src/themes/monokai.css +24 -14
- package/src/themes/nord.css +186 -0
- package/src/themes/phosphor.css +7 -14
- package/src/themes/pro-dark.css +12 -16
- package/src/themes/pro.css +118 -0
- package/src/themes/solarized-dark.css +9 -16
- package/src/themes/solarized.css +7 -0
- package/src/themes/themes.css +10 -5
- package/src/themes/vaporwave.css +22 -14
- package/src/themes/velvet.css +192 -0
- package/src/ts/column-format.ts +52 -2
- package/src/ts/perspective-viewer.ts +1 -0
- package/src/ts/plugin.ts +14 -0
- package/src/ts/ts-rs/PanelViewerConfig.ts +1 -1
- package/src/ts/ts-rs/SaveWorkspaceOptions.ts +11 -0
- package/src/ts/ts-rs/ViewerConfig.ts +1 -1
- package/src/ts/ts-rs/WorkspaceConfig.ts +8 -2
- package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +11 -3
- package/src/rust/components/form/color_range_selector.rs +0 -137
- package/src/svg/dropdown-selector-light.svg +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline4.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline5.js +0 -0
|
@@ -20,9 +20,11 @@ use perspective_client::config::ViewConfig;
|
|
|
20
20
|
use yew::prelude::*;
|
|
21
21
|
|
|
22
22
|
use crate::components::column_settings_sidebar::style_tab::primitive_field::{
|
|
23
|
-
BoolField, ColorField,
|
|
23
|
+
BoolField, ColorField, EnumField, NumberFieldPrimitive,
|
|
24
24
|
};
|
|
25
|
+
use crate::components::containers::control_group::ControlGroup;
|
|
25
26
|
use crate::config::ControlSpec;
|
|
27
|
+
use crate::presentation::Presentation;
|
|
26
28
|
use crate::queries::get_plugin_config_schema;
|
|
27
29
|
use crate::renderer::Renderer;
|
|
28
30
|
use crate::session::Session;
|
|
@@ -47,6 +49,7 @@ pub struct PluginTabProps {
|
|
|
47
49
|
pub plugin_config: PtrEqRc<serde_json::Map<String, serde_json::Value>>,
|
|
48
50
|
|
|
49
51
|
// State
|
|
52
|
+
pub presentation: Presentation,
|
|
50
53
|
pub renderer: Renderer,
|
|
51
54
|
pub session: Session,
|
|
52
55
|
}
|
|
@@ -95,122 +98,133 @@ pub fn PluginTab(props: &PluginTabProps) -> Html {
|
|
|
95
98
|
})
|
|
96
99
|
};
|
|
97
100
|
|
|
98
|
-
let
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
.filter_map(|spec| {
|
|
103
|
-
let component = match spec {
|
|
104
|
-
ControlSpec::Enum {
|
|
105
|
-
key,
|
|
106
|
-
variants,
|
|
107
|
-
default,
|
|
108
|
-
} => {
|
|
109
|
-
let current = raw_config
|
|
110
|
-
.get(&key)
|
|
111
|
-
.and_then(|v| v.as_str().map(|s| s.to_string()));
|
|
112
|
-
html! {
|
|
113
|
-
<EnumField
|
|
114
|
-
field_key={key}
|
|
115
|
-
{variants}
|
|
116
|
-
{default}
|
|
117
|
-
{current}
|
|
118
|
-
on_change={on_change.clone()}
|
|
119
|
-
/>
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
ControlSpec::Bool { key, default } => {
|
|
123
|
-
let current = raw_config.get(&key).and_then(|v| v.as_bool());
|
|
124
|
-
html! {
|
|
125
|
-
<BoolField
|
|
126
|
-
field_key={key}
|
|
127
|
-
{default}
|
|
128
|
-
{current}
|
|
129
|
-
on_change={on_change.clone()}
|
|
130
|
-
/>
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
ControlSpec::Color { key, default } => {
|
|
134
|
-
let current = raw_config
|
|
135
|
-
.get(&key)
|
|
136
|
-
.and_then(|v| v.as_str().map(|s| s.to_string()));
|
|
137
|
-
html! {
|
|
138
|
-
<ColorField
|
|
139
|
-
field_key={key}
|
|
140
|
-
{default}
|
|
141
|
-
{current}
|
|
142
|
-
on_change={on_change.clone()}
|
|
143
|
-
/>
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
ControlSpec::ColorRange {
|
|
147
|
-
key_pos,
|
|
148
|
-
key_neg,
|
|
149
|
-
default_pos,
|
|
150
|
-
default_neg,
|
|
151
|
-
is_gradient,
|
|
152
|
-
} => {
|
|
153
|
-
let current_pos = raw_config
|
|
154
|
-
.get(&key_pos)
|
|
155
|
-
.and_then(|v| v.as_str().map(|s| s.to_string()));
|
|
156
|
-
let current_neg = raw_config
|
|
157
|
-
.get(&key_neg)
|
|
158
|
-
.and_then(|v| v.as_str().map(|s| s.to_string()));
|
|
159
|
-
html! {
|
|
160
|
-
<ColorRangeField
|
|
161
|
-
field_key_pos={key_pos}
|
|
162
|
-
field_key_neg={key_neg}
|
|
163
|
-
{default_pos}
|
|
164
|
-
{default_neg}
|
|
165
|
-
{current_pos}
|
|
166
|
-
{current_neg}
|
|
167
|
-
{is_gradient}
|
|
168
|
-
on_change={on_change.clone()}
|
|
169
|
-
/>
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
ControlSpec::Number {
|
|
173
|
-
key,
|
|
174
|
-
default,
|
|
175
|
-
min,
|
|
176
|
-
max,
|
|
177
|
-
step,
|
|
178
|
-
include,
|
|
179
|
-
} => {
|
|
180
|
-
let current = raw_config.get(&key).and_then(|v| v.as_f64());
|
|
181
|
-
html! {
|
|
182
|
-
<NumberFieldPrimitive
|
|
183
|
-
field_key={key}
|
|
184
|
-
{default}
|
|
185
|
-
{current}
|
|
186
|
-
{min}
|
|
187
|
-
{max}
|
|
188
|
-
{step}
|
|
189
|
-
{include}
|
|
190
|
-
on_change={on_change.clone()}
|
|
191
|
-
/>
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
// Column-scoped variants don't apply to
|
|
195
|
-
// plugin-level config; drop silently.
|
|
196
|
-
ControlSpec::AggregateDepth
|
|
197
|
-
| ControlSpec::NumberSeriesStyle { .. }
|
|
198
|
-
| ControlSpec::DatetimeFormat
|
|
199
|
-
| ControlSpec::StringFormat
|
|
200
|
-
| ControlSpec::Symbols { .. }
|
|
201
|
-
| ControlSpec::NumberFormat
|
|
202
|
-
| ControlSpec::String { .. } => {
|
|
203
|
-
return None;
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
Some(html! { <fieldset class="style-control">{ component }</fieldset> })
|
|
101
|
+
let on_group_toggle = {
|
|
102
|
+
let presentation = props.presentation.clone();
|
|
103
|
+
yew::Callback::from(move |(key, open): (String, bool)| {
|
|
104
|
+
presentation.set_control_group_collapsed(&key, !open);
|
|
208
105
|
})
|
|
209
|
-
|
|
106
|
+
};
|
|
210
107
|
|
|
108
|
+
let raw_config = &*props.plugin_config;
|
|
109
|
+
let components = render_specs(
|
|
110
|
+
&schema,
|
|
111
|
+
raw_config,
|
|
112
|
+
&on_change,
|
|
113
|
+
&props.presentation,
|
|
114
|
+
&on_group_toggle,
|
|
115
|
+
);
|
|
211
116
|
html! {
|
|
212
117
|
<div id="plugin-tab" class="sidebar_column scrollable">
|
|
213
118
|
<div id="plugin-config-container" class="tab-section">{ components }</div>
|
|
214
119
|
</div>
|
|
215
120
|
}
|
|
216
121
|
}
|
|
122
|
+
|
|
123
|
+
fn render_specs(
|
|
124
|
+
specs: &[ControlSpec],
|
|
125
|
+
raw_config: &serde_json::Map<String, serde_json::Value>,
|
|
126
|
+
on_change: &Callback<crate::config::ColumnConfigFieldUpdate>,
|
|
127
|
+
presentation: &Presentation,
|
|
128
|
+
on_group_toggle: &Callback<(String, bool)>,
|
|
129
|
+
) -> Vec<Html> {
|
|
130
|
+
specs
|
|
131
|
+
.iter()
|
|
132
|
+
.filter_map(|spec| match spec {
|
|
133
|
+
ControlSpec::Group { key, fields } => {
|
|
134
|
+
let children =
|
|
135
|
+
render_specs(fields, raw_config, on_change, presentation, on_group_toggle);
|
|
136
|
+
|
|
137
|
+
(!children.is_empty()).then(|| {
|
|
138
|
+
html! {
|
|
139
|
+
<ControlGroup
|
|
140
|
+
key={format!("group::{key}")}
|
|
141
|
+
group_key={key.clone()}
|
|
142
|
+
open={!presentation.is_control_group_collapsed(key)}
|
|
143
|
+
on_toggle={on_group_toggle.clone()}
|
|
144
|
+
>
|
|
145
|
+
{ children }
|
|
146
|
+
</ControlGroup>
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
},
|
|
150
|
+
leaf => {
|
|
151
|
+
let key = leaf.serialized_keys().join("+");
|
|
152
|
+
let component = render_leaf(leaf, raw_config, on_change)?;
|
|
153
|
+
Some(html! { <fieldset class="style-control" {key}>{ component }</fieldset> })
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
.collect_vec()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
fn render_leaf(
|
|
160
|
+
spec: &ControlSpec,
|
|
161
|
+
raw_config: &serde_json::Map<String, serde_json::Value>,
|
|
162
|
+
on_change: &Callback<crate::config::ColumnConfigFieldUpdate>,
|
|
163
|
+
) -> Option<Html> {
|
|
164
|
+
match spec.clone() {
|
|
165
|
+
ControlSpec::Enum {
|
|
166
|
+
key,
|
|
167
|
+
variants,
|
|
168
|
+
default,
|
|
169
|
+
} => {
|
|
170
|
+
let current = raw_config
|
|
171
|
+
.get(&key)
|
|
172
|
+
.and_then(|v| v.as_str().map(|s| s.to_string()));
|
|
173
|
+
Some(html! {
|
|
174
|
+
<EnumField
|
|
175
|
+
field_key={key}
|
|
176
|
+
{variants}
|
|
177
|
+
{default}
|
|
178
|
+
{current}
|
|
179
|
+
on_change={on_change.clone()}
|
|
180
|
+
/>
|
|
181
|
+
})
|
|
182
|
+
},
|
|
183
|
+
ControlSpec::Bool { key, default } => {
|
|
184
|
+
let current = raw_config.get(&key).and_then(|v| v.as_bool());
|
|
185
|
+
Some(html! {
|
|
186
|
+
<BoolField field_key={key} {default} {current} on_change={on_change.clone()} />
|
|
187
|
+
})
|
|
188
|
+
},
|
|
189
|
+
ControlSpec::Color { key, default } => {
|
|
190
|
+
let current = raw_config
|
|
191
|
+
.get(&key)
|
|
192
|
+
.and_then(|v| v.as_str().map(|s| s.to_string()));
|
|
193
|
+
Some(html! {
|
|
194
|
+
<ColorField field_key={key} {default} {current} on_change={on_change.clone()} />
|
|
195
|
+
})
|
|
196
|
+
},
|
|
197
|
+
ControlSpec::Number {
|
|
198
|
+
key,
|
|
199
|
+
default,
|
|
200
|
+
min,
|
|
201
|
+
max,
|
|
202
|
+
step,
|
|
203
|
+
include,
|
|
204
|
+
} => {
|
|
205
|
+
let current = raw_config.get(&key).and_then(|v| v.as_f64());
|
|
206
|
+
Some(html! {
|
|
207
|
+
<NumberFieldPrimitive
|
|
208
|
+
field_key={key}
|
|
209
|
+
{default}
|
|
210
|
+
{current}
|
|
211
|
+
{min}
|
|
212
|
+
{max}
|
|
213
|
+
{step}
|
|
214
|
+
{include}
|
|
215
|
+
on_change={on_change.clone()}
|
|
216
|
+
/>
|
|
217
|
+
})
|
|
218
|
+
},
|
|
219
|
+
ControlSpec::Group { .. }
|
|
220
|
+
| ControlSpec::AggregateDepth
|
|
221
|
+
| ControlSpec::NumberSeriesStyle { .. }
|
|
222
|
+
| ControlSpec::DatetimeFormat { .. }
|
|
223
|
+
| ControlSpec::StringFormat
|
|
224
|
+
| ControlSpec::Symbols { .. }
|
|
225
|
+
| ControlSpec::NumberFormat { .. }
|
|
226
|
+
| ControlSpec::String { .. }
|
|
227
|
+
| ControlSpec::Palette { .. }
|
|
228
|
+
| ControlSpec::GradientStops { .. } => None,
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -22,7 +22,8 @@ use super::plugin_tab::PluginTab;
|
|
|
22
22
|
use crate::components::containers::sidebar_close_button::SidebarCloseButton;
|
|
23
23
|
use crate::components::form::debug::DebugPanel;
|
|
24
24
|
use crate::config::{PluginStaticConfig, PluginUpdate};
|
|
25
|
-
use crate::presentation::{ColumnLocator, OpenColumnSettings, Presentation};
|
|
25
|
+
use crate::presentation::{ColumnLocator, ColumnSettingsTarget, OpenColumnSettings, Presentation};
|
|
26
|
+
use crate::queries::classify_column;
|
|
26
27
|
use crate::renderer::*;
|
|
27
28
|
use crate::session::column_defaults_update::*;
|
|
28
29
|
use crate::session::*;
|
|
@@ -34,7 +35,7 @@ use crate::workspace::Workspace;
|
|
|
34
35
|
pub struct SettingsPanelProps {
|
|
35
36
|
pub on_close: Callback<()>,
|
|
36
37
|
pub on_resize: Rc<PubSub<()>>,
|
|
37
|
-
pub on_select_column: Callback<Option<
|
|
38
|
+
pub on_select_column: Callback<Option<ColumnSettingsTarget>>,
|
|
38
39
|
pub on_debug: Callback<()>,
|
|
39
40
|
pub is_debug: bool,
|
|
40
41
|
|
|
@@ -145,25 +146,28 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
145
146
|
} = &props;
|
|
146
147
|
|
|
147
148
|
let selected_column = {
|
|
148
|
-
let locator = props.open_column_settings.locator.clone();
|
|
149
149
|
let config = &props.view_config;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
150
|
+
props
|
|
151
|
+
.open_column_settings
|
|
152
|
+
.target
|
|
153
|
+
.as_ref()
|
|
154
|
+
.and_then(|target| match target {
|
|
155
|
+
ColumnSettingsTarget::NewExpression => Some(ColumnLocator::NewExpression),
|
|
156
|
+
ColumnSettingsTarget::Column(n) => {
|
|
157
|
+
let locator = classify_column(n, config, &props.metadata)?;
|
|
158
|
+
if !matches!(locator, ColumnLocator::Table(_)) {
|
|
159
|
+
return Some(locator);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let used = config.columns.iter().any(|maybe_col| {
|
|
163
|
+
maybe_col.as_ref().map(|col| col == n).unwrap_or_default()
|
|
164
|
+
}) || config.group_by.iter().any(|col| col == n)
|
|
165
|
+
|| config.split_by.iter().any(|col| col == n)
|
|
166
|
+
|| config.filter.iter().any(|col| col.column() == n)
|
|
167
|
+
|| config.sort.iter().any(|col| &col.0 == n);
|
|
168
|
+
(used && props.renderer.can_render_column_styles()).then_some(locator)
|
|
169
|
+
},
|
|
170
|
+
})
|
|
167
171
|
};
|
|
168
172
|
|
|
169
173
|
let plugin_name = props.plugin_name.clone();
|
|
@@ -217,6 +221,7 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
217
221
|
|
|
218
222
|
update.set_update_column_defaults(
|
|
219
223
|
&session_metadata,
|
|
224
|
+
&view_config,
|
|
220
225
|
&view_config.columns,
|
|
221
226
|
plugin_config,
|
|
222
227
|
);
|
|
@@ -365,6 +370,7 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
365
370
|
<PluginTab
|
|
366
371
|
view_config={props.view_config.clone()}
|
|
367
372
|
plugin_config={props.plugin_config.clone()}
|
|
373
|
+
presentation={presentation.clone()}
|
|
368
374
|
renderer={renderer.clone()}
|
|
369
375
|
session={session.clone()}
|
|
370
376
|
// initial_width={width}
|
|
@@ -37,7 +37,7 @@ impl CustomNumberFormat {
|
|
|
37
37
|
min=1.
|
|
38
38
|
max=21.
|
|
39
39
|
step=1.
|
|
40
|
-
default=
|
|
40
|
+
default={ctx.props().defaults.minimum_integer_digits}
|
|
41
41
|
current_value={self.config.minimum_integer_digits}
|
|
42
42
|
on_change={ctx.link().callback(CustomNumberFormatMsg::MinimumIntegerDigits)}
|
|
43
43
|
/>
|
|
@@ -84,14 +84,23 @@ impl CustomNumberFormat {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
fn float_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
|
|
87
|
+
let defaults = &ctx.props().defaults;
|
|
87
88
|
let fractional_value = Some((
|
|
88
|
-
self.config
|
|
89
|
-
|
|
89
|
+
self.config
|
|
90
|
+
.minimum_fraction_digits
|
|
91
|
+
.unwrap_or(defaults.fraction.0),
|
|
92
|
+
self.config
|
|
93
|
+
.maximum_fraction_digits
|
|
94
|
+
.unwrap_or(defaults.fraction.1),
|
|
90
95
|
));
|
|
91
96
|
|
|
92
97
|
let significant_value = Some((
|
|
93
|
-
self.config
|
|
94
|
-
|
|
98
|
+
self.config
|
|
99
|
+
.minimum_significant_digits
|
|
100
|
+
.unwrap_or(defaults.significant.0),
|
|
101
|
+
self.config
|
|
102
|
+
.maximum_significant_digits
|
|
103
|
+
.unwrap_or(defaults.significant.1),
|
|
95
104
|
));
|
|
96
105
|
|
|
97
106
|
html! {
|
|
@@ -102,7 +111,7 @@ impl CustomNumberFormat {
|
|
|
102
111
|
min=0.
|
|
103
112
|
max=20.
|
|
104
113
|
step=1.
|
|
105
|
-
default={
|
|
114
|
+
default={defaults.fraction}
|
|
106
115
|
current_value={fractional_value}
|
|
107
116
|
on_change={ctx.link().callback(CustomNumberFormatMsg::FracChange)}
|
|
108
117
|
/>
|
|
@@ -113,7 +122,7 @@ impl CustomNumberFormat {
|
|
|
113
122
|
min=1.
|
|
114
123
|
max=21.
|
|
115
124
|
step=1.
|
|
116
|
-
default={
|
|
125
|
+
default={defaults.significant}
|
|
117
126
|
current_value={significant_value}
|
|
118
127
|
on_change={ctx.link().callback(CustomNumberFormatMsg::SigChange)}
|
|
119
128
|
/>
|
|
@@ -121,17 +130,20 @@ impl CustomNumberFormat {
|
|
|
121
130
|
{ self.rounding_increment(ctx) }
|
|
122
131
|
<SelectEnumField<RoundingPriority>
|
|
123
132
|
label="rounding-priority"
|
|
124
|
-
current_value={self.config.rounding_priority}
|
|
133
|
+
current_value={self.config.rounding_priority.unwrap_or(defaults.rounding_priority)}
|
|
134
|
+
default_value={defaults.rounding_priority}
|
|
125
135
|
on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingPriority)}
|
|
126
136
|
/>
|
|
127
137
|
<SelectEnumField<RoundingMode>
|
|
128
138
|
label="rounding-mode"
|
|
129
|
-
current_value={self.config.rounding_mode}
|
|
139
|
+
current_value={self.config.rounding_mode.unwrap_or(defaults.rounding_mode)}
|
|
140
|
+
default_value={defaults.rounding_mode}
|
|
130
141
|
on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingMode)}
|
|
131
142
|
/>
|
|
132
143
|
<SelectEnumField<TrailingZeroDisplay>
|
|
133
144
|
label="trailing-zero-display"
|
|
134
|
-
current_value={self.config.trailing_zero_display}
|
|
145
|
+
current_value={self.config.trailing_zero_display.unwrap_or(defaults.trailing_zero_display)}
|
|
146
|
+
default_value={defaults.trailing_zero_display}
|
|
135
147
|
on_change={ctx.link().callback(CustomNumberFormatMsg::TrailingZero)}
|
|
136
148
|
/>
|
|
137
149
|
</>
|
|
@@ -32,23 +32,27 @@ impl CustomNumberFormat {
|
|
|
32
32
|
None
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
let defaults = &ctx.props().defaults;
|
|
35
36
|
html! {
|
|
36
37
|
<>
|
|
37
38
|
<SelectEnumField<NotationName>
|
|
38
39
|
label="notation"
|
|
39
40
|
on_change={ctx.link().callback(CustomNumberFormatMsg::NotationChanged)}
|
|
40
41
|
current_value={self.notation.unwrap_or_default()}
|
|
42
|
+
default_value={NotationName::from(&defaults.notation)}
|
|
41
43
|
/>
|
|
42
44
|
{ compact_display_checkbox }
|
|
43
45
|
<SelectEnumField<UseGrouping>
|
|
44
46
|
label="use-grouping"
|
|
45
47
|
on_change={ctx.link().callback(CustomNumberFormatMsg::UseGrouping)}
|
|
46
|
-
current_value={self.config.use_grouping.
|
|
48
|
+
current_value={self.config.use_grouping.unwrap_or(defaults.use_grouping)}
|
|
49
|
+
default_value={defaults.use_grouping}
|
|
47
50
|
/>
|
|
48
51
|
<SelectEnumField<SignDisplay>
|
|
49
52
|
label="sign-display"
|
|
50
53
|
on_change={ctx.link().callback(CustomNumberFormatMsg::SignDisplay)}
|
|
51
|
-
current_value={self.config.sign_display.
|
|
54
|
+
current_value={self.config.sign_display.unwrap_or(defaults.sign_display)}
|
|
55
|
+
default_value={defaults.sign_display}
|
|
52
56
|
/>
|
|
53
57
|
</>
|
|
54
58
|
}
|
|
@@ -60,6 +60,7 @@ impl CustomNumberFormat {
|
|
|
60
60
|
<SelectEnumField<NumberStyle>
|
|
61
61
|
label="style"
|
|
62
62
|
current_value={self.style}
|
|
63
|
+
default_value={NumberStyle::from(&ctx.props().defaults.style)}
|
|
63
64
|
on_change={ctx.link().callback(CustomNumberFormatMsg::StyleChanged)}
|
|
64
65
|
/>
|
|
65
66
|
{ section }
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
use strum::{Display, EnumIter};
|
|
14
14
|
|
|
15
|
+
use crate::config::{Notation, NumberFormatStyle};
|
|
16
|
+
|
|
15
17
|
#[derive(Clone, PartialEq, Debug, Copy, Default, EnumIter, Display)]
|
|
16
18
|
pub enum NumberStyle {
|
|
17
19
|
#[default]
|
|
@@ -21,6 +23,17 @@ pub enum NumberStyle {
|
|
|
21
23
|
Unit,
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
impl From<&NumberFormatStyle> for NumberStyle {
|
|
27
|
+
fn from(style: &NumberFormatStyle) -> Self {
|
|
28
|
+
match style {
|
|
29
|
+
NumberFormatStyle::Decimal => Self::Decimal,
|
|
30
|
+
NumberFormatStyle::Currency(_) => Self::Currency,
|
|
31
|
+
NumberFormatStyle::Percent => Self::Percent,
|
|
32
|
+
NumberFormatStyle::Unit(_) => Self::Unit,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
#[derive(Clone, PartialEq, Debug, Copy, Default, Display, EnumIter)]
|
|
25
38
|
pub enum NotationName {
|
|
26
39
|
#[default]
|
|
@@ -29,3 +42,14 @@ pub enum NotationName {
|
|
|
29
42
|
Engineering,
|
|
30
43
|
Compact,
|
|
31
44
|
}
|
|
45
|
+
|
|
46
|
+
impl From<&Notation> for NotationName {
|
|
47
|
+
fn from(notation: &Notation) -> Self {
|
|
48
|
+
match notation {
|
|
49
|
+
Notation::Standard => Self::Standard,
|
|
50
|
+
Notation::Scientific => Self::Scientific,
|
|
51
|
+
Notation::Engineering => Self::Engineering,
|
|
52
|
+
Notation::Compact(_) => Self::Compact,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -15,6 +15,8 @@ mod misc_section;
|
|
|
15
15
|
mod style_section;
|
|
16
16
|
mod types;
|
|
17
17
|
|
|
18
|
+
use std::rc::Rc;
|
|
19
|
+
|
|
18
20
|
use perspective_client::config::ColumnType;
|
|
19
21
|
pub use types::*;
|
|
20
22
|
use yew::{Callback, Component, Properties, html};
|
|
@@ -27,6 +29,10 @@ pub struct CustomNumberFormatProps {
|
|
|
27
29
|
pub on_change: Callback<ColumnConfigFieldUpdate>,
|
|
28
30
|
pub view_type: ColumnType,
|
|
29
31
|
pub column_name: String,
|
|
32
|
+
|
|
33
|
+
/// Resolved default values for this column under the active plugin.
|
|
34
|
+
pub defaults: Rc<NumberFormatDefaults>,
|
|
35
|
+
|
|
30
36
|
#[prop_or_default]
|
|
31
37
|
pub keys: Vec<String>,
|
|
32
38
|
}
|
|
@@ -147,25 +153,39 @@ impl Component for CustomNumberFormat {
|
|
|
147
153
|
self.config.minimum_integer_digits = val;
|
|
148
154
|
},
|
|
149
155
|
CustomNumberFormatMsg::FracChange(val) => {
|
|
156
|
+
let defaults = &ctx.props().defaults;
|
|
150
157
|
self.config.rounding_increment = None;
|
|
151
158
|
self.config.maximum_fraction_digits = val.map(|(_, val)| {
|
|
152
|
-
let min = self
|
|
159
|
+
let min = self
|
|
160
|
+
.config
|
|
161
|
+
.minimum_fraction_digits
|
|
162
|
+
.unwrap_or(defaults.fraction.0);
|
|
153
163
|
val.max(min)
|
|
154
164
|
});
|
|
155
165
|
|
|
156
166
|
self.config.minimum_fraction_digits = val.map(|(val, _)| {
|
|
157
|
-
let max = self
|
|
167
|
+
let max = self
|
|
168
|
+
.config
|
|
169
|
+
.maximum_fraction_digits
|
|
170
|
+
.unwrap_or(defaults.fraction.1);
|
|
158
171
|
val.min(max)
|
|
159
172
|
});
|
|
160
173
|
},
|
|
161
174
|
CustomNumberFormatMsg::SigChange(val) => {
|
|
175
|
+
let defaults = &ctx.props().defaults;
|
|
162
176
|
self.config.maximum_significant_digits = val.map(|(_, val)| {
|
|
163
|
-
let min = self
|
|
177
|
+
let min = self
|
|
178
|
+
.config
|
|
179
|
+
.minimum_significant_digits
|
|
180
|
+
.unwrap_or(defaults.significant.0);
|
|
164
181
|
val.max(min)
|
|
165
182
|
});
|
|
166
183
|
|
|
167
184
|
self.config.minimum_significant_digits = val.map(|(val, _)| {
|
|
168
|
-
let max = self
|
|
185
|
+
let max = self
|
|
186
|
+
.config
|
|
187
|
+
.maximum_significant_digits
|
|
188
|
+
.unwrap_or(defaults.significant.1);
|
|
169
189
|
val.min(max)
|
|
170
190
|
});
|
|
171
191
|
},
|
|
@@ -191,8 +211,7 @@ impl Component for CustomNumberFormat {
|
|
|
191
211
|
},
|
|
192
212
|
};
|
|
193
213
|
|
|
194
|
-
let
|
|
195
|
-
let filtered_config = self.config.clone().filter_default(is_float);
|
|
214
|
+
let filtered_config = self.config.clone().filter_default(&ctx.props().defaults);
|
|
196
215
|
let mut value = serde_json::Map::new();
|
|
197
216
|
if filtered_config != CustomNumberFormatConfig::default() {
|
|
198
217
|
value.insert(
|
|
@@ -216,20 +235,24 @@ impl Component for CustomNumberFormat {
|
|
|
216
235
|
|
|
217
236
|
impl CustomNumberFormat {
|
|
218
237
|
fn initialize(ctx: &yew::prelude::Context<Self>) -> Self {
|
|
219
|
-
let
|
|
238
|
+
let defaults = &ctx.props().defaults;
|
|
239
|
+
let mut config = ctx.props().restored_config.clone();
|
|
240
|
+
if config._style.is_none() && defaults.style != NumberFormatStyle::Decimal {
|
|
241
|
+
config._style = Some(defaults.style.clone());
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if config._notation.is_none() && defaults.notation != Notation::Standard {
|
|
245
|
+
config._notation = Some(defaults.notation.clone());
|
|
246
|
+
}
|
|
247
|
+
|
|
220
248
|
Self {
|
|
221
249
|
style: config
|
|
222
250
|
._style
|
|
223
251
|
.as_ref()
|
|
224
|
-
.map(
|
|
225
|
-
NumberFormatStyle::Decimal => NumberStyle::Decimal,
|
|
226
|
-
NumberFormatStyle::Currency(_) => NumberStyle::Currency,
|
|
227
|
-
NumberFormatStyle::Percent => NumberStyle::Percent,
|
|
228
|
-
NumberFormatStyle::Unit(_) => NumberStyle::Unit,
|
|
229
|
-
})
|
|
252
|
+
.map(NumberStyle::from)
|
|
230
253
|
.unwrap_or_default(),
|
|
254
|
+
notation: config._notation.as_ref().map(NotationName::from),
|
|
231
255
|
config,
|
|
232
|
-
notation: None,
|
|
233
256
|
}
|
|
234
257
|
}
|
|
235
258
|
}
|