@perspective-dev/viewer 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/perspective-viewer.js +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/ar.css +1 -0
- 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/extensions.d.ts +0 -5
- package/dist/esm/perspective-viewer.inline.js +7 -7
- 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/ts-rs/ViewOnUpdateResp.d.ts +1 -1
- package/dist/wasm/perspective-viewer.d.ts +62 -73
- package/dist/wasm/perspective-viewer.js +230 -238
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +18 -28
- package/package.json +7 -7
- package/src/css/_context_menu.css +1 -1
- package/src/css/_dropdown_menu.css +1 -1
- package/src/css/_viewer_bundle.css +7 -8
- package/src/css/column-dropdown.css +0 -3
- package/src/css/column-selector.css +8 -5
- package/src/css/column-settings-panel.css +0 -206
- package/src/css/column-style.css +95 -0
- package/src/css/config-selector.css +18 -10
- package/src/css/filter-dropdown.css +5 -5
- package/src/css/form/debug.css +28 -4
- package/src/css/function-dropdown.css +5 -5
- package/src/css/panel-tab.css +23 -0
- package/src/css/plugin-selector.css +6 -5
- package/src/css/render-warning.css +1 -1
- package/src/css/status-bar.css +52 -21
- package/src/css/type-icon.css +1 -3
- package/src/css/{containers → ui/containers}/context-menu.css +22 -16
- package/src/css/ui/containers/dropdown-menu-items.css +66 -0
- package/src/css/{containers → ui/containers}/dropdown-menu.css +8 -53
- package/src/css/{containers → ui/containers}/tabs.css +13 -3
- package/src/css/{dom → ui/dom}/select.css +19 -8
- package/src/css/viewer.css +32 -31
- package/src/rust/agent/tools.rs +5 -2
- package/src/rust/components/chat_panel.rs +1 -1
- package/src/rust/components/{form/code_editor.rs → code_editor.rs} +4 -2
- package/src/rust/components/column_dropdown.rs +2 -2
- package/src/rust/components/column_selector/active_column.rs +15 -9
- package/src/rust/components/column_selector/aggregate_selector.rs +1 -1
- package/src/rust/components/column_selector/config_selector.rs +2 -2
- package/src/rust/components/column_selector/filter_column.rs +8 -5
- package/src/rust/components/column_selector/inactive_column.rs +4 -2
- package/src/rust/components/column_selector/pivot_column.rs +4 -3
- package/src/rust/components/column_selector/sort_column.rs +7 -4
- package/src/rust/components/column_selector.rs +3 -3
- package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +15 -17
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_selector.rs +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab.rs +296 -238
- package/src/rust/components/column_settings_sidebar.rs +3 -4
- package/src/rust/components/copy_dropdown.rs +1 -1
- package/src/rust/components/datetime_column_style/custom.rs +1 -3
- package/src/rust/components/datetime_column_style/simple.rs +16 -6
- package/src/rust/components/datetime_column_style.rs +51 -12
- package/src/rust/components/{form/debug.rs → debug_panel.rs} +5 -5
- package/src/rust/components/{containers/dragdrop_list.rs → dragdrop_list.rs} +2 -10
- package/src/rust/components/export_dropdown.rs +1 -1
- package/src/rust/components/expression_editor.rs +1 -1
- package/src/rust/components/filter_dropdown.rs +2 -2
- package/src/rust/components/function_dropdown.rs +2 -2
- package/src/rust/components/main_panel/frame_theme.rs +3 -59
- package/src/rust/components/main_panel/reconcile.rs +9 -4
- package/src/rust/components/main_panel/render.rs +62 -11
- package/src/rust/components/main_panel/update.rs +39 -10
- package/src/rust/components/main_panel.rs +26 -2
- package/src/rust/components/mod.rs +5 -7
- package/src/rust/components/new_panel_menu.rs +97 -0
- package/src/rust/components/number_series_style.rs +2 -3
- package/src/rust/components/panel_menu.rs +61 -87
- package/src/rust/components/panel_tab.rs +100 -43
- package/src/rust/components/plugin_tab.rs +125 -87
- package/src/rust/components/render_warning.rs +2 -2
- package/src/rust/components/{status_bar_counter.rs → rows_counter.rs} +10 -10
- package/src/rust/components/settings_panel.rs +3 -2
- package/src/rust/components/status_bar.rs +113 -20
- package/src/rust/components/status_indicator.rs +5 -14
- package/src/rust/components/string_column_style.rs +1 -2
- package/src/rust/components/{style/mod.rs → style.rs} +32 -15
- package/src/rust/components/style_controls/number_string_format/digits_section.rs +25 -15
- package/src/rust/components/style_controls/number_string_format/misc_section.rs +7 -3
- package/src/rust/components/style_controls/number_string_format/style_section.rs +2 -1
- 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 +43 -30
- package/src/rust/components/viewer/panels.rs +50 -19
- package/src/rust/components/viewer/render.rs +15 -13
- package/src/rust/components/viewer/settings.rs +137 -68
- package/src/rust/components/viewer/snapshots.rs +5 -10
- package/src/rust/components/viewer/wiring.rs +1 -21
- package/src/rust/components/viewer.rs +15 -10
- package/src/rust/components/window_editor.rs +8 -9
- package/src/rust/config/column_config_schema.rs +358 -52
- package/src/rust/config/datetime_column_style.rs +4 -21
- package/src/rust/config/mod.rs +0 -2
- package/src/rust/config/number_string_format.rs +211 -18
- package/src/rust/config/workspace_config.rs +2 -1
- package/src/rust/custom_elements/debug_plugin.rs +1 -10
- package/src/rust/custom_elements/mod.rs +0 -3
- package/src/rust/custom_elements/viewer.rs +0 -18
- package/src/rust/js/plugin.rs +0 -86
- package/src/rust/lib.rs +12 -15
- package/src/rust/presentation/column_locator.rs +3 -7
- package/src/rust/presentation.rs +85 -38
- package/src/rust/queries/hosted_tables.rs +38 -0
- package/src/rust/queries/mod.rs +2 -0
- package/src/rust/queries/palette_set.rs +1 -1
- package/src/rust/queries/plugin_column_styles.rs +2 -2
- package/src/rust/renderer/activate.rs +1 -3
- package/src/rust/renderer/dispatch.rs +117 -30
- package/src/rust/renderer/limits.rs +24 -5
- package/src/rust/renderer/plugin_config.rs +56 -8
- package/src/rust/renderer/props.rs +2 -1
- package/src/rust/renderer.rs +14 -27
- package/src/rust/session/props.rs +4 -3
- package/src/rust/session/view_subscription.rs +19 -6
- package/src/rust/session.rs +38 -70
- package/src/rust/tasks/create_panel.rs +1 -1
- package/src/rust/tasks/dismiss_render_warning.rs +1 -1
- package/src/rust/tasks/eject.rs +1 -0
- package/src/rust/tasks/pipeline.rs +0 -60
- package/src/rust/tasks/presize_panels.rs +24 -1
- package/src/rust/tasks/restore_and_render.rs +0 -17
- package/src/rust/tasks/send_column_config.rs +1 -1
- package/src/rust/tasks/send_plugin_config.rs +1 -1
- package/src/rust/tasks/set_edit_mode.rs +1 -1
- package/src/rust/ui/containers/control_group.rs +113 -0
- package/src/rust/{components → ui}/containers/dropdown_menu.rs +5 -2
- package/src/rust/{components → ui}/containers/mod.rs +1 -4
- package/src/rust/{components → ui}/containers/scroll_panel.rs +0 -22
- package/src/rust/{components → ui}/containers/scroll_panel_item.rs +0 -13
- package/src/rust/{components → ui}/containers/select.rs +8 -8
- package/src/rust/{components → ui}/containers/sidebar.rs +5 -32
- package/src/rust/{components → ui}/containers/split_panel.rs +8 -80
- package/src/rust/{components → ui}/containers/tab_list.rs +15 -9
- package/src/rust/{components → ui}/context_menu.rs +8 -13
- package/src/rust/{presentation/drag_helpers.rs → ui/dragdrop.rs} +26 -31
- package/src/rust/{components → ui}/font_loader.rs +0 -26
- package/src/rust/{components → ui}/form/color_selector.rs +4 -2
- package/src/rust/ui/form/intl_label.rs +81 -0
- package/src/rust/{components → ui}/form/mirrored_textarea.rs +0 -53
- package/src/rust/{components → ui}/form/mod.rs +1 -10
- package/src/rust/{components → ui}/form/multi_stop_gradient_selector.rs +4 -5
- package/src/rust/{components → ui}/form/named_value_picker.rs +1 -6
- package/src/rust/{components → ui}/form/number_field.rs +1 -1
- package/src/rust/{components → ui}/form/number_range_field.rs +1 -1
- package/src/rust/{components → ui}/form/optional_field.rs +3 -1
- package/src/rust/{components → ui}/form/palette_selector.rs +4 -5
- package/src/rust/{components → ui}/form/select_enum_field.rs +2 -2
- package/src/rust/{components → ui}/form/select_value_field.rs +2 -2
- package/src/rust/ui/mod.rs +56 -0
- package/src/rust/ui/modal.rs +61 -0
- package/src/rust/{components → ui}/portal.rs +174 -79
- package/src/rust/{components/style/style_provider.rs → ui/style.rs} +4 -34
- package/src/rust/utils/completion.rs +0 -6
- package/src/rust/{config/css_scale.rs → utils/css.rs} +38 -35
- package/src/rust/utils/mod.rs +2 -0
- package/src/rust/workspace.rs +35 -0
- package/src/svg/boolean-type.svg +3 -2
- package/src/svg/checkbox-checked-icon.svg +4 -7
- package/src/svg/checkbox-hover.svg +3 -3
- package/src/svg/checkbox-off.svg +2 -3
- package/src/svg/checkbox-on.svg +3 -3
- package/src/svg/checkbox-unchecked-icon.svg +3 -3
- package/src/svg/datagrid-select-column.svg +8 -15
- package/src/svg/datagrid-select-region.svg +8 -15
- package/src/svg/datagrid-select-row-tree.svg +7 -12
- package/src/svg/datagrid-select-row.svg +8 -13
- package/src/svg/date-type.svg +4 -23
- package/src/svg/drawer-tab-hover.svg +4 -6
- package/src/svg/drawer-tab-invert-hover.svg +5 -5
- package/src/svg/drawer-tab-invert.svg +3 -5
- package/src/svg/drawer-tab.svg +5 -5
- package/src/svg/mega-menu-icons-candlestick.svg +5 -37
- package/src/svg/mega-menu-icons-ohlc.svg +4 -39
- package/src/svg/mega-menu-icons-sunburst.svg +4 -38
- package/src/svg/mega-menu-icons-treemap.svg +3 -43
- package/src/svg/mega-menu-icons-y-scatter.svg +12 -72
- package/src/svg/new-panel-icon.svg +4 -0
- package/src/svg/number-type.svg +3 -3
- package/src/svg/radio-hover.svg +3 -3
- package/src/svg/radio-off.svg +3 -3
- package/src/svg/radio-on.svg +3 -3
- package/src/svg/status_ok.svg +3 -26
- package/src/svg/string-type.svg +4 -8
- package/src/svg/theme-icon.svg +5 -5
- package/src/themes/blueprint.css +133 -0
- package/src/themes/botanical.css +3 -52
- package/src/themes/defaults.css +3 -144
- package/src/themes/dracula.css +1 -71
- package/src/themes/eggplant.css +131 -0
- package/src/themes/gruvbox-dark.css +2 -79
- package/src/themes/gruvbox.css +2 -40
- package/src/themes/icons.css +2 -10
- package/src/themes/intl/ar.css +185 -0
- package/src/themes/intl/de.css +65 -33
- package/src/themes/intl/es.css +60 -28
- package/src/themes/intl/fr.css +60 -28
- package/src/themes/intl/ja.css +62 -30
- package/src/themes/intl/pt.css +58 -26
- package/src/themes/intl/zh.css +68 -36
- package/src/themes/intl.css +42 -7
- package/src/themes/ledger.css +137 -0
- package/src/themes/monokai.css +1 -64
- package/src/themes/nord.css +131 -0
- package/src/themes/phosphor.css +1 -61
- package/src/themes/pro-dark.css +1 -52
- package/src/themes/pro.css +98 -0
- package/src/themes/solarized-dark.css +1 -46
- package/src/themes/solarized.css +1 -24
- package/src/themes/themes.css +10 -5
- package/src/themes/vaporwave.css +1 -57
- package/src/themes/velvet.css +132 -0
- package/src/ts/column-format.ts +52 -2
- package/src/ts/extensions.ts +0 -13
- package/src/ts/ts-rs/ViewOnUpdateResp.ts +1 -1
- package/src/css/plugin-settings-panel.css +0 -99
- package/src/rust/components/modal.rs +0 -177
- package/src/rust/custom_elements/copy_dropdown.rs +0 -219
- package/src/rust/custom_elements/export_dropdown.rs +0 -216
- package/src/rust/custom_elements/modal.rs +0 -299
- package/src/svg/dropdown-selector-light.svg +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-39c3c3b28e3cbd48 → perspective-viewer-adc6f3f79141112b}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39c3c3b28e3cbd48 → perspective-viewer-adc6f3f79141112b}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39c3c3b28e3cbd48 → perspective-viewer-adc6f3f79141112b}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39c3c3b28e3cbd48 → perspective-viewer-adc6f3f79141112b}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39c3c3b28e3cbd48 → perspective-viewer-adc6f3f79141112b}/inline4.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-39c3c3b28e3cbd48 → perspective-viewer-adc6f3f79141112b}/inline5.js +0 -0
- /package/src/css/{containers → ui/containers}/scroll-panel.css +0 -0
- /package/src/css/{containers → ui/containers}/split-panel.css +0 -0
- /package/src/css/{dom → ui/dom}/checkbox.css +0 -0
- /package/src/css/{dom → ui/dom}/scrollbar.css +0 -0
- /package/src/css/{form → ui/form}/mirrored-textarea.css +0 -0
- /package/src/rust/components/{form → code_editor}/highlight.rs +0 -0
- /package/src/rust/{components → ui}/containers/sidebar_close_button.rs +0 -0
- /package/src/rust/{components → ui}/form/number_input.rs +0 -0
|
@@ -10,25 +10,27 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
+
use std::rc::Rc;
|
|
14
|
+
|
|
13
15
|
use perspective_client::config::Filter;
|
|
14
16
|
use wasm_bindgen_futures::spawn_local;
|
|
15
17
|
use web_sys::*;
|
|
16
18
|
use yew::prelude::*;
|
|
17
19
|
|
|
18
20
|
use super::status_indicator::StatusIndicator;
|
|
19
|
-
use crate::components::containers::select::*;
|
|
20
21
|
use crate::components::copy_dropdown::CopyDropDownMenu;
|
|
21
22
|
use crate::components::export_dropdown::ExportDropDownMenu;
|
|
22
23
|
use crate::components::global_filter_bar::GlobalFilterBar;
|
|
23
|
-
use crate::components::
|
|
24
|
-
use crate::components::status_bar_counter::StatusBarRowsCounter;
|
|
24
|
+
use crate::components::new_panel_menu::{HostedTables, NewPanelMenu, NewPanelPick, PanelLabels};
|
|
25
25
|
use crate::components::style::StyleSurface;
|
|
26
26
|
use crate::config::*;
|
|
27
27
|
use crate::js::*;
|
|
28
28
|
use crate::presentation::{Presentation, PresentationProps};
|
|
29
|
+
use crate::queries::fetch_hosted_tables;
|
|
29
30
|
use crate::renderer::*;
|
|
30
31
|
use crate::session::*;
|
|
31
32
|
use crate::tasks::*;
|
|
33
|
+
use crate::ui::{PortalModal, Select, SelectItem};
|
|
32
34
|
use crate::utils::*;
|
|
33
35
|
use crate::workspace::Workspace;
|
|
34
36
|
use crate::*;
|
|
@@ -41,9 +43,12 @@ pub struct StatusBarProps {
|
|
|
41
43
|
/// Fired when the reset button is clicked.
|
|
42
44
|
pub on_reset: Callback<bool>,
|
|
43
45
|
|
|
44
|
-
///
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
/// The left-anchored "New" action, fired with the [`NewPanelMenu`] pick.
|
|
47
|
+
pub on_new_panel: Callback<NewPanelPick>,
|
|
48
|
+
|
|
49
|
+
/// Snapshots threaded from root. Component reads `has_table`,
|
|
50
|
+
/// `has_table_cells`, `error` from session_props; `selected_theme`,
|
|
51
|
+
/// `available_themes` from presentation_props.
|
|
47
52
|
pub session_props: SessionProps,
|
|
48
53
|
pub presentation_props: PresentationProps,
|
|
49
54
|
|
|
@@ -89,6 +94,18 @@ impl PartialEq for StatusBarProps {
|
|
|
89
94
|
|
|
90
95
|
pub enum StatusBarMsg {
|
|
91
96
|
Reset(MouseEvent),
|
|
97
|
+
|
|
98
|
+
/// The "New" button: fetch the hosted-table listing, then open the
|
|
99
|
+
/// dropdown.
|
|
100
|
+
NewPanel,
|
|
101
|
+
|
|
102
|
+
/// The listing resolved: open the dropdown anchored at the button, if
|
|
103
|
+
/// the generation is still the newest.
|
|
104
|
+
OpenNewPanel(u32, HostedTables),
|
|
105
|
+
CloseNewPanel,
|
|
106
|
+
|
|
107
|
+
/// A pick in the "New" dropdown.
|
|
108
|
+
NewPanelPick(NewPanelPick),
|
|
92
109
|
Export,
|
|
93
110
|
Copy,
|
|
94
111
|
CloseExport,
|
|
@@ -103,9 +120,17 @@ pub enum StatusBarMsg {
|
|
|
103
120
|
pub struct StatusBar {
|
|
104
121
|
copy_ref: NodeRef,
|
|
105
122
|
export_ref: NodeRef,
|
|
123
|
+
new_ref: NodeRef,
|
|
106
124
|
statusbar_ref: NodeRef,
|
|
107
125
|
copy_target: Option<HtmlElement>,
|
|
108
126
|
export_target: Option<HtmlElement>,
|
|
127
|
+
|
|
128
|
+
/// The "New" dropdown's anchor and listings while it is open.
|
|
129
|
+
new_menu: Option<(HtmlElement, HostedTables, PanelLabels)>,
|
|
130
|
+
|
|
131
|
+
/// Bumped per "New" click; a resolving fetch opens only if it is still
|
|
132
|
+
/// the newest one.
|
|
133
|
+
new_generation: u32,
|
|
109
134
|
}
|
|
110
135
|
|
|
111
136
|
impl Component for StatusBar {
|
|
@@ -116,9 +141,12 @@ impl Component for StatusBar {
|
|
|
116
141
|
Self {
|
|
117
142
|
copy_ref: NodeRef::default(),
|
|
118
143
|
export_ref: NodeRef::default(),
|
|
144
|
+
new_ref: NodeRef::default(),
|
|
119
145
|
statusbar_ref: NodeRef::default(),
|
|
120
146
|
copy_target: None,
|
|
121
147
|
export_target: None,
|
|
148
|
+
new_menu: None,
|
|
149
|
+
new_generation: 0,
|
|
122
150
|
}
|
|
123
151
|
}
|
|
124
152
|
|
|
@@ -129,6 +157,54 @@ impl Component for StatusBar {
|
|
|
129
157
|
ctx.props().on_reset.emit(all);
|
|
130
158
|
false
|
|
131
159
|
},
|
|
160
|
+
StatusBarMsg::NewPanel => {
|
|
161
|
+
self.new_generation = self.new_generation.wrapping_add(1);
|
|
162
|
+
let generation = self.new_generation;
|
|
163
|
+
let workspace = ctx.props().workspace.clone();
|
|
164
|
+
let link = ctx.link().clone();
|
|
165
|
+
ApiFuture::spawn(async move {
|
|
166
|
+
let tables = fetch_hosted_tables(&workspace).await;
|
|
167
|
+
link.send_message(StatusBarMsg::OpenNewPanel(generation, Rc::new(tables)));
|
|
168
|
+
Ok(())
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
false
|
|
172
|
+
},
|
|
173
|
+
StatusBarMsg::OpenNewPanel(generation, tables) => {
|
|
174
|
+
if generation != self.new_generation {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
match self.new_ref.cast::<HtmlElement>() {
|
|
179
|
+
Some(target) => {
|
|
180
|
+
let workspace = &ctx.props().workspace;
|
|
181
|
+
let panels = Rc::new(
|
|
182
|
+
workspace
|
|
183
|
+
.panel_ids()
|
|
184
|
+
.into_iter()
|
|
185
|
+
.filter_map(|id| {
|
|
186
|
+
let panel = workspace.panel(&id)?;
|
|
187
|
+
let title = panel.session.get_title().filter(|t| !t.is_empty());
|
|
188
|
+
Some((id.as_str().to_owned(), title))
|
|
189
|
+
})
|
|
190
|
+
.collect::<Vec<_>>(),
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
self.new_menu = Some((target, tables, panels));
|
|
194
|
+
true
|
|
195
|
+
},
|
|
196
|
+
None => false,
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
StatusBarMsg::CloseNewPanel => {
|
|
200
|
+
self.new_menu = None;
|
|
201
|
+
true
|
|
202
|
+
},
|
|
203
|
+
StatusBarMsg::NewPanelPick(pick) => {
|
|
204
|
+
ctx.props().on_new_panel.emit(pick);
|
|
205
|
+
self.new_menu = None;
|
|
206
|
+
true
|
|
207
|
+
},
|
|
132
208
|
StatusBarMsg::ResetTheme => {
|
|
133
209
|
update_theme(
|
|
134
210
|
&ctx.props().renderer,
|
|
@@ -187,7 +263,6 @@ impl Component for StatusBar {
|
|
|
187
263
|
let has_table = ctx.props().session_props.has_table.clone();
|
|
188
264
|
let is_errored = ctx.props().session_props.is_errored();
|
|
189
265
|
let is_settings_open = ctx.props().is_settings_open;
|
|
190
|
-
let title = &ctx.props().session_props.title;
|
|
191
266
|
|
|
192
267
|
let mut is_updating_class_name = classes!();
|
|
193
268
|
if !is_settings_open {
|
|
@@ -204,6 +279,9 @@ impl Component for StatusBar {
|
|
|
204
279
|
let onexport = ctx.link().callback(|_: MouseEvent| StatusBarMsg::Export);
|
|
205
280
|
let oncopy = ctx.link().callback(|_: MouseEvent| StatusBarMsg::Copy);
|
|
206
281
|
let onreset = ctx.link().callback(StatusBarMsg::Reset);
|
|
282
|
+
let onnew = ctx.link().callback(|_: MouseEvent| StatusBarMsg::NewPanel);
|
|
283
|
+
let on_new_select = ctx.link().callback(StatusBarMsg::NewPanelPick);
|
|
284
|
+
let on_close_new = ctx.link().callback(|_| StatusBarMsg::CloseNewPanel);
|
|
207
285
|
|
|
208
286
|
// Project only the *active* panel's plugin toolbar into the shared status
|
|
209
287
|
// bar. Each panel's toolbar slots into `statusbar-extra-{its-panel-id}`
|
|
@@ -216,12 +294,7 @@ impl Component for StatusBar {
|
|
|
216
294
|
.map(|id| format!("statusbar-extra-{id}"))
|
|
217
295
|
.unwrap_or_else(|| "statusbar-extra".to_owned());
|
|
218
296
|
let is_menu = matches!(has_table, Some(TableLoadState::Loaded)) && is_settings_open;
|
|
219
|
-
|
|
220
|
-
// status bar no longer hosts an `<input>`, so its `is_active` factor is
|
|
221
|
-
// gone. `is_title` now only gates the row counter.
|
|
222
|
-
let is_title =
|
|
223
|
-
is_menu || ctx.props().presentation_props.is_workspace || title.is_some() || is_errored;
|
|
224
|
-
|
|
297
|
+
let is_panel_bar = !ctx.props().workspace.clients().is_empty();
|
|
225
298
|
let is_settings =
|
|
226
299
|
!matches!(has_table, Some(TableLoadState::Loaded)) || is_errored || is_settings_open;
|
|
227
300
|
|
|
@@ -293,11 +366,16 @@ impl Component for StatusBar {
|
|
|
293
366
|
update_count={ctx.props().update_count}
|
|
294
367
|
session_props={ctx.props().session_props.clone()}
|
|
295
368
|
/>
|
|
296
|
-
if
|
|
297
|
-
<
|
|
369
|
+
if is_panel_bar {
|
|
370
|
+
<div id="panel-bar" class="section">
|
|
371
|
+
<span ref={&self.new_ref} class="hover-target" onmousedown={onnew}>
|
|
372
|
+
<span id="new_panel" class="button">
|
|
373
|
+
<span class="icon" />
|
|
374
|
+
<span class="icon-label" />
|
|
375
|
+
</span>
|
|
376
|
+
</span>
|
|
377
|
+
</div>
|
|
298
378
|
}
|
|
299
|
-
// Global-filter chips sit between the row stats and the
|
|
300
|
-
// menu icons (rendered only when there are filters).
|
|
301
379
|
if !ctx.props().global_filters.is_empty() {
|
|
302
380
|
<GlobalFilterBar
|
|
303
381
|
filters={ctx.props().global_filters.clone()}
|
|
@@ -349,9 +427,25 @@ impl Component for StatusBar {
|
|
|
349
427
|
</div>
|
|
350
428
|
}
|
|
351
429
|
</div>
|
|
430
|
+
<PortalModal
|
|
431
|
+
tag_name="perspective-new-panel-menu"
|
|
432
|
+
sheet={StyleSurface::DropdownMenu.sheet()}
|
|
433
|
+
target={self.new_menu.as_ref().map(|(target, ..)| target.clone())}
|
|
434
|
+
own_focus=true
|
|
435
|
+
on_close={on_close_new}
|
|
436
|
+
theme={ctx.props().presentation_props.selected_theme.clone().unwrap_or_default()}
|
|
437
|
+
>
|
|
438
|
+
if let Some((_, tables, panels)) = &self.new_menu {
|
|
439
|
+
<NewPanelMenu
|
|
440
|
+
tables={Some(tables.clone())}
|
|
441
|
+
panels={panels.clone()}
|
|
442
|
+
callback={on_new_select}
|
|
443
|
+
/>
|
|
444
|
+
}
|
|
445
|
+
</PortalModal>
|
|
352
446
|
<PortalModal
|
|
353
447
|
tag_name="perspective-copy-menu"
|
|
354
|
-
|
|
448
|
+
sheet={StyleSurface::DropdownMenu.sheet()}
|
|
355
449
|
target={self.copy_target.clone()}
|
|
356
450
|
own_focus=true
|
|
357
451
|
on_close={on_close_copy}
|
|
@@ -361,7 +455,7 @@ impl Component for StatusBar {
|
|
|
361
455
|
</PortalModal>
|
|
362
456
|
<PortalModal
|
|
363
457
|
tag_name="perspective-export-menu"
|
|
364
|
-
|
|
458
|
+
sheet={StyleSurface::DropdownMenu.sheet()}
|
|
365
459
|
target={self.export_target.clone()}
|
|
366
460
|
own_focus=true
|
|
367
461
|
on_close={on_close_export}
|
|
@@ -429,7 +523,6 @@ fn ThemeSelector(props: &ThemeSelectorProps) -> Html {
|
|
|
429
523
|
<span class="icon" />
|
|
430
524
|
<Select<String>
|
|
431
525
|
id="theme_selector"
|
|
432
|
-
class="invert"
|
|
433
526
|
{values}
|
|
434
527
|
selected={selected.to_owned()}
|
|
435
528
|
on_select={props.on_change.clone()}
|
|
@@ -22,18 +22,15 @@ use crate::utils::*;
|
|
|
22
22
|
|
|
23
23
|
/// Value-prop version: no PubSub subscriptions, no reducer.
|
|
24
24
|
/// The parent (`StatusBar`) re-renders this component whenever
|
|
25
|
-
/// `session_props.error/has_table/
|
|
26
|
-
/// root's `UpdateInFlight` / `UpdateSession` messages).
|
|
25
|
+
/// `session_props.error/has_table/has_table_cells` or `update_count` change
|
|
26
|
+
/// (via root's `UpdateInFlight` / `UpdateSession` messages).
|
|
27
27
|
#[derive(PartialEq, Properties)]
|
|
28
28
|
pub struct StatusIndicatorProps {
|
|
29
29
|
pub renderer: Renderer,
|
|
30
30
|
pub session: Session,
|
|
31
|
-
|
|
32
|
-
///
|
|
33
|
-
/// (RAII-settled; see `UPDATE_COUNT_REGRESSION_PLAN.md`).
|
|
31
|
+
|
|
32
|
+
/// TODO(texodus): remove this
|
|
34
33
|
pub update_count: u32,
|
|
35
|
-
/// Snapshot of session value props — read for `error`, `has_table`,
|
|
36
|
-
/// `stats` to derive the icon state.
|
|
37
34
|
pub session_props: SessionProps,
|
|
38
35
|
}
|
|
39
36
|
|
|
@@ -42,13 +39,7 @@ pub struct StatusIndicatorProps {
|
|
|
42
39
|
/// reconnect callback when in an error state.
|
|
43
40
|
#[function_component]
|
|
44
41
|
pub fn StatusIndicator(props: &StatusIndicatorProps) -> Html {
|
|
45
|
-
let has_table_cells = props
|
|
46
|
-
.session_props
|
|
47
|
-
.stats
|
|
48
|
-
.as_ref()
|
|
49
|
-
.and_then(|s| s.num_table_cells)
|
|
50
|
-
.is_some();
|
|
51
|
-
|
|
42
|
+
let has_table_cells = props.session_props.has_table_cells;
|
|
52
43
|
let state = if let Some(err) = &props.session_props.error {
|
|
53
44
|
StatusIconState::Errored(
|
|
54
45
|
err.message(),
|
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
use yew::prelude::*;
|
|
14
14
|
|
|
15
|
-
use super::modal::{ModalLink, SetModalLink};
|
|
16
|
-
use crate::components::form::select_enum_field::SelectEnumField;
|
|
17
15
|
use crate::config::*;
|
|
16
|
+
use crate::ui::{ModalLink, SelectEnumField, SetModalLink};
|
|
18
17
|
use crate::utils::WeakScope;
|
|
19
18
|
|
|
20
19
|
/// Format-only widget for [`String`] columns. Renders the `format` enum
|
|
@@ -25,15 +25,44 @@
|
|
|
25
25
|
//!
|
|
26
26
|
//! ```ignore
|
|
27
27
|
//! html! {
|
|
28
|
-
//! <StyleProvider root={host}
|
|
28
|
+
//! <StyleProvider root={host} sheet={StyleSurface::Viewer.sheet()}>
|
|
29
29
|
//! <h1>{ "I am styled!" }</h1>
|
|
30
30
|
//! </StyleProvider>
|
|
31
31
|
//! }
|
|
32
32
|
//! ```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
/// The CSS bundle a shadow tree adopts; each variant maps to one build-time
|
|
35
|
+
/// `src/css/_*.css` entrypoint.
|
|
36
|
+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
|
37
|
+
pub enum StyleSurface {
|
|
38
|
+
/// The `<perspective-viewer>` ShadowRoot.
|
|
39
|
+
#[default]
|
|
40
|
+
Viewer,
|
|
41
|
+
/// Column-name completion dropdown (inverted color scheme).
|
|
42
|
+
ColumnDropdown,
|
|
43
|
+
/// Filter-value completion dropdown.
|
|
44
|
+
FilterDropdown,
|
|
45
|
+
/// Expression function-completion dropdown.
|
|
46
|
+
FunctionDropdown,
|
|
47
|
+
/// Copy / Export menu (non-inverted color scheme).
|
|
48
|
+
DropdownMenu,
|
|
49
|
+
/// Panel context menu (right-click a panel).
|
|
50
|
+
ContextMenu,
|
|
51
|
+
}
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
impl StyleSurface {
|
|
54
|
+
/// The shared, lazily constructed `CSSStyleSheet` for this surface.
|
|
55
|
+
pub fn sheet(self) -> web_sys::CssStyleSheet {
|
|
56
|
+
match self {
|
|
57
|
+
StyleSurface::Viewer => VIEWER_SHEET.with(|x| x.clone()),
|
|
58
|
+
StyleSurface::ColumnDropdown => COLUMN_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
59
|
+
StyleSurface::FilterDropdown => FILTER_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
60
|
+
StyleSurface::FunctionDropdown => FUNCTION_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
61
|
+
StyleSurface::DropdownMenu => DROPDOWN_MENU_SHEET.with(|x| x.clone()),
|
|
62
|
+
StyleSurface::ContextMenu => CONTEXT_MENU_SHEET.with(|x| x.clone()),
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
37
66
|
|
|
38
67
|
/// The viewer-surface bundle: every `src/css` file except the floating-popup
|
|
39
68
|
/// sheets. Adopted into the `<perspective-viewer>` ShadowRoot.
|
|
@@ -76,15 +105,3 @@ fn make_sheet(css: &str) -> web_sys::CssStyleSheet {
|
|
|
76
105
|
sheet.replace_sync(css).unwrap();
|
|
77
106
|
sheet
|
|
78
107
|
}
|
|
79
|
-
|
|
80
|
-
/// The memoized, shared `CSSStyleSheet` for a given [`StyleSurface`].
|
|
81
|
-
pub(crate) fn surface_sheet(surface: StyleSurface) -> web_sys::CssStyleSheet {
|
|
82
|
-
match surface {
|
|
83
|
-
StyleSurface::Viewer => VIEWER_SHEET.with(|x| x.clone()),
|
|
84
|
-
StyleSurface::ColumnDropdown => COLUMN_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
85
|
-
StyleSurface::FilterDropdown => FILTER_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
86
|
-
StyleSurface::FunctionDropdown => FUNCTION_DROPDOWN_SHEET.with(|x| x.clone()),
|
|
87
|
-
StyleSurface::DropdownMenu => DROPDOWN_MENU_SHEET.with(|x| x.clone()),
|
|
88
|
-
StyleSurface::ContextMenu => CONTEXT_MENU_SHEET.with(|x| x.clone()),
|
|
89
|
-
}
|
|
90
|
-
}
|
|
@@ -17,15 +17,13 @@ use perspective_client::config::ColumnType;
|
|
|
17
17
|
use yew::html;
|
|
18
18
|
|
|
19
19
|
use super::CustomNumberFormat;
|
|
20
|
-
use crate::components::containers::select::{Select, SelectItem};
|
|
21
|
-
use crate::components::form::number_field::NumberField;
|
|
22
|
-
use crate::components::form::number_range_field::NumberRangeField;
|
|
23
|
-
use crate::components::form::optional_field::OptionalField;
|
|
24
|
-
use crate::components::form::select_enum_field::SelectEnumField;
|
|
25
20
|
use crate::components::style_controls::CustomNumberFormatMsg;
|
|
26
21
|
use crate::config::{
|
|
27
22
|
ROUNDING_INCREMENTS, RoundingIncrement, RoundingMode, RoundingPriority, TrailingZeroDisplay,
|
|
28
23
|
};
|
|
24
|
+
use crate::ui::{
|
|
25
|
+
NumberField, NumberRangeField, OptionalField, Select, SelectEnumField, SelectItem,
|
|
26
|
+
};
|
|
29
27
|
|
|
30
28
|
impl CustomNumberFormat {
|
|
31
29
|
pub fn digits_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
|
|
@@ -37,7 +35,7 @@ impl CustomNumberFormat {
|
|
|
37
35
|
min=1.
|
|
38
36
|
max=21.
|
|
39
37
|
step=1.
|
|
40
|
-
default=
|
|
38
|
+
default={ctx.props().defaults.minimum_integer_digits}
|
|
41
39
|
current_value={self.config.minimum_integer_digits}
|
|
42
40
|
on_change={ctx.link().callback(CustomNumberFormatMsg::MinimumIntegerDigits)}
|
|
43
41
|
/>
|
|
@@ -84,14 +82,23 @@ impl CustomNumberFormat {
|
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
fn float_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
|
|
85
|
+
let defaults = &ctx.props().defaults;
|
|
87
86
|
let fractional_value = Some((
|
|
88
|
-
self.config
|
|
89
|
-
|
|
87
|
+
self.config
|
|
88
|
+
.minimum_fraction_digits
|
|
89
|
+
.unwrap_or(defaults.fraction.0),
|
|
90
|
+
self.config
|
|
91
|
+
.maximum_fraction_digits
|
|
92
|
+
.unwrap_or(defaults.fraction.1),
|
|
90
93
|
));
|
|
91
94
|
|
|
92
95
|
let significant_value = Some((
|
|
93
|
-
self.config
|
|
94
|
-
|
|
96
|
+
self.config
|
|
97
|
+
.minimum_significant_digits
|
|
98
|
+
.unwrap_or(defaults.significant.0),
|
|
99
|
+
self.config
|
|
100
|
+
.maximum_significant_digits
|
|
101
|
+
.unwrap_or(defaults.significant.1),
|
|
95
102
|
));
|
|
96
103
|
|
|
97
104
|
html! {
|
|
@@ -102,7 +109,7 @@ impl CustomNumberFormat {
|
|
|
102
109
|
min=0.
|
|
103
110
|
max=20.
|
|
104
111
|
step=1.
|
|
105
|
-
default={
|
|
112
|
+
default={defaults.fraction}
|
|
106
113
|
current_value={fractional_value}
|
|
107
114
|
on_change={ctx.link().callback(CustomNumberFormatMsg::FracChange)}
|
|
108
115
|
/>
|
|
@@ -113,7 +120,7 @@ impl CustomNumberFormat {
|
|
|
113
120
|
min=1.
|
|
114
121
|
max=21.
|
|
115
122
|
step=1.
|
|
116
|
-
default={
|
|
123
|
+
default={defaults.significant}
|
|
117
124
|
current_value={significant_value}
|
|
118
125
|
on_change={ctx.link().callback(CustomNumberFormatMsg::SigChange)}
|
|
119
126
|
/>
|
|
@@ -121,17 +128,20 @@ impl CustomNumberFormat {
|
|
|
121
128
|
{ self.rounding_increment(ctx) }
|
|
122
129
|
<SelectEnumField<RoundingPriority>
|
|
123
130
|
label="rounding-priority"
|
|
124
|
-
current_value={self.config.rounding_priority}
|
|
131
|
+
current_value={self.config.rounding_priority.unwrap_or(defaults.rounding_priority)}
|
|
132
|
+
default_value={defaults.rounding_priority}
|
|
125
133
|
on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingPriority)}
|
|
126
134
|
/>
|
|
127
135
|
<SelectEnumField<RoundingMode>
|
|
128
136
|
label="rounding-mode"
|
|
129
|
-
current_value={self.config.rounding_mode}
|
|
137
|
+
current_value={self.config.rounding_mode.unwrap_or(defaults.rounding_mode)}
|
|
138
|
+
default_value={defaults.rounding_mode}
|
|
130
139
|
on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingMode)}
|
|
131
140
|
/>
|
|
132
141
|
<SelectEnumField<TrailingZeroDisplay>
|
|
133
142
|
label="trailing-zero-display"
|
|
134
|
-
current_value={self.config.trailing_zero_display}
|
|
143
|
+
current_value={self.config.trailing_zero_display.unwrap_or(defaults.trailing_zero_display)}
|
|
144
|
+
default_value={defaults.trailing_zero_display}
|
|
135
145
|
on_change={ctx.link().callback(CustomNumberFormatMsg::TrailingZero)}
|
|
136
146
|
/>
|
|
137
147
|
</>
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
use yew::html;
|
|
14
14
|
|
|
15
15
|
use super::CustomNumberFormat;
|
|
16
|
-
use crate::components::form::select_enum_field::SelectEnumField;
|
|
17
16
|
use crate::components::style_controls::{CustomNumberFormatMsg, NotationName};
|
|
18
17
|
use crate::config::*;
|
|
18
|
+
use crate::ui::SelectEnumField;
|
|
19
19
|
|
|
20
20
|
impl CustomNumberFormat {
|
|
21
21
|
pub fn misc_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
|
|
@@ -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
|
}
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
use yew::html;
|
|
14
14
|
|
|
15
15
|
use super::CustomNumberFormat;
|
|
16
|
-
use crate::components::form::select_enum_field::SelectEnumField;
|
|
17
16
|
use crate::components::style_controls::{CustomNumberFormatMsg, NumberStyle};
|
|
18
17
|
use crate::config::*;
|
|
18
|
+
use crate::ui::SelectEnumField;
|
|
19
19
|
|
|
20
20
|
impl CustomNumberFormat {
|
|
21
21
|
pub fn style_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
|
|
@@ -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
|
}
|