@perspective-dev/viewer 4.0.1 → 4.1.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 +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 +1242 -753
- 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 +367 -169
- 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/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-9a89352df1552d2b → perspective-viewer-11a3c51b6310ee99}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-11a3c51b6310ee99}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-11a3c51b6310ee99}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-11a3c51b6310ee99}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-9a89352df1552d2b → perspective-viewer-11a3c51b6310ee99}/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,20 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
use yew::prelude::*;
|
|
14
14
|
|
|
15
|
-
use crate::components::form::
|
|
15
|
+
use crate::components::form::select_enum_field::SelectEnumField;
|
|
16
16
|
use crate::components::modal::{ModalLink, SetModalLink};
|
|
17
17
|
use crate::config::*;
|
|
18
18
|
use crate::utils::WeakScope;
|
|
19
19
|
|
|
20
|
-
pub enum DatetimeStyleSimpleMsg {
|
|
21
|
-
DateStyleChanged(Option<SimpleDatetimeFormat>),
|
|
22
|
-
TimeStyleChanged(Option<SimpleDatetimeFormat>),
|
|
23
|
-
}
|
|
24
|
-
|
|
25
20
|
#[derive(Properties)]
|
|
26
21
|
pub struct DatetimeStyleSimpleProps {
|
|
27
22
|
pub enable_time_config: bool,
|
|
28
|
-
|
|
29
23
|
pub config: SimpleDatetimeStyleConfig,
|
|
30
24
|
|
|
31
25
|
#[prop_or_default]
|
|
@@ -47,6 +41,11 @@ impl PartialEq for DatetimeStyleSimpleProps {
|
|
|
47
41
|
}
|
|
48
42
|
}
|
|
49
43
|
|
|
44
|
+
pub enum DatetimeStyleSimpleMsg {
|
|
45
|
+
DateStyleChanged(Option<SimpleDatetimeFormat>),
|
|
46
|
+
TimeStyleChanged(Option<SimpleDatetimeFormat>),
|
|
47
|
+
}
|
|
48
|
+
|
|
50
49
|
/// `DatetimeStyleSimple` represents the variation of the options parameter to
|
|
51
50
|
/// `Intl.DatetimeFormat()` which supports `timeStyle` and `dateStyle`. These
|
|
52
51
|
/// options are mutually exclusive with those of `DatetimeStyleCustom`, hence
|
|
@@ -55,13 +54,6 @@ pub struct DatetimeStyleSimple {
|
|
|
55
54
|
config: SimpleDatetimeStyleConfig,
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
impl DatetimeStyleSimple {
|
|
59
|
-
/// When this config has changed, we must signal the wrapper element.
|
|
60
|
-
fn dispatch_config(&self, ctx: &Context<Self>) {
|
|
61
|
-
ctx.props().on_change.emit(self.config.clone());
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
57
|
impl Component for DatetimeStyleSimple {
|
|
66
58
|
type Message = DatetimeStyleSimpleMsg;
|
|
67
59
|
type Properties = DatetimeStyleSimpleProps;
|
|
@@ -120,3 +112,10 @@ impl Component for DatetimeStyleSimple {
|
|
|
120
112
|
}
|
|
121
113
|
}
|
|
122
114
|
}
|
|
115
|
+
|
|
116
|
+
impl DatetimeStyleSimple {
|
|
117
|
+
/// When this config has changed, we must signal the wrapper element.
|
|
118
|
+
fn dispatch_config(&self, ctx: &Context<Self>) {
|
|
119
|
+
ctx.props().on_change.emit(self.config.clone());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -28,54 +28,17 @@ use super::modal::{ModalLink, SetModalLink};
|
|
|
28
28
|
use super::style::LocalStyle;
|
|
29
29
|
use crate::components::datetime_column_style::custom::DatetimeStyleCustom;
|
|
30
30
|
use crate::components::datetime_column_style::simple::DatetimeStyleSimple;
|
|
31
|
-
use crate::components::form::
|
|
31
|
+
use crate::components::form::select_enum_field::SelectEnumField;
|
|
32
|
+
use crate::components::form::select_value_field::SelectValueField;
|
|
32
33
|
use crate::config::*;
|
|
34
|
+
use crate::css;
|
|
33
35
|
use crate::utils::WeakScope;
|
|
34
|
-
use crate::*;
|
|
35
|
-
|
|
36
|
-
#[wasm_bindgen]
|
|
37
|
-
extern "C" {
|
|
38
|
-
#[wasm_bindgen(js_name = supportedValuesOf, js_namespace = Intl)]
|
|
39
|
-
pub fn supported_values_of(s: &JsValue) -> js_sys::Array;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
thread_local! {
|
|
43
|
-
static ALL_TIMEZONES: LazyLock<Rc<Vec<String>>> = LazyLock::new(|| {
|
|
44
|
-
Rc::new(
|
|
45
|
-
supported_values_of(&JsValue::from("timeZone"))
|
|
46
|
-
.iter()
|
|
47
|
-
.map(|x| x.as_string().unwrap())
|
|
48
|
-
.collect(),
|
|
49
|
-
)
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
static USER_TIMEZONE: LazyLock<String> = LazyLock::new(|| {
|
|
54
|
-
js_sys::Reflect::get(
|
|
55
|
-
&js_sys::Intl::DateTimeFormat::new(&navigator().languages(), &json!({})).resolved_options(),
|
|
56
|
-
&JsValue::from("timeZone"),
|
|
57
|
-
)
|
|
58
|
-
.unwrap()
|
|
59
|
-
.as_string()
|
|
60
|
-
.unwrap()
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
pub enum DatetimeColumnStyleMsg {
|
|
64
|
-
SimpleDatetimeStyleConfigChanged(SimpleDatetimeStyleConfig),
|
|
65
|
-
CustomDatetimeStyleConfigChanged(CustomDatetimeStyleConfig),
|
|
66
|
-
TimezoneChanged(Option<String>),
|
|
67
|
-
ColorModeChanged(Option<DatetimeColorMode>),
|
|
68
|
-
ColorChanged(String),
|
|
69
|
-
ColorReset,
|
|
70
|
-
}
|
|
71
36
|
|
|
72
37
|
#[derive(Properties, Derivative)]
|
|
73
38
|
#[derivative(Debug)]
|
|
74
39
|
pub struct DatetimeColumnStyleProps {
|
|
75
40
|
pub enable_time_config: bool,
|
|
76
|
-
|
|
77
41
|
pub config: Option<DatetimeColumnStyleConfig>,
|
|
78
|
-
|
|
79
42
|
pub default_config: DatetimeColumnStyleDefaultConfig,
|
|
80
43
|
|
|
81
44
|
#[prop_or_default]
|
|
@@ -98,6 +61,15 @@ impl PartialEq for DatetimeColumnStyleProps {
|
|
|
98
61
|
}
|
|
99
62
|
}
|
|
100
63
|
|
|
64
|
+
pub enum DatetimeColumnStyleMsg {
|
|
65
|
+
SimpleDatetimeStyleConfigChanged(SimpleDatetimeStyleConfig),
|
|
66
|
+
CustomDatetimeStyleConfigChanged(CustomDatetimeStyleConfig),
|
|
67
|
+
TimezoneChanged(Option<String>),
|
|
68
|
+
ColorModeChanged(Option<DatetimeColorMode>),
|
|
69
|
+
ColorChanged(String),
|
|
70
|
+
ColorReset,
|
|
71
|
+
}
|
|
72
|
+
|
|
101
73
|
/// Column style controls for the `datetime` type.
|
|
102
74
|
#[derive(Debug)]
|
|
103
75
|
pub struct DatetimeColumnStyle {
|
|
@@ -105,42 +77,6 @@ pub struct DatetimeColumnStyle {
|
|
|
105
77
|
default_config: DatetimeColumnStyleDefaultConfig,
|
|
106
78
|
}
|
|
107
79
|
|
|
108
|
-
impl DatetimeColumnStyle {
|
|
109
|
-
/// When this config has changed, we must signal the wrapper element.
|
|
110
|
-
fn dispatch_config(&self, ctx: &Context<Self>) {
|
|
111
|
-
let update =
|
|
112
|
-
Some(self.config.clone()).filter(|x| x != &DatetimeColumnStyleConfig::default());
|
|
113
|
-
ctx.props()
|
|
114
|
-
.on_change
|
|
115
|
-
.emit(ColumnConfigValueUpdate::DatagridDatetimeStyle(update));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/// Generate a color selector component for a specific `StringColorMode`
|
|
119
|
-
/// variant.
|
|
120
|
-
fn color_select_row(&self, ctx: &Context<Self>, mode: &DatetimeColorMode, title: &str) -> Html {
|
|
121
|
-
let on_color = ctx.link().callback(DatetimeColumnStyleMsg::ColorChanged);
|
|
122
|
-
let color = self
|
|
123
|
-
.config
|
|
124
|
-
.color
|
|
125
|
-
.clone()
|
|
126
|
-
.unwrap_or_else(|| self.default_config.color.to_owned());
|
|
127
|
-
|
|
128
|
-
let color_props = props!(ColorProps {
|
|
129
|
-
title: title.to_owned(),
|
|
130
|
-
on_color,
|
|
131
|
-
is_modified: color != self.default_config.color,
|
|
132
|
-
color,
|
|
133
|
-
on_reset: ctx.link().callback(|_| DatetimeColumnStyleMsg::ColorReset)
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
if &self.config.datetime_color_mode == mode {
|
|
137
|
-
html! { <div class="row"><ColorSelector ..color_props /></div> }
|
|
138
|
-
} else {
|
|
139
|
-
html! {}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
80
|
impl Component for DatetimeColumnStyle {
|
|
145
81
|
type Message = DatetimeColumnStyleMsg;
|
|
146
82
|
type Properties = DatetimeColumnStyleProps;
|
|
@@ -282,3 +218,66 @@ impl Component for DatetimeColumnStyle {
|
|
|
282
218
|
}
|
|
283
219
|
}
|
|
284
220
|
}
|
|
221
|
+
|
|
222
|
+
#[wasm_bindgen]
|
|
223
|
+
extern "C" {
|
|
224
|
+
#[wasm_bindgen(js_name = supportedValuesOf, js_namespace = Intl)]
|
|
225
|
+
pub fn supported_values_of(s: &JsValue) -> js_sys::Array;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
thread_local! {
|
|
229
|
+
static ALL_TIMEZONES: LazyLock<Rc<Vec<String>>> = LazyLock::new(|| {
|
|
230
|
+
Rc::new(
|
|
231
|
+
supported_values_of(&JsValue::from("timeZone"))
|
|
232
|
+
.iter()
|
|
233
|
+
.map(|x| x.as_string().unwrap())
|
|
234
|
+
.collect(),
|
|
235
|
+
)
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static USER_TIMEZONE: LazyLock<String> = LazyLock::new(|| {
|
|
240
|
+
js_sys::Reflect::get(
|
|
241
|
+
&js_sys::Intl::DateTimeFormat::new(&navigator().languages(), &json!({})).resolved_options(),
|
|
242
|
+
&JsValue::from("timeZone"),
|
|
243
|
+
)
|
|
244
|
+
.unwrap()
|
|
245
|
+
.as_string()
|
|
246
|
+
.unwrap()
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
impl DatetimeColumnStyle {
|
|
250
|
+
/// When this config has changed, we must signal the wrapper element.
|
|
251
|
+
fn dispatch_config(&self, ctx: &Context<Self>) {
|
|
252
|
+
let update =
|
|
253
|
+
Some(self.config.clone()).filter(|x| x != &DatetimeColumnStyleConfig::default());
|
|
254
|
+
ctx.props()
|
|
255
|
+
.on_change
|
|
256
|
+
.emit(ColumnConfigValueUpdate::DatagridDatetimeStyle(update));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/// Generate a color selector component for a specific `StringColorMode`
|
|
260
|
+
/// variant.
|
|
261
|
+
fn color_select_row(&self, ctx: &Context<Self>, mode: &DatetimeColorMode, title: &str) -> Html {
|
|
262
|
+
let on_color = ctx.link().callback(DatetimeColumnStyleMsg::ColorChanged);
|
|
263
|
+
let color = self
|
|
264
|
+
.config
|
|
265
|
+
.color
|
|
266
|
+
.clone()
|
|
267
|
+
.unwrap_or_else(|| self.default_config.color.to_owned());
|
|
268
|
+
|
|
269
|
+
let color_props = props!(ColorProps {
|
|
270
|
+
title: title.to_owned(),
|
|
271
|
+
on_color,
|
|
272
|
+
is_modified: color != self.default_config.color,
|
|
273
|
+
color,
|
|
274
|
+
on_reset: ctx.link().callback(|_| DatetimeColumnStyleMsg::ColorReset)
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
if &self.config.datetime_color_mode == mode {
|
|
278
|
+
html! { <div class="row"><ColorSelector ..color_props /></div> }
|
|
279
|
+
} else {
|
|
280
|
+
html! {}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -12,29 +12,30 @@
|
|
|
12
12
|
|
|
13
13
|
use std::rc::Rc;
|
|
14
14
|
|
|
15
|
-
use derivative::Derivative;
|
|
16
15
|
use itertools::Itertools;
|
|
17
16
|
use web_sys::{FocusEvent, HtmlInputElement, KeyboardEvent};
|
|
18
17
|
use yew::{Callback, Component, Html, NodeRef, Properties, TargetCast, classes, html};
|
|
19
18
|
|
|
20
19
|
use super::type_icon::TypeIconType;
|
|
21
20
|
use crate::components::type_icon::TypeIcon;
|
|
22
|
-
use crate::maybe;
|
|
23
21
|
use crate::session::Session;
|
|
22
|
+
use crate::*;
|
|
24
23
|
|
|
25
|
-
#[derive(PartialEq, Properties,
|
|
26
|
-
#[derivative(Debug)]
|
|
24
|
+
#[derive(Clone, PartialEq, Properties, PerspectiveProperties!)]
|
|
27
25
|
pub struct EditableHeaderProps {
|
|
28
26
|
pub icon_type: Option<TypeIconType>,
|
|
29
27
|
pub on_change: Callback<(Option<String>, bool)>,
|
|
30
28
|
pub editable: bool,
|
|
31
29
|
pub initial_value: Option<String>,
|
|
32
30
|
pub placeholder: Rc<String>,
|
|
31
|
+
|
|
33
32
|
#[prop_or_default]
|
|
34
33
|
pub reset_count: u8,
|
|
35
|
-
|
|
34
|
+
|
|
35
|
+
// State
|
|
36
36
|
pub session: Session,
|
|
37
37
|
}
|
|
38
|
+
|
|
38
39
|
impl EditableHeaderProps {
|
|
39
40
|
fn split_placeholder(&self) -> String {
|
|
40
41
|
let split = self
|
|
@@ -42,6 +43,7 @@ impl EditableHeaderProps {
|
|
|
42
43
|
.split_once('\n')
|
|
43
44
|
.map(|(a, _)| a)
|
|
44
45
|
.unwrap_or(&*self.placeholder);
|
|
46
|
+
|
|
45
47
|
match split.char_indices().nth(25) {
|
|
46
48
|
None => split.to_string(),
|
|
47
49
|
Some((idx, _)) => split[..idx].to_owned(),
|
|
@@ -49,19 +51,12 @@ impl EditableHeaderProps {
|
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
#[derive(Default, Debug, PartialEq, Copy, Clone)]
|
|
53
|
-
pub enum ValueState {
|
|
54
|
-
#[default]
|
|
55
|
-
Unedited,
|
|
56
|
-
Edited,
|
|
57
|
-
}
|
|
58
|
-
|
|
59
54
|
pub enum EditableHeaderMsg {
|
|
60
55
|
SetNewValue(String),
|
|
61
56
|
OnClick(()),
|
|
62
57
|
}
|
|
63
58
|
|
|
64
|
-
#[derive(
|
|
59
|
+
#[derive(Debug)]
|
|
65
60
|
pub struct EditableHeader {
|
|
66
61
|
noderef: NodeRef,
|
|
67
62
|
edited: bool,
|
|
@@ -69,6 +64,7 @@ pub struct EditableHeader {
|
|
|
69
64
|
value: Option<String>,
|
|
70
65
|
placeholder: String,
|
|
71
66
|
}
|
|
67
|
+
|
|
72
68
|
impl Component for EditableHeader {
|
|
73
69
|
type Message = EditableHeaderMsg;
|
|
74
70
|
type Properties = EditableHeaderProps;
|
|
@@ -78,7 +74,8 @@ impl Component for EditableHeader {
|
|
|
78
74
|
value: ctx.props().initial_value.clone(),
|
|
79
75
|
placeholder: ctx.props().split_placeholder(),
|
|
80
76
|
valid: true,
|
|
81
|
-
|
|
77
|
+
noderef: NodeRef::default(),
|
|
78
|
+
edited: false,
|
|
82
79
|
}
|
|
83
80
|
}
|
|
84
81
|
|
|
@@ -181,3 +178,10 @@ impl Component for EditableHeader {
|
|
|
181
178
|
}
|
|
182
179
|
}
|
|
183
180
|
}
|
|
181
|
+
|
|
182
|
+
#[derive(Default, Debug, PartialEq, Copy, Clone)]
|
|
183
|
+
pub enum ValueState {
|
|
184
|
+
#[default]
|
|
185
|
+
Unedited,
|
|
186
|
+
Edited,
|
|
187
|
+
}
|
|
@@ -23,11 +23,6 @@ use crate::components::style::LocalStyle;
|
|
|
23
23
|
use crate::css;
|
|
24
24
|
use crate::custom_elements::FilterDropDownElement;
|
|
25
25
|
|
|
26
|
-
#[derive(Default)]
|
|
27
|
-
pub struct EmptyRow {
|
|
28
|
-
input_ref: NodeRef,
|
|
29
|
-
}
|
|
30
|
-
|
|
31
26
|
#[derive(Properties, Derivative)]
|
|
32
27
|
#[derivative(Debug)]
|
|
33
28
|
pub struct EmptyRowProps {
|
|
@@ -57,6 +52,11 @@ pub enum EmptyRowMsg {
|
|
|
57
52
|
|
|
58
53
|
use EmptyRowMsg::*;
|
|
59
54
|
|
|
55
|
+
#[derive(Default)]
|
|
56
|
+
pub struct EmptyRow {
|
|
57
|
+
input_ref: NodeRef,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
60
|
impl Component for EmptyRow {
|
|
61
61
|
type Message = EmptyRowMsg;
|
|
62
62
|
type Properties = EmptyRowProps;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
use std::rc::Rc;
|
|
14
14
|
|
|
15
|
-
use
|
|
15
|
+
use session::Session;
|
|
16
16
|
use yew::prelude::*;
|
|
17
17
|
|
|
18
18
|
use super::containers::dropdown_menu::*;
|
|
@@ -28,7 +28,7 @@ pub type ExportDropDownMenuItem = DropDownMenuItem<ExportFile>;
|
|
|
28
28
|
#[derive(Properties, PartialEq)]
|
|
29
29
|
pub struct ExportDropDownMenuProps {
|
|
30
30
|
pub renderer: Renderer,
|
|
31
|
-
pub
|
|
31
|
+
pub session: Session,
|
|
32
32
|
pub callback: Callback<ExportFile>,
|
|
33
33
|
pub root: web_sys::HtmlElement,
|
|
34
34
|
|
|
@@ -42,6 +42,10 @@ impl ModalLink<ExportDropDownMenu> for ExportDropDownMenuProps {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
pub enum ExportDropDownMenuMsg {
|
|
46
|
+
TitleChange,
|
|
47
|
+
}
|
|
48
|
+
|
|
45
49
|
#[derive(Default)]
|
|
46
50
|
pub struct ExportDropDownMenu {
|
|
47
51
|
title: String,
|
|
@@ -50,45 +54,6 @@ pub struct ExportDropDownMenu {
|
|
|
50
54
|
invalid: bool,
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
pub enum ExportDropDownMenuMsg {
|
|
54
|
-
TitleChange,
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
fn get_menu_items(name: &str, is_chart: bool) -> Vec<ExportDropDownMenuItem> {
|
|
58
|
-
vec![
|
|
59
|
-
ExportDropDownMenuItem::OptGroup(
|
|
60
|
-
"Current View".into(),
|
|
61
|
-
if is_chart {
|
|
62
|
-
vec![
|
|
63
|
-
ExportMethod::Csv.new_file(name, is_chart),
|
|
64
|
-
ExportMethod::Json.new_file(name, is_chart),
|
|
65
|
-
ExportMethod::Ndjson.new_file(name, is_chart),
|
|
66
|
-
ExportMethod::Arrow.new_file(name, is_chart),
|
|
67
|
-
ExportMethod::Html.new_file(name, is_chart),
|
|
68
|
-
ExportMethod::Plugin.new_file(name, is_chart),
|
|
69
|
-
]
|
|
70
|
-
} else {
|
|
71
|
-
vec![
|
|
72
|
-
ExportMethod::Csv.new_file(name, is_chart),
|
|
73
|
-
ExportMethod::Json.new_file(name, is_chart),
|
|
74
|
-
ExportMethod::Ndjson.new_file(name, is_chart),
|
|
75
|
-
ExportMethod::Arrow.new_file(name, is_chart),
|
|
76
|
-
ExportMethod::Html.new_file(name, is_chart),
|
|
77
|
-
]
|
|
78
|
-
},
|
|
79
|
-
),
|
|
80
|
-
ExportDropDownMenuItem::OptGroup("All".into(), vec![
|
|
81
|
-
ExportMethod::CsvAll.new_file(name, is_chart),
|
|
82
|
-
ExportMethod::JsonAll.new_file(name, is_chart),
|
|
83
|
-
ExportMethod::NdjsonAll.new_file(name, is_chart),
|
|
84
|
-
ExportMethod::ArrowAll.new_file(name, is_chart),
|
|
85
|
-
]),
|
|
86
|
-
ExportDropDownMenuItem::OptGroup("Config".into(), vec![
|
|
87
|
-
ExportMethod::JsonConfig.new_file(name, is_chart),
|
|
88
|
-
]),
|
|
89
|
-
]
|
|
90
|
-
}
|
|
91
|
-
|
|
92
57
|
impl Component for ExportDropDownMenu {
|
|
93
58
|
type Message = ExportDropDownMenuMsg;
|
|
94
59
|
type Properties = ExportDropDownMenuProps;
|
|
@@ -143,7 +108,7 @@ impl Component for ExportDropDownMenu {
|
|
|
143
108
|
Self {
|
|
144
109
|
title: ctx
|
|
145
110
|
.props()
|
|
146
|
-
.
|
|
111
|
+
.session
|
|
147
112
|
.get_title()
|
|
148
113
|
.unwrap_or_else(|| "untitled".to_owned()),
|
|
149
114
|
_sub,
|
|
@@ -151,3 +116,38 @@ impl Component for ExportDropDownMenu {
|
|
|
151
116
|
}
|
|
152
117
|
}
|
|
153
118
|
}
|
|
119
|
+
|
|
120
|
+
fn get_menu_items(name: &str, is_chart: bool) -> Vec<ExportDropDownMenuItem> {
|
|
121
|
+
vec![
|
|
122
|
+
ExportDropDownMenuItem::OptGroup(
|
|
123
|
+
"Current View".into(),
|
|
124
|
+
if is_chart {
|
|
125
|
+
vec![
|
|
126
|
+
ExportMethod::Csv.new_file(name, is_chart),
|
|
127
|
+
ExportMethod::Json.new_file(name, is_chart),
|
|
128
|
+
ExportMethod::Ndjson.new_file(name, is_chart),
|
|
129
|
+
ExportMethod::Arrow.new_file(name, is_chart),
|
|
130
|
+
ExportMethod::Html.new_file(name, is_chart),
|
|
131
|
+
ExportMethod::Plugin.new_file(name, is_chart),
|
|
132
|
+
]
|
|
133
|
+
} else {
|
|
134
|
+
vec![
|
|
135
|
+
ExportMethod::Csv.new_file(name, is_chart),
|
|
136
|
+
ExportMethod::Json.new_file(name, is_chart),
|
|
137
|
+
ExportMethod::Ndjson.new_file(name, is_chart),
|
|
138
|
+
ExportMethod::Arrow.new_file(name, is_chart),
|
|
139
|
+
ExportMethod::Html.new_file(name, is_chart),
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
),
|
|
143
|
+
ExportDropDownMenuItem::OptGroup("All".into(), vec![
|
|
144
|
+
ExportMethod::CsvAll.new_file(name, is_chart),
|
|
145
|
+
ExportMethod::JsonAll.new_file(name, is_chart),
|
|
146
|
+
ExportMethod::NdjsonAll.new_file(name, is_chart),
|
|
147
|
+
ExportMethod::ArrowAll.new_file(name, is_chart),
|
|
148
|
+
]),
|
|
149
|
+
ExportDropDownMenuItem::OptGroup("Config".into(), vec![
|
|
150
|
+
ExportMethod::JsonConfig.new_file(name, is_chart),
|
|
151
|
+
]),
|
|
152
|
+
]
|
|
153
|
+
}
|
|
@@ -17,35 +17,29 @@ use yew::prelude::*;
|
|
|
17
17
|
|
|
18
18
|
use super::form::code_editor::*;
|
|
19
19
|
use super::style::LocalStyle;
|
|
20
|
+
use crate::model::*;
|
|
20
21
|
use crate::session::Session;
|
|
21
22
|
use crate::*;
|
|
22
23
|
|
|
23
|
-
#[derive(
|
|
24
|
-
pub enum ExpressionEditorMsg {
|
|
25
|
-
SetExpr(Rc<String>),
|
|
26
|
-
ValidateComplete(Option<ExprValidationError>),
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
#[derive(Properties, PartialEq, Clone)]
|
|
24
|
+
#[derive(Properties, PartialEq, PerspectiveProperties!, Clone)]
|
|
30
25
|
pub struct ExpressionEditorProps {
|
|
31
|
-
pub session: Session,
|
|
32
26
|
pub on_save: Callback<()>,
|
|
33
27
|
pub on_validate: Callback<bool>,
|
|
34
28
|
pub on_input: Callback<Rc<String>>,
|
|
35
29
|
pub alias: Option<String>,
|
|
36
30
|
pub disabled: bool,
|
|
31
|
+
|
|
37
32
|
#[prop_or_default]
|
|
38
33
|
pub reset_count: u8,
|
|
34
|
+
|
|
35
|
+
// State
|
|
36
|
+
pub session: Session,
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
.and_then(|alias| self.session.metadata().get_expression_by_alias(alias))
|
|
46
|
-
.unwrap_or_default()
|
|
47
|
-
.into()
|
|
48
|
-
}
|
|
39
|
+
#[derive(Debug)]
|
|
40
|
+
pub enum ExpressionEditorMsg {
|
|
41
|
+
SetExpr(Rc<String>),
|
|
42
|
+
ValidateComplete(Option<ExprValidationError>),
|
|
49
43
|
}
|
|
50
44
|
|
|
51
45
|
/// Expression editor component `CodeEditor` and a button toolbar.
|
|
@@ -61,7 +55,7 @@ impl Component for ExpressionEditor {
|
|
|
61
55
|
|
|
62
56
|
fn create(ctx: &Context<Self>) -> Self {
|
|
63
57
|
let oninput = ctx.link().callback(ExpressionEditorMsg::SetExpr);
|
|
64
|
-
let expr = ctx.props().
|
|
58
|
+
let expr = initial_expr(&ctx.props().session, &ctx.props().alias);
|
|
65
59
|
ctx.link()
|
|
66
60
|
.send_message(Self::Message::SetExpr(expr.clone()));
|
|
67
61
|
|
|
@@ -95,12 +89,13 @@ impl Component for ExpressionEditor {
|
|
|
95
89
|
if self.error.is_none() {
|
|
96
90
|
maybe!({
|
|
97
91
|
let alias = ctx.props().alias.as_ref()?;
|
|
98
|
-
let session =
|
|
92
|
+
let session = ctx.props().session();
|
|
99
93
|
let old = session.metadata().get_expression_by_alias(alias)?;
|
|
100
94
|
let is_edited = *self.expr != old;
|
|
101
95
|
session
|
|
102
96
|
.metadata_mut()
|
|
103
97
|
.set_edit_by_alias(alias, self.expr.to_string());
|
|
98
|
+
|
|
104
99
|
Some(is_edited)
|
|
105
100
|
});
|
|
106
101
|
|
|
@@ -144,10 +139,21 @@ impl Component for ExpressionEditor {
|
|
|
144
139
|
if ctx.props().alias != old_props.alias || ctx.props().reset_count != old_props.reset_count
|
|
145
140
|
{
|
|
146
141
|
ctx.link()
|
|
147
|
-
.send_message(ExpressionEditorMsg::SetExpr(
|
|
142
|
+
.send_message(ExpressionEditorMsg::SetExpr(initial_expr(
|
|
143
|
+
&ctx.props().session,
|
|
144
|
+
&ctx.props().alias,
|
|
145
|
+
)));
|
|
148
146
|
false
|
|
149
147
|
} else {
|
|
150
148
|
true
|
|
151
149
|
}
|
|
152
150
|
}
|
|
153
151
|
}
|
|
152
|
+
|
|
153
|
+
fn initial_expr(session: &Session, alias: &Option<String>) -> Rc<String> {
|
|
154
|
+
alias
|
|
155
|
+
.as_ref()
|
|
156
|
+
.and_then(|alias| session.metadata().get_expression_by_alias(alias))
|
|
157
|
+
.unwrap_or_default()
|
|
158
|
+
.into()
|
|
159
|
+
}
|
|
@@ -18,6 +18,18 @@ use crate::utils::WeakScope;
|
|
|
18
18
|
|
|
19
19
|
static CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/css/filter-dropdown.css"));
|
|
20
20
|
|
|
21
|
+
#[derive(Properties, PartialEq)]
|
|
22
|
+
pub struct FilterDropDownProps {
|
|
23
|
+
#[prop_or_default]
|
|
24
|
+
pub weak_link: WeakScope<FilterDropDown>,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
impl ModalLink<FilterDropDown> for FilterDropDownProps {
|
|
28
|
+
fn weak_link(&self) -> &'_ WeakScope<FilterDropDown> {
|
|
29
|
+
&self.weak_link
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
21
33
|
pub enum FilterDropDownMsg {
|
|
22
34
|
SetValues(Vec<String>),
|
|
23
35
|
SetCallback(Callback<String>),
|
|
@@ -32,18 +44,6 @@ pub struct FilterDropDown {
|
|
|
32
44
|
on_select: Option<Callback<String>>,
|
|
33
45
|
}
|
|
34
46
|
|
|
35
|
-
#[derive(Properties, PartialEq)]
|
|
36
|
-
pub struct FilterDropDownProps {
|
|
37
|
-
#[prop_or_default]
|
|
38
|
-
pub weak_link: WeakScope<FilterDropDown>,
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
impl ModalLink<FilterDropDown> for FilterDropDownProps {
|
|
42
|
-
fn weak_link(&self) -> &'_ WeakScope<FilterDropDown> {
|
|
43
|
-
&self.weak_link
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
47
|
impl Component for FilterDropDown {
|
|
48
48
|
type Message = FilterDropDownMsg;
|
|
49
49
|
type Properties = FilterDropDownProps;
|
|
@@ -87,20 +87,20 @@ impl Component for FilterDropDown {
|
|
|
87
87
|
},
|
|
88
88
|
FilterDropDownMsg::ItemDown => {
|
|
89
89
|
self.selected += 1;
|
|
90
|
-
if let Some(ref values) = self.values
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
if let Some(ref values) = self.values {
|
|
91
|
+
if self.selected >= values.len() {
|
|
92
|
+
self.selected = 0;
|
|
93
|
+
}
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
true
|
|
97
97
|
},
|
|
98
98
|
FilterDropDownMsg::ItemUp => {
|
|
99
|
-
if let Some(ref values) = self.values
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
99
|
+
if let Some(ref values) = self.values {
|
|
100
|
+
if self.selected < 1 {
|
|
101
|
+
self.selected = values.len();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
104
|
|
|
105
105
|
self.selected -= 1;
|
|
106
106
|
true
|
|
@@ -139,6 +139,6 @@ impl Component for FilterDropDown {
|
|
|
139
139
|
}
|
|
140
140
|
};
|
|
141
141
|
|
|
142
|
-
html! { <><style>{
|
|
142
|
+
html! { <><style>{ CSS }</style>{ body }</> }
|
|
143
143
|
}
|
|
144
144
|
}
|