@perspective-dev/viewer 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/perspective-viewer.js +2 -2
- package/dist/cdn/perspective-viewer.js.map +4 -4
- package/dist/css/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/monokai.css +1 -1
- package/dist/css/pro-dark.css +1 -1
- package/dist/css/pro.css +1 -1
- package/dist/css/solarized-dark.css +1 -1
- package/dist/css/solarized.css +1 -1
- package/dist/css/themes.css +1 -1
- package/dist/css/vaporwave.css +1 -1
- package/dist/esm/extensions.d.ts +23 -2
- package/dist/esm/perspective-viewer.d.ts +2 -7
- package/dist/esm/perspective-viewer.inline.js +2 -2
- package/dist/esm/perspective-viewer.inline.js.map +4 -4
- package/dist/esm/perspective-viewer.js +2 -2
- package/dist/esm/perspective-viewer.js.map +4 -4
- package/dist/esm/plugin.d.ts +1 -1
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +1 -0
- package/dist/wasm/perspective-viewer.d.ts +218 -46
- package/dist/wasm/perspective-viewer.js +1251 -762
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +38 -19
- package/package.json +1 -1
- package/src/less/containers/scroll-panel.less +0 -1
- package/src/less/plugin-selector.less +15 -5
- package/src/less/status-bar.less +75 -27
- package/src/less/viewer.less +140 -58
- package/src/rust/components/column_dropdown.rs +21 -21
- package/src/rust/components/column_selector/active_column.rs +131 -120
- package/src/rust/components/column_selector/add_expression_button.rs +5 -0
- package/src/rust/components/column_selector/aggregate_selector.rs +8 -4
- package/src/rust/components/column_selector/config_selector.rs +170 -161
- package/src/rust/components/column_selector/empty_column.rs +16 -11
- package/src/rust/components/column_selector/{expression_toolbar.rs → expr_edit_button.rs} +7 -0
- package/src/rust/components/column_selector/filter_column.rs +195 -194
- package/src/rust/components/column_selector/inactive_column.rs +82 -67
- package/src/rust/components/column_selector/pivot_column.rs +16 -11
- package/src/rust/components/column_selector/sort_column.rs +9 -7
- package/src/rust/components/column_selector.rs +42 -37
- package/src/rust/components/column_settings_sidebar/save_settings.rs +3 -1
- package/src/rust/components/column_settings_sidebar/style_tab/agg_depth_selector.rs +58 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/row_selector.rs +6 -6
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs.rs +2 -94
- package/src/rust/components/column_settings_sidebar/style_tab/symbol/symbol_pairs_item.rs +111 -0
- package/src/rust/components/column_settings_sidebar/style_tab/symbol.rs +3 -3
- package/src/rust/components/column_settings_sidebar/style_tab.rs +23 -83
- package/src/rust/components/{column_settings_sidebar/sidebar.rs → column_settings_sidebar.rs} +198 -171
- package/src/rust/components/containers/dragdrop_list.rs +20 -20
- package/src/rust/components/containers/dropdown_menu.rs +4 -6
- package/src/rust/components/containers/mod.rs +1 -4
- package/src/rust/components/containers/scroll_panel.rs +80 -80
- package/src/rust/components/containers/scroll_panel_item.rs +36 -36
- package/src/rust/components/containers/select.rs +46 -44
- package/src/rust/components/containers/sidebar.rs +3 -19
- package/src/rust/components/{column_settings_sidebar/style_tab/symbol/symbol_config.rs → containers/sidebar_close_button.rs} +15 -9
- package/src/rust/components/containers/split_panel.rs +212 -200
- package/src/rust/components/containers/tab_list.rs +11 -11
- package/src/rust/components/copy_dropdown.rs +22 -25
- package/src/rust/components/datetime_column_style/custom.rs +19 -19
- package/src/rust/components/datetime_column_style/simple.rs +13 -14
- package/src/rust/components/datetime_column_style.rs +75 -76
- package/src/rust/components/editable_header.rs +18 -14
- package/src/rust/components/empty_row.rs +5 -5
- package/src/rust/components/export_dropdown.rs +42 -42
- package/src/rust/components/expression_editor.rs +25 -19
- package/src/rust/components/filter_dropdown.rs +22 -22
- package/src/rust/components/font_loader.rs +11 -9
- package/src/rust/components/form/code_editor.rs +106 -105
- package/src/rust/components/form/color_range_selector.rs +14 -12
- package/src/rust/components/form/color_selector.rs +3 -1
- package/src/rust/components/form/debug.rs +95 -94
- package/src/rust/components/form/highlight.rs +5 -3
- package/src/rust/components/form/mod.rs +3 -2
- package/src/rust/components/form/optional_field.rs +2 -2
- package/src/rust/components/form/{select_field.rs → select_enum_field.rs} +1 -46
- package/src/rust/components/form/select_value_field.rs +64 -0
- package/src/rust/components/function_dropdown.rs +21 -21
- package/src/rust/components/main_panel.rs +219 -0
- package/src/rust/components/mod.rs +6 -6
- package/src/rust/components/modal.rs +42 -42
- package/src/rust/components/number_column_style.rs +34 -88
- package/src/rust/components/plugin_selector.rs +22 -25
- package/src/rust/components/render_warning.rs +9 -6
- package/src/rust/components/settings_panel.rs +82 -0
- package/src/rust/components/status_bar.rs +250 -146
- package/src/rust/components/status_bar_counter.rs +26 -119
- package/src/rust/components/status_indicator.rs +95 -79
- package/src/rust/components/string_column_style.rs +45 -45
- package/src/rust/components/style/style_provider.rs +1 -15
- package/src/rust/components/style_controls/number_string_format/digits_section.rs +1 -1
- package/src/rust/components/style_controls/number_string_format/misc_section.rs +1 -1
- package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -1
- package/src/rust/components/style_controls/number_string_format.rs +45 -46
- package/src/rust/components/type_icon.rs +14 -11
- package/src/rust/components/viewer.rs +241 -384
- package/src/rust/config/columns_config.rs +2 -2
- package/src/rust/config/datetime_column_style.rs +1 -6
- package/src/rust/config/mod.rs +1 -0
- package/src/rust/config/number_column_style.rs +0 -6
- package/src/rust/config/number_string_format.rs +27 -4
- package/src/rust/config/viewer_config.rs +27 -167
- package/src/rust/custom_elements/copy_dropdown.rs +14 -6
- package/src/rust/custom_elements/export_dropdown.rs +15 -7
- package/src/rust/custom_elements/filter_dropdown.rs +4 -4
- package/src/rust/custom_elements/mod.rs +3 -0
- package/src/rust/custom_elements/viewer.rs +353 -161
- package/src/rust/custom_events.rs +55 -32
- package/src/rust/dragdrop.rs +4 -24
- package/src/rust/exprtk/cursor.rs +10 -1
- package/src/rust/exprtk/mod.rs +2 -0
- package/src/rust/exprtk/tokenize.rs +20 -3
- package/src/rust/js/clipboard.rs +2 -2
- package/src/rust/js/mimetype.rs +2 -7
- package/src/rust/js/mod.rs +0 -1
- package/src/rust/js/plugin.rs +7 -0
- package/src/rust/lib.rs +18 -5
- package/src/rust/model/column_locator.rs +82 -0
- package/src/rust/model/columns_iter_set.rs +1 -0
- package/src/rust/model/copy_export.rs +50 -14
- package/src/rust/model/edit_expression.rs +2 -5
- package/src/rust/model/eject.rs +41 -0
- package/src/rust/model/export_app.rs +3 -2
- package/src/rust/model/get_viewer_config.rs +4 -28
- package/src/rust/model/intersection_observer.rs +20 -8
- package/src/rust/model/mod.rs +11 -4
- package/src/rust/model/plugin_column_styles.rs +0 -31
- package/src/rust/model/reset_all.rs +38 -0
- package/src/rust/model/resize_observer.rs +34 -7
- package/src/rust/model/restore_and_render.rs +12 -7
- package/src/rust/{utils/scope.rs → model/send_plugin_config.rs} +32 -35
- package/src/rust/model/structural.rs +194 -23
- package/src/rust/model/update_and_render.rs +14 -4
- package/src/rust/{model/create_col.rs → presentation/column_locator.rs} +73 -42
- package/src/rust/{utils/wasm_abi.rs → presentation/sheets.rs} +54 -40
- package/src/rust/presentation.rs +60 -119
- package/src/rust/renderer/activate.rs +20 -5
- package/src/rust/renderer/limits.rs +0 -149
- package/src/rust/renderer/render_timer.rs +1 -1
- package/src/rust/renderer.rs +34 -18
- package/src/rust/root.rs +50 -0
- package/src/rust/session/column_defaults_update.rs +4 -4
- package/src/rust/session/drag_drop_update.rs +1 -1
- package/src/rust/session/metadata.rs +3 -17
- package/src/rust/session/replace_expression_update.rs +1 -2
- package/src/rust/session.rs +162 -82
- package/src/rust/utils/browser/blob.rs +16 -2
- package/src/rust/utils/browser/download.rs +1 -0
- package/src/rust/{components/column_settings_sidebar/mod.rs → utils/browser/dragdrop.rs} +14 -5
- package/src/rust/utils/browser/mod.rs +8 -4
- package/src/rust/utils/browser/selection.rs +5 -0
- package/src/rust/utils/custom_element.rs +28 -13
- package/src/rust/utils/datetime.rs +5 -0
- package/src/rust/utils/debounce.rs +7 -1
- package/src/rust/utils/hooks/use_async_callback.rs +7 -17
- package/src/rust/utils/mod.rs +28 -40
- package/src/rust/utils/number_format.rs +6 -5
- package/src/rust/utils/pubsub.rs +15 -10
- package/src/rust/utils/weak_scope.rs +11 -1
- package/src/svg/bookmark-icon.svg +4 -0
- package/src/svg/drag-handle copy.svg +10 -0
- package/src/svg/drawer-tab-hover.svg +5 -7
- package/src/svg/drawer-tab-invert-hover.svg +4 -8
- package/src/svg/drawer-tab-invert.svg +4 -7
- package/src/svg/drawer-tab.svg +4 -6
- package/src/svg/status_ok.svg +24 -24
- package/src/ts/extensions.ts +51 -3
- package/src/ts/perspective-viewer.ts +2 -14
- package/src/ts/plugin.ts +1 -1
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +1 -1
- package/src/rust/components/column_settings_sidebar/style_tab/column_style.rs +0 -177
- package/src/rust/components/containers/tests/mod.rs +0 -11
- package/src/rust/components/containers/tests/split_panel.rs +0 -91
- package/src/rust/js/testing.rs +0 -149
- package/src/rust/utils/tee.rs +0 -88
- /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-c69283f6f62a5f14 → perspective-viewer-0d326a25c1022412}/inline4.js +0 -0
- /package/src/rust/components/{style_controls.rs → style_controls/mod.rs} +0 -0
- /package/src/rust/{components/containers → config}/kvpair.rs +0 -0
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
use std::rc::Rc;
|
|
14
14
|
|
|
15
|
-
use wasm_bindgen::JsCast;
|
|
16
15
|
use web_sys::*;
|
|
17
16
|
use yew::prelude::*;
|
|
18
17
|
|
|
@@ -22,29 +21,33 @@ use crate::components::containers::select::*;
|
|
|
22
21
|
use crate::components::status_bar_counter::StatusBarRowsCounter;
|
|
23
22
|
use crate::custom_elements::copy_dropdown::*;
|
|
24
23
|
use crate::custom_elements::export_dropdown::*;
|
|
24
|
+
use crate::custom_events::CustomEvents;
|
|
25
|
+
use crate::model::*;
|
|
25
26
|
use crate::presentation::Presentation;
|
|
26
27
|
use crate::renderer::*;
|
|
27
28
|
use crate::session::*;
|
|
28
|
-
#[cfg(test)]
|
|
29
|
-
use crate::utils::WeakScope;
|
|
30
29
|
use crate::utils::*;
|
|
31
30
|
use crate::*;
|
|
32
31
|
|
|
33
|
-
#[derive(Properties,
|
|
32
|
+
#[derive(Properties, PerspectiveProperties!)]
|
|
34
33
|
pub struct StatusBarProps {
|
|
34
|
+
// DOM Attribute
|
|
35
35
|
pub id: String,
|
|
36
|
+
|
|
37
|
+
/// Fired when the reset button is clicked.
|
|
36
38
|
pub on_reset: Callback<bool>,
|
|
39
|
+
|
|
40
|
+
/// Fires when the settings button is clicked
|
|
41
|
+
#[prop_or_default]
|
|
42
|
+
pub on_settings: Option<Callback<()>>,
|
|
43
|
+
|
|
44
|
+
// State
|
|
45
|
+
pub custom_events: CustomEvents,
|
|
37
46
|
pub session: Session,
|
|
38
47
|
pub renderer: Renderer,
|
|
39
48
|
pub presentation: Presentation,
|
|
40
|
-
|
|
41
|
-
#[cfg(test)]
|
|
42
|
-
#[prop_or_default]
|
|
43
|
-
pub weak_link: WeakScope<StatusBar>,
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
derive_model!(Renderer, Session, Presentation for StatusBarProps);
|
|
47
|
-
|
|
48
51
|
impl PartialEq for StatusBarProps {
|
|
49
52
|
fn eq(&self, other: &Self) -> bool {
|
|
50
53
|
self.id == other.id
|
|
@@ -52,27 +55,29 @@ impl PartialEq for StatusBarProps {
|
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
pub enum StatusBarMsg {
|
|
55
|
-
Reset(
|
|
58
|
+
Reset(MouseEvent),
|
|
56
59
|
Export,
|
|
57
60
|
Copy,
|
|
58
61
|
Noop,
|
|
62
|
+
Eject,
|
|
59
63
|
SetThemeConfig((Rc<Vec<String>>, Option<usize>)),
|
|
60
64
|
SetTheme(String),
|
|
61
65
|
ResetTheme,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
SetTitle(Option<String>),
|
|
66
|
+
PointerEvent(web_sys::PointerEvent),
|
|
67
|
+
TitleInputEvent,
|
|
68
|
+
TitleChangeEvent,
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
/// A toolbar with buttons, and `Table` & `View` status information.
|
|
69
72
|
pub struct StatusBar {
|
|
70
|
-
|
|
73
|
+
_subscriptions: [Subscription; 5],
|
|
74
|
+
copy_ref: NodeRef,
|
|
75
|
+
export_ref: NodeRef,
|
|
76
|
+
input_ref: NodeRef,
|
|
77
|
+
statusbar_ref: NodeRef,
|
|
71
78
|
theme: Option<String>,
|
|
72
79
|
themes: Rc<Vec<String>>,
|
|
73
|
-
|
|
74
|
-
copy_ref: NodeRef,
|
|
75
|
-
_sub: [Subscription; 2],
|
|
80
|
+
title: Option<String>,
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
impl Component for StatusBar {
|
|
@@ -80,52 +85,37 @@ impl Component for StatusBar {
|
|
|
80
85
|
type Properties = StatusBarProps;
|
|
81
86
|
|
|
82
87
|
fn create(ctx: &Context<Self>) -> Self {
|
|
83
|
-
|
|
84
|
-
ctx.props()
|
|
85
|
-
.presentation
|
|
86
|
-
.theme_config_updated
|
|
87
|
-
.add_listener(ctx.link().callback(StatusBarMsg::SetThemeConfig)),
|
|
88
|
-
ctx.props()
|
|
89
|
-
.presentation
|
|
90
|
-
.title_changed
|
|
91
|
-
.add_listener(ctx.link().callback(|_| StatusBarMsg::Noop)),
|
|
92
|
-
];
|
|
93
|
-
|
|
94
|
-
// Fetch initial theme
|
|
95
|
-
let presentation = ctx.props().presentation.clone();
|
|
96
|
-
let on_theme = ctx.link().callback(StatusBarMsg::SetThemeConfig);
|
|
97
|
-
ApiFuture::spawn(async move {
|
|
98
|
-
on_theme.emit(presentation.get_selected_theme_config().await?);
|
|
99
|
-
Ok(())
|
|
100
|
-
});
|
|
101
|
-
|
|
88
|
+
fetch_initial_theme(ctx);
|
|
102
89
|
Self {
|
|
103
|
-
|
|
104
|
-
theme: None,
|
|
105
|
-
themes: vec![].into(),
|
|
90
|
+
_subscriptions: register_listeners(ctx),
|
|
106
91
|
copy_ref: NodeRef::default(),
|
|
107
92
|
export_ref: NodeRef::default(),
|
|
108
|
-
|
|
93
|
+
input_ref: NodeRef::default(),
|
|
94
|
+
statusbar_ref: NodeRef::default(),
|
|
95
|
+
theme: None,
|
|
96
|
+
themes: vec![].into(),
|
|
97
|
+
title: ctx.props().session().get_title().clone(),
|
|
109
98
|
}
|
|
110
99
|
}
|
|
111
100
|
|
|
101
|
+
fn changed(&mut self, ctx: &Context<Self>, _old_props: &Self::Properties) -> bool {
|
|
102
|
+
self._subscriptions = register_listeners(ctx);
|
|
103
|
+
true
|
|
104
|
+
}
|
|
105
|
+
|
|
112
106
|
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
113
|
-
match msg {
|
|
114
|
-
StatusBarMsg::Reset(
|
|
107
|
+
maybe_log_or_default!(Ok(match msg {
|
|
108
|
+
StatusBarMsg::Reset(event) => {
|
|
109
|
+
let all = event.shift_key();
|
|
115
110
|
ctx.props().on_reset.emit(all);
|
|
116
111
|
false
|
|
117
112
|
},
|
|
118
113
|
StatusBarMsg::ResetTheme => {
|
|
119
|
-
|
|
120
|
-
ctx.props().renderer,
|
|
121
|
-
ctx.props().session,
|
|
122
|
-
ctx.props().presentation
|
|
123
|
-
);
|
|
124
|
-
|
|
114
|
+
let state = ctx.props().clone_state();
|
|
125
115
|
ApiFuture::spawn(async move {
|
|
126
|
-
presentation.reset_theme().await?;
|
|
127
|
-
let view = session.get_view().into_apierror()?;
|
|
128
|
-
renderer.restyle_all(&view).await
|
|
116
|
+
state.presentation.reset_theme().await?;
|
|
117
|
+
let view = state.session.get_view().into_apierror()?;
|
|
118
|
+
state.renderer.restyle_all(&view).await
|
|
129
119
|
});
|
|
130
120
|
true
|
|
131
121
|
},
|
|
@@ -137,133 +127,247 @@ impl Component for StatusBar {
|
|
|
137
127
|
should_render
|
|
138
128
|
},
|
|
139
129
|
StatusBarMsg::SetTheme(theme_name) => {
|
|
140
|
-
|
|
141
|
-
ctx.props().renderer,
|
|
142
|
-
ctx.props().session,
|
|
143
|
-
ctx.props().presentation
|
|
144
|
-
);
|
|
130
|
+
let state = ctx.props().clone_state();
|
|
145
131
|
ApiFuture::spawn(async move {
|
|
146
|
-
presentation.set_theme_name(Some(&theme_name)).await?;
|
|
147
|
-
let view = session.get_view().into_apierror()?;
|
|
148
|
-
renderer.restyle_all(&view).await
|
|
132
|
+
state.presentation.set_theme_name(Some(&theme_name)).await?;
|
|
133
|
+
let view = state.session.get_view().into_apierror()?;
|
|
134
|
+
state.renderer.restyle_all(&view).await
|
|
149
135
|
});
|
|
150
136
|
|
|
151
137
|
false
|
|
152
138
|
},
|
|
153
139
|
StatusBarMsg::Export => {
|
|
154
|
-
let target = self.export_ref.cast::<HtmlElement>().
|
|
140
|
+
let target = self.export_ref.cast::<HtmlElement>().into_apierror()?;
|
|
155
141
|
ExportDropDownMenuElement::new_from_model(ctx.props()).open(target);
|
|
156
142
|
false
|
|
157
143
|
},
|
|
158
144
|
StatusBarMsg::Copy => {
|
|
159
|
-
let target = self.copy_ref.cast::<HtmlElement>().
|
|
145
|
+
let target = self.copy_ref.cast::<HtmlElement>().into_apierror()?;
|
|
160
146
|
CopyDropDownMenuElement::new_from_model(ctx.props()).open(target);
|
|
161
147
|
false
|
|
162
148
|
},
|
|
163
|
-
StatusBarMsg::
|
|
164
|
-
|
|
165
|
-
ctx.props().presentation.set_title(title);
|
|
149
|
+
StatusBarMsg::Eject => {
|
|
150
|
+
ctx.props().presentation().on_eject.emit(());
|
|
166
151
|
false
|
|
167
152
|
},
|
|
168
|
-
|
|
153
|
+
StatusBarMsg::Noop => {
|
|
154
|
+
self.title = ctx.props().session().get_title();
|
|
155
|
+
true
|
|
156
|
+
},
|
|
157
|
+
StatusBarMsg::TitleInputEvent => {
|
|
158
|
+
let elem = self.input_ref.cast::<HtmlInputElement>().into_apierror()?;
|
|
159
|
+
let title = elem.value();
|
|
160
|
+
let title = if title.trim().is_empty() {
|
|
161
|
+
None
|
|
162
|
+
} else {
|
|
163
|
+
Some(title)
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
self.title = title;
|
|
167
|
+
true
|
|
168
|
+
},
|
|
169
|
+
StatusBarMsg::TitleChangeEvent => {
|
|
170
|
+
let elem = self.input_ref.cast::<HtmlInputElement>().into_apierror()?;
|
|
171
|
+
let title = elem.value();
|
|
172
|
+
let title = if title.trim().is_empty() {
|
|
173
|
+
None
|
|
174
|
+
} else {
|
|
175
|
+
Some(title)
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
ctx.props().session().set_title(title);
|
|
179
|
+
false
|
|
180
|
+
},
|
|
181
|
+
StatusBarMsg::PointerEvent(event) => {
|
|
182
|
+
if event.target().map(JsValue::from)
|
|
183
|
+
== self.statusbar_ref.cast::<HtmlElement>().map(JsValue::from)
|
|
184
|
+
{
|
|
185
|
+
ctx.props()
|
|
186
|
+
.custom_events()
|
|
187
|
+
.dispatch_event(format!("statusbar-{}", event.type_()).as_str(), &event)?;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
false
|
|
191
|
+
},
|
|
192
|
+
}))
|
|
169
193
|
}
|
|
170
194
|
|
|
171
195
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
196
|
+
let Self::Properties {
|
|
197
|
+
custom_events,
|
|
198
|
+
presentation,
|
|
199
|
+
renderer,
|
|
200
|
+
session,
|
|
201
|
+
..
|
|
202
|
+
} = ctx.props();
|
|
203
|
+
|
|
172
204
|
let mut is_updating_class_name = classes!();
|
|
173
|
-
if
|
|
174
|
-
is_updating_class_name.push("
|
|
205
|
+
if session.get_title().is_some() {
|
|
206
|
+
is_updating_class_name.push("titled");
|
|
175
207
|
};
|
|
176
208
|
|
|
177
|
-
if
|
|
178
|
-
is_updating_class_name.push("titled")
|
|
209
|
+
if !presentation.is_settings_open() {
|
|
210
|
+
is_updating_class_name.push(["settings-closed", "titled"]);
|
|
179
211
|
};
|
|
180
212
|
|
|
181
|
-
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
let export = ctx.link().callback(|_: MouseEvent| StatusBarMsg::Export);
|
|
186
|
-
let copy = ctx.link().callback(|_: MouseEvent| StatusBarMsg::Copy);
|
|
187
|
-
|
|
188
|
-
let onchange = ctx.link().callback({
|
|
189
|
-
move |input: Event| {
|
|
190
|
-
let title = input
|
|
191
|
-
.target()
|
|
192
|
-
.unwrap()
|
|
193
|
-
.unchecked_into::<HtmlInputElement>()
|
|
194
|
-
.value();
|
|
213
|
+
if !session.has_table() {
|
|
214
|
+
is_updating_class_name.push("updating");
|
|
215
|
+
}
|
|
195
216
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
217
|
+
// TODO Memoizing these would reduce some vdom diffing later on
|
|
218
|
+
let onblur = ctx.link().callback(|_| StatusBarMsg::Noop);
|
|
219
|
+
let onclose = ctx.link().callback(|_| StatusBarMsg::Eject);
|
|
220
|
+
let onpointerdown = ctx.link().callback(StatusBarMsg::PointerEvent);
|
|
221
|
+
let onexport = ctx.link().callback(|_: MouseEvent| StatusBarMsg::Export);
|
|
222
|
+
let oncopy = ctx.link().callback(|_: MouseEvent| StatusBarMsg::Copy);
|
|
223
|
+
let onreset = ctx.link().callback(StatusBarMsg::Reset);
|
|
224
|
+
let onchange = ctx
|
|
225
|
+
.link()
|
|
226
|
+
.callback(|_: Event| StatusBarMsg::TitleChangeEvent);
|
|
201
227
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
228
|
+
let oninput = ctx
|
|
229
|
+
.link()
|
|
230
|
+
.callback(|_: InputEvent| StatusBarMsg::TitleInputEvent);
|
|
205
231
|
|
|
206
|
-
let is_menu = ctx.props().
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
232
|
+
let is_menu = session.has_table() && ctx.props().on_settings.as_ref().is_none();
|
|
233
|
+
let is_title = is_menu
|
|
234
|
+
|| presentation.get_is_workspace()
|
|
235
|
+
|| session.get_title().is_some()
|
|
236
|
+
|| session.is_errored()
|
|
237
|
+
|| presentation.is_active(&self.input_ref.cast::<Element>());
|
|
210
238
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
239
|
+
let is_settings = session.get_title().is_some()
|
|
240
|
+
|| presentation.get_is_workspace()
|
|
241
|
+
|| !session.has_table()
|
|
242
|
+
|| session.is_errored()
|
|
243
|
+
|| presentation.is_settings_open()
|
|
244
|
+
|| presentation.is_active(&self.input_ref.cast::<Element>());
|
|
214
245
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
if is_settings {
|
|
247
|
+
html! {
|
|
248
|
+
<>
|
|
249
|
+
<LocalStyle href={css!("status-bar")} />
|
|
250
|
+
<div
|
|
251
|
+
ref={&self.statusbar_ref}
|
|
252
|
+
id={ctx.props().id.clone()}
|
|
253
|
+
class={is_updating_class_name}
|
|
254
|
+
{onpointerdown}
|
|
255
|
+
>
|
|
256
|
+
<StatusIndicator {custom_events} {renderer} {session} />
|
|
257
|
+
if is_title {
|
|
258
|
+
<label
|
|
259
|
+
class="input-sizer"
|
|
260
|
+
data-value={self.title.clone().unwrap_or_default()}
|
|
261
|
+
>
|
|
262
|
+
<input
|
|
263
|
+
ref={&self.input_ref}
|
|
264
|
+
placeholder=""
|
|
265
|
+
value={self.title.clone().unwrap_or_default()}
|
|
266
|
+
size="10"
|
|
267
|
+
{onblur}
|
|
268
|
+
{onchange}
|
|
269
|
+
{oninput}
|
|
270
|
+
/>
|
|
271
|
+
<span id="status-bar-placeholder" />
|
|
272
|
+
</label>
|
|
273
|
+
}
|
|
274
|
+
if is_title {
|
|
275
|
+
<StatusBarRowsCounter {session} />
|
|
276
|
+
}
|
|
277
|
+
<div id="spacer" />
|
|
278
|
+
if is_menu {
|
|
279
|
+
<div id="menu-bar" class="section">
|
|
280
|
+
<ThemeSelector
|
|
281
|
+
theme={self.theme.clone()}
|
|
282
|
+
themes={self.themes.clone()}
|
|
283
|
+
on_change={ctx.link().callback(StatusBarMsg::SetTheme)}
|
|
284
|
+
on_reset={ctx.link().callback(|_| StatusBarMsg::ResetTheme)}
|
|
285
|
+
/>
|
|
286
|
+
<div id="plugin-settings"><slot name="statusbar-extra" /></div>
|
|
287
|
+
<span class="hover-target">
|
|
288
|
+
<span id="reset" class="button" onmousedown={&onreset}>
|
|
289
|
+
<span />
|
|
290
|
+
</span>
|
|
291
|
+
</span>
|
|
292
|
+
<span
|
|
293
|
+
ref={&self.export_ref}
|
|
294
|
+
class="hover-target"
|
|
295
|
+
onmousedown={onexport}
|
|
296
|
+
>
|
|
297
|
+
<span id="export" class="button"><span /></span>
|
|
298
|
+
</span>
|
|
299
|
+
<span
|
|
300
|
+
ref={&self.copy_ref}
|
|
301
|
+
class="hover-target"
|
|
302
|
+
onmousedown={oncopy}
|
|
303
|
+
>
|
|
304
|
+
<span id="copy" class="button"><span /></span>
|
|
305
|
+
</span>
|
|
306
|
+
</div>
|
|
307
|
+
}
|
|
308
|
+
if let Some(x) = ctx.props().on_settings.as_ref() {
|
|
309
|
+
<div
|
|
310
|
+
id="settings_button"
|
|
311
|
+
class="noselect"
|
|
312
|
+
onmousedown={x.reform(|_| ())}
|
|
246
313
|
/>
|
|
247
|
-
<div id="
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
314
|
+
<div id="close_button" class="noselect" onmousedown={onclose} />
|
|
315
|
+
}
|
|
316
|
+
</div>
|
|
317
|
+
</>
|
|
318
|
+
}
|
|
319
|
+
} else if let Some(x) = ctx.props().on_settings.as_ref() {
|
|
320
|
+
let class = classes!(is_updating_class_name, "floating");
|
|
321
|
+
html! {
|
|
322
|
+
<div id={ctx.props().id.clone()} {class}>
|
|
323
|
+
<div id="settings_button" class="noselect" onmousedown={x.reform(|_| ())} />
|
|
324
|
+
<div id="close_button" class="noselect" onmousedown={&onclose} />
|
|
259
325
|
</div>
|
|
260
|
-
|
|
326
|
+
}
|
|
327
|
+
} else {
|
|
328
|
+
html! {}
|
|
261
329
|
}
|
|
262
330
|
}
|
|
263
331
|
}
|
|
264
332
|
|
|
333
|
+
fn register_listeners(ctx: &Context<StatusBar>) -> [Subscription; 5] {
|
|
334
|
+
[
|
|
335
|
+
ctx.props()
|
|
336
|
+
.presentation()
|
|
337
|
+
.theme_config_updated
|
|
338
|
+
.add_listener(ctx.link().callback(StatusBarMsg::SetThemeConfig)),
|
|
339
|
+
ctx.props()
|
|
340
|
+
.presentation()
|
|
341
|
+
.visibility_changed
|
|
342
|
+
.add_listener(ctx.link().callback(|_| StatusBarMsg::Noop)),
|
|
343
|
+
ctx.props()
|
|
344
|
+
.session()
|
|
345
|
+
.title_changed
|
|
346
|
+
.add_listener(ctx.link().callback(|_| StatusBarMsg::Noop)),
|
|
347
|
+
ctx.props()
|
|
348
|
+
.session()
|
|
349
|
+
.table_loaded
|
|
350
|
+
.add_listener(ctx.link().callback(|_| StatusBarMsg::Noop)),
|
|
351
|
+
ctx.props()
|
|
352
|
+
.session()
|
|
353
|
+
.table_errored
|
|
354
|
+
.add_listener(ctx.link().callback(|_| StatusBarMsg::Noop)),
|
|
355
|
+
]
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
fn fetch_initial_theme(ctx: &Context<StatusBar>) {
|
|
359
|
+
ApiFuture::spawn({
|
|
360
|
+
let on_theme = ctx.link().callback(StatusBarMsg::SetThemeConfig);
|
|
361
|
+
clone!(ctx.props().presentation());
|
|
362
|
+
async move {
|
|
363
|
+
on_theme.emit(presentation.get_selected_theme_config().await?);
|
|
364
|
+
Ok(())
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
265
369
|
#[derive(Properties, PartialEq)]
|
|
266
|
-
|
|
370
|
+
struct ThemeSelectorProps {
|
|
267
371
|
pub theme: Option<String>,
|
|
268
372
|
pub themes: Rc<Vec<String>>,
|
|
269
373
|
pub on_reset: Callback<()>,
|
|
@@ -271,7 +375,7 @@ pub struct ThemeSelectorProps {
|
|
|
271
375
|
}
|
|
272
376
|
|
|
273
377
|
#[function_component]
|
|
274
|
-
|
|
378
|
+
fn ThemeSelector(props: &ThemeSelectorProps) -> Html {
|
|
275
379
|
let is_first = props
|
|
276
380
|
.theme
|
|
277
381
|
.as_ref()
|