@perspective-dev/viewer 5.1.0 → 5.3.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 +9 -9
- package/dist/cdn/perspective-viewer.js.map +4 -4
- package/dist/css/botanical.css +1 -1
- package/dist/css/dracula.css +1 -1
- package/dist/css/gruvbox-dark.css +1 -1
- package/dist/css/gruvbox.css +1 -1
- package/dist/css/icons.css +1 -1
- package/dist/css/intl/de.css +1 -1
- package/dist/css/intl/es.css +1 -1
- package/dist/css/intl/fr.css +1 -1
- package/dist/css/intl/ja.css +1 -1
- package/dist/css/intl/pt.css +1 -1
- package/dist/css/intl/zh.css +1 -1
- package/dist/css/intl.css +1 -1
- package/dist/css/monokai.css +1 -1
- package/dist/css/phosphor.css +1 -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/docs/perspective-docs.json +1 -0
- package/dist/esm/column-format.d.ts +19 -28
- package/dist/esm/perspective-viewer.d.ts +3 -0
- package/dist/esm/perspective-viewer.inline.js +9 -9
- package/dist/esm/perspective-viewer.inline.js.map +4 -4
- package/dist/esm/perspective-viewer.js +9 -9
- package/dist/esm/perspective-viewer.js.map +4 -4
- package/dist/esm/plugin.d.ts +10 -0
- package/dist/esm/providers.d.ts +79 -0
- package/dist/esm/ts-rs/CompactDisplay.d.ts +5 -0
- package/dist/esm/ts-rs/CurrencyCode.d.ts +1 -0
- package/dist/esm/ts-rs/CurrencyDisplay.d.ts +1 -0
- package/dist/esm/ts-rs/CurrencyNumberFormatStyle.d.ts +8 -0
- package/dist/esm/ts-rs/CurrencySign.d.ts +1 -0
- package/dist/esm/ts-rs/CustomDatetimeFormat.d.ts +1 -0
- package/dist/esm/ts-rs/CustomDatetimeStyleConfig.d.ts +54 -0
- package/dist/esm/ts-rs/CustomNumberFormatConfig.d.ts +34 -0
- package/dist/esm/ts-rs/DatetimeColorMode.d.ts +1 -0
- package/dist/esm/ts-rs/DatetimeFormatType.d.ts +6 -0
- package/dist/esm/ts-rs/FormatMode.d.ts +1 -0
- package/dist/esm/ts-rs/FormatUnit.d.ts +1 -0
- package/dist/esm/ts-rs/Notation.d.ts +17 -0
- package/dist/esm/ts-rs/NumberFormatStyle.d.ts +18 -0
- package/dist/esm/ts-rs/PanelViewerConfig.d.ts +42 -2
- package/dist/esm/ts-rs/PluginStaticConfig.d.ts +35 -0
- package/dist/esm/ts-rs/RestoreOptions.d.ts +19 -0
- package/dist/esm/ts-rs/RoundingMode.d.ts +1 -0
- package/dist/esm/ts-rs/RoundingPriority.d.ts +1 -0
- package/dist/esm/ts-rs/SaveWorkspaceOptions.d.ts +10 -0
- package/dist/esm/ts-rs/SignDisplay.d.ts +1 -0
- package/dist/esm/ts-rs/SimpleDatetimeFormat.d.ts +1 -0
- package/dist/esm/ts-rs/SimpleDatetimeStyleConfig.d.ts +24 -0
- package/dist/esm/ts-rs/SplitRollupMode.d.ts +9 -0
- package/dist/esm/ts-rs/StringColorMode.d.ts +1 -0
- package/dist/esm/ts-rs/TrailingZeroDisplay.d.ts +1 -0
- package/dist/esm/ts-rs/Unit.d.ts +1 -0
- package/dist/esm/ts-rs/UnitDisplay.d.ts +1 -0
- package/dist/esm/ts-rs/UnitNumberFormatStyle.d.ts +6 -0
- package/dist/esm/ts-rs/UseGrouping.d.ts +1 -0
- package/dist/esm/ts-rs/ViewerConfig.d.ts +42 -2
- package/dist/esm/ts-rs/ViewerConfigInitial.d.ts +175 -0
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +63 -0
- package/dist/esm/ts-rs/WindowSpec.d.ts +3 -2
- package/dist/esm/ts-rs/WorkspaceConfig.d.ts +9 -1
- package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +20 -9
- package/dist/wasm/perspective-viewer.d.ts +157 -41
- package/dist/wasm/perspective-viewer.js +452 -151
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +22 -17
- package/package.json +2 -1
- package/src/css/_viewer_bundle.css +1 -0
- package/src/css/column-selector.css +8 -0
- package/src/css/column-settings-panel.css +9 -5
- package/src/css/column-style.css +209 -31
- package/src/css/config-selector.css +38 -3
- package/src/css/dom/select.css +2 -1
- package/src/css/form/code-editor.css +6 -7
- package/src/css/form/mirrored-textarea.css +81 -0
- package/src/css/viewer.css +328 -0
- package/src/rust/agent/client/mod.rs +19 -0
- package/src/rust/agent/client/protocol.rs +320 -0
- package/src/rust/agent/client/transport.rs +287 -0
- package/src/rust/agent/client/turn.rs +174 -0
- package/src/rust/agent/config.rs +159 -0
- package/src/rust/agent/docs.rs +293 -0
- package/src/rust/agent/markdown/block.rs +509 -0
- package/src/rust/agent/markdown/entity.rs +52 -0
- package/src/rust/agent/markdown/events.rs +71 -0
- package/src/rust/agent/markdown/inline.rs +497 -0
- package/src/rust/agent/markdown/mod.rs +466 -0
- package/src/rust/agent/mod.rs +23 -0
- package/src/rust/agent/preamble.md +16 -0
- package/src/rust/agent/runtime.rs +201 -0
- package/src/rust/agent/slot.rs +236 -0
- package/src/rust/agent/tools.rs +1141 -0
- package/src/rust/components/chat_panel.rs +289 -0
- package/src/rust/components/column_selector/active_column.rs +2 -2
- package/src/rust/components/column_selector/add_expression_button.rs +3 -3
- package/src/rust/components/column_selector/aggregate_selector.rs +2 -3
- package/src/rust/components/column_selector/config_selector.rs +84 -7
- package/src/rust/components/column_selector/expr_edit_button.rs +4 -10
- package/src/rust/components/column_selector/inactive_column.rs +2 -2
- package/src/rust/components/column_selector.rs +55 -4
- package/src/rust/components/column_settings_sidebar/style_tab/primitive_field.rs +293 -126
- package/src/rust/components/column_settings_sidebar/style_tab.rs +262 -225
- package/src/rust/components/column_settings_sidebar.rs +88 -69
- package/src/rust/components/containers/dragdrop_list.rs +37 -0
- package/src/rust/components/editable_header.rs +85 -144
- package/src/rust/components/expression_editor.rs +9 -16
- package/src/rust/components/form/code_editor.rs +29 -28
- package/src/rust/components/form/debug.rs +9 -5
- package/src/rust/components/form/mirrored_textarea.rs +165 -0
- package/src/rust/components/form/mod.rs +4 -1
- package/src/rust/components/form/multi_stop_gradient_selector.rs +476 -0
- package/src/rust/components/form/named_value_picker.rs +86 -0
- package/src/rust/components/form/palette_selector.rs +440 -0
- package/src/rust/components/main_panel/msg.rs +2 -2
- package/src/rust/components/main_panel/reconcile.rs +4 -4
- package/src/rust/components/mod.rs +2 -0
- package/src/rust/components/plugin_tab.rs +4 -28
- package/src/rust/components/settings_panel.rs +105 -22
- package/src/rust/components/viewer/msg.rs +46 -7
- package/src/rust/components/viewer/panels.rs +17 -20
- package/src/rust/components/viewer/render.rs +10 -3
- package/src/rust/components/viewer/settings.rs +163 -23
- package/src/rust/components/viewer/snapshots.rs +46 -21
- package/src/rust/components/viewer/wiring.rs +14 -25
- package/src/rust/components/viewer.rs +12 -8
- package/src/rust/components/window_editor.rs +75 -103
- package/src/rust/config/column_config_schema.rs +100 -41
- package/src/rust/config/css_scale.rs +882 -0
- package/src/rust/config/datetime_column_style/custom.rs +17 -0
- package/src/rust/config/datetime_column_style/simple.rs +10 -0
- package/src/rust/config/mod.rs +2 -0
- package/src/rust/config/number_string_format.rs +33 -0
- package/src/rust/config/options.rs +28 -0
- package/src/rust/config/plugin_static_config.rs +120 -5
- package/src/rust/config/viewer_config.rs +216 -3
- package/src/rust/config/workspace_config.rs +138 -10
- package/src/rust/custom_elements/viewer.rs +369 -119
- package/src/rust/custom_events.rs +43 -1
- package/src/rust/js/regular_layout.rs +3 -3
- package/src/rust/lib.rs +15 -0
- package/src/rust/presentation/column_locator.rs +19 -5
- package/src/rust/presentation.rs +200 -36
- package/src/rust/queries/column_locator.rs +74 -44
- package/src/rust/queries/get_viewer_config.rs +2 -1
- package/src/rust/queries/mod.rs +2 -0
- package/src/rust/queries/palette_set.rs +82 -0
- package/src/rust/queries/plugin_column_styles.rs +6 -2
- package/src/rust/renderer/dispatch.rs +16 -4
- package/src/rust/renderer/plugin_config.rs +309 -47
- package/src/rust/renderer.rs +15 -42
- package/src/rust/session/column_defaults_update.rs +32 -7
- package/src/rust/session/metadata.rs +23 -21
- package/src/rust/session/props.rs +1 -0
- package/src/rust/session/replace_expression_update.rs +1 -0
- package/src/rust/session.rs +9 -6
- package/src/rust/tasks/create_panel.rs +46 -49
- package/src/rust/tasks/edit_expression.rs +19 -23
- package/src/rust/tasks/edit_window.rs +9 -11
- package/src/rust/tasks/eject.rs +4 -1
- package/src/rust/tasks/pipeline.rs +2 -2
- package/src/rust/tasks/presize_panels.rs +44 -5
- package/src/rust/tasks/reset_all.rs +4 -4
- package/src/rust/tasks/restore_and_render.rs +17 -44
- package/src/rust/tasks/restore_panel.rs +37 -22
- package/src/rust/tasks/set_edit_mode.rs +3 -1
- package/src/rust/tasks/sync_update_panels.rs +18 -24
- package/src/rust/tasks/update_theme.rs +23 -18
- package/src/rust/utils/css_vars.rs +26 -0
- package/src/rust/utils/mod.rs +2 -0
- package/src/rust/utils/spawn.rs +1 -1
- package/src/rust/workspace.rs +454 -199
- package/src/svg/lock.svg +7 -0
- package/src/themes/botanical.css +10 -0
- package/src/themes/defaults.css +12 -0
- package/src/themes/dracula.css +17 -0
- package/src/themes/gruvbox-dark.css +20 -0
- package/src/themes/gruvbox.css +10 -0
- package/src/themes/icons.css +1 -0
- package/src/themes/intl/de.css +16 -0
- package/src/themes/intl/es.css +16 -0
- package/src/themes/intl/fr.css +16 -0
- package/src/themes/intl/ja.css +16 -0
- package/src/themes/intl/pt.css +16 -0
- package/src/themes/intl/zh.css +16 -0
- package/src/themes/intl.css +16 -0
- package/src/themes/monokai.css +22 -0
- package/src/themes/phosphor.css +5 -0
- package/src/themes/pro-dark.css +10 -0
- package/src/themes/solarized-dark.css +7 -0
- package/src/themes/solarized.css +7 -0
- package/src/themes/vaporwave.css +20 -0
- package/src/ts/column-format.ts +67 -46
- package/src/ts/perspective-viewer.ts +3 -0
- package/src/ts/plugin.ts +14 -0
- package/src/ts/providers.ts +96 -0
- package/src/ts/ts-rs/CompactDisplay.ts +3 -0
- package/src/ts/ts-rs/CurrencyCode.ts +3 -0
- package/src/ts/ts-rs/CurrencyDisplay.ts +3 -0
- package/src/ts/ts-rs/CurrencyNumberFormatStyle.ts +6 -0
- package/src/ts/ts-rs/CurrencySign.ts +3 -0
- package/src/ts/ts-rs/CustomDatetimeFormat.ts +3 -0
- package/src/ts/ts-rs/CustomDatetimeStyleConfig.ts +54 -0
- package/src/ts/ts-rs/CustomNumberFormatConfig.ts +25 -0
- package/src/ts/ts-rs/DatetimeColorMode.ts +3 -0
- package/src/ts/ts-rs/DatetimeFormatType.ts +8 -0
- package/src/ts/ts-rs/FormatMode.ts +3 -0
- package/src/ts/ts-rs/FormatUnit.ts +3 -0
- package/src/ts/ts-rs/Notation.ts +11 -0
- package/src/ts/ts-rs/NumberFormatStyle.ts +12 -0
- package/src/ts/ts-rs/PanelViewerConfig.ts +48 -2
- package/src/ts/ts-rs/PluginStaticConfig.ts +36 -1
- package/src/ts/ts-rs/RestoreOptions.ts +20 -0
- package/src/ts/ts-rs/RoundingMode.ts +3 -0
- package/src/ts/ts-rs/RoundingPriority.ts +3 -0
- package/src/ts/ts-rs/SaveWorkspaceOptions.ts +11 -0
- package/src/ts/ts-rs/SignDisplay.ts +3 -0
- package/src/ts/ts-rs/SimpleDatetimeFormat.ts +3 -0
- package/src/ts/ts-rs/SimpleDatetimeStyleConfig.ts +25 -0
- package/src/ts/ts-rs/SplitRollupMode.ts +11 -0
- package/src/ts/ts-rs/StringColorMode.ts +3 -0
- package/src/ts/ts-rs/TrailingZeroDisplay.ts +3 -0
- package/src/ts/ts-rs/Unit.ts +3 -0
- package/src/ts/ts-rs/UnitDisplay.ts +3 -0
- package/src/ts/ts-rs/UnitNumberFormatStyle.ts +5 -0
- package/src/ts/ts-rs/UseGrouping.ts +3 -0
- package/src/ts/ts-rs/ViewerConfig.ts +48 -2
- package/src/ts/ts-rs/ViewerConfigInitial.ts +164 -0
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +72 -2
- package/src/ts/ts-rs/WindowSpec.ts +3 -2
- package/src/ts/ts-rs/WorkspaceConfig.ts +8 -2
- package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +18 -9
- package/dist/esm/ts-rs/WindowAggregate.d.ts +0 -1
- package/src/rust/components/form/color_range_selector.rs +0 -137
- package/src/ts/ts-rs/WindowAggregate.ts +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-8a8c7d5d696b43ae → perspective-viewer-39c3c3b28e3cbd48}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-8a8c7d5d696b43ae → perspective-viewer-39c3c3b28e3cbd48}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-8a8c7d5d696b43ae → perspective-viewer-39c3c3b28e3cbd48}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-8a8c7d5d696b43ae → perspective-viewer-39c3c3b28e3cbd48}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-8a8c7d5d696b43ae → perspective-viewer-39c3c3b28e3cbd48}/inline4.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-8a8c7d5d696b43ae → perspective-viewer-39c3c3b28e3cbd48}/inline5.js +0 -0
|
@@ -21,19 +21,21 @@ use super::plugin_selector::PluginSelector;
|
|
|
21
21
|
use super::plugin_tab::PluginTab;
|
|
22
22
|
use crate::components::containers::sidebar_close_button::SidebarCloseButton;
|
|
23
23
|
use crate::components::form::debug::DebugPanel;
|
|
24
|
-
use crate::config::PluginUpdate;
|
|
25
|
-
use crate::presentation::{ColumnLocator, OpenColumnSettings, Presentation};
|
|
24
|
+
use crate::config::{PluginStaticConfig, PluginUpdate};
|
|
25
|
+
use crate::presentation::{ColumnLocator, ColumnSettingsTarget, OpenColumnSettings, Presentation};
|
|
26
|
+
use crate::queries::classify_column;
|
|
26
27
|
use crate::renderer::*;
|
|
27
28
|
use crate::session::column_defaults_update::*;
|
|
28
29
|
use crate::session::*;
|
|
29
30
|
use crate::tasks::update_plugin_and_render;
|
|
30
31
|
use crate::utils::*;
|
|
32
|
+
use crate::workspace::Workspace;
|
|
31
33
|
|
|
32
34
|
#[derive(Clone, Properties)]
|
|
33
35
|
pub struct SettingsPanelProps {
|
|
34
36
|
pub on_close: Callback<()>,
|
|
35
37
|
pub on_resize: Rc<PubSub<()>>,
|
|
36
|
-
pub on_select_column: Callback<Option<
|
|
38
|
+
pub on_select_column: Callback<Option<ColumnSettingsTarget>>,
|
|
37
39
|
pub on_debug: Callback<()>,
|
|
38
40
|
pub is_debug: bool,
|
|
39
41
|
|
|
@@ -42,6 +44,15 @@ pub struct SettingsPanelProps {
|
|
|
42
44
|
pub available_plugins: PtrEqRc<Vec<String>>,
|
|
43
45
|
pub has_table: Option<TableLoadState>,
|
|
44
46
|
pub named_column_count: usize,
|
|
47
|
+
|
|
48
|
+
/// The ACTIVE plugin's declared contract, threaded as a value prop so
|
|
49
|
+
/// that switching plugins re-renders the panes that read it. The
|
|
50
|
+
/// renderer handle cannot serve this: it is excluded from prop
|
|
51
|
+
/// equality (it is a handle, not a value), so a plugin swap that
|
|
52
|
+
/// leaves the view config untouched — Y Line back to Datagrid, both
|
|
53
|
+
/// of which name one column slot — would otherwise change nothing any
|
|
54
|
+
/// component compares.
|
|
55
|
+
pub plugin_static_config: Rc<PluginStaticConfig>,
|
|
45
56
|
pub view_config: PtrEqRc<ViewConfig>,
|
|
46
57
|
|
|
47
58
|
/// Snapshot of the active plugin's `plugin_config` bucket, threaded
|
|
@@ -90,6 +101,7 @@ pub struct SettingsPanelProps {
|
|
|
90
101
|
pub session: Session,
|
|
91
102
|
pub renderer: Renderer,
|
|
92
103
|
pub presentation: Presentation,
|
|
104
|
+
pub workspace: Workspace,
|
|
93
105
|
}
|
|
94
106
|
|
|
95
107
|
impl PartialEq for SettingsPanelProps {
|
|
@@ -99,6 +111,7 @@ impl PartialEq for SettingsPanelProps {
|
|
|
99
111
|
&& self.available_plugins == rhs.available_plugins
|
|
100
112
|
&& self.has_table == rhs.has_table
|
|
101
113
|
&& self.named_column_count == rhs.named_column_count
|
|
114
|
+
&& self.plugin_static_config == rhs.plugin_static_config
|
|
102
115
|
&& self.view_config == rhs.view_config
|
|
103
116
|
&& self.plugin_config == rhs.plugin_config
|
|
104
117
|
&& self.drag_column == rhs.drag_column
|
|
@@ -116,6 +129,11 @@ pub enum SelectedTab {
|
|
|
116
129
|
Query,
|
|
117
130
|
Plugin,
|
|
118
131
|
Debug,
|
|
132
|
+
|
|
133
|
+
/// The embedded LLM agent's chat panel. The variant exists in every
|
|
134
|
+
/// build; its tab button and body render only under the `llm-agent`
|
|
135
|
+
/// feature, and only once `agentConfig()` has been called.
|
|
136
|
+
Chat,
|
|
119
137
|
}
|
|
120
138
|
|
|
121
139
|
#[function_component]
|
|
@@ -128,25 +146,28 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
128
146
|
} = &props;
|
|
129
147
|
|
|
130
148
|
let selected_column = {
|
|
131
|
-
let locator = props.open_column_settings.locator.clone();
|
|
132
149
|
let config = &props.view_config;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
props
|
|
151
|
+
.open_column_settings
|
|
152
|
+
.target
|
|
153
|
+
.as_ref()
|
|
154
|
+
.and_then(|target| match target {
|
|
155
|
+
ColumnSettingsTarget::NewExpression => Some(ColumnLocator::NewExpression),
|
|
156
|
+
ColumnSettingsTarget::Column(n) => {
|
|
157
|
+
let locator = classify_column(n, config, &props.metadata)?;
|
|
158
|
+
if !matches!(locator, ColumnLocator::Table(_)) {
|
|
159
|
+
return Some(locator);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let used = config.columns.iter().any(|maybe_col| {
|
|
163
|
+
maybe_col.as_ref().map(|col| col == n).unwrap_or_default()
|
|
164
|
+
}) || config.group_by.iter().any(|col| col == n)
|
|
165
|
+
|| config.split_by.iter().any(|col| col == n)
|
|
166
|
+
|| config.filter.iter().any(|col| col.column() == n)
|
|
167
|
+
|| config.sort.iter().any(|col| &col.0 == n);
|
|
168
|
+
(used && props.renderer.can_render_column_styles()).then_some(locator)
|
|
169
|
+
},
|
|
170
|
+
})
|
|
150
171
|
};
|
|
151
172
|
|
|
152
173
|
let plugin_name = props.plugin_name.clone();
|
|
@@ -186,13 +207,21 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
186
207
|
.unwrap();
|
|
187
208
|
|
|
188
209
|
let group_rollups = plugin_config.get_group_rollups(&rollup_features);
|
|
210
|
+
let split_rollup_features = session_metadata
|
|
211
|
+
.get_features()
|
|
212
|
+
.map(|x| x.get_split_rollup_modes())
|
|
213
|
+
.unwrap();
|
|
214
|
+
|
|
215
|
+
let split_rollups = plugin_config.get_split_rollups(&split_rollup_features);
|
|
189
216
|
let mut update = ViewConfigUpdate {
|
|
190
217
|
group_rollup_mode: group_rollups.first().cloned(),
|
|
218
|
+
split_rollup_mode: split_rollups.first().cloned(),
|
|
191
219
|
..ViewConfigUpdate::default()
|
|
192
220
|
};
|
|
193
221
|
|
|
194
222
|
update.set_update_column_defaults(
|
|
195
223
|
&session_metadata,
|
|
224
|
+
&view_config,
|
|
196
225
|
&view_config.columns,
|
|
197
226
|
plugin_config,
|
|
198
227
|
);
|
|
@@ -237,6 +266,52 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
237
266
|
}
|
|
238
267
|
};
|
|
239
268
|
|
|
269
|
+
// The chat tab is zero-affordance until `agentConfig()` is called; the
|
|
270
|
+
// subscription re-renders this panel when that happens (and as the
|
|
271
|
+
// transcript updates while the chat body is mounted).
|
|
272
|
+
#[cfg(feature = "llm-agent")]
|
|
273
|
+
let (chat_tab_button, chat_body) = {
|
|
274
|
+
let update = use_force_update();
|
|
275
|
+
let agent = presentation.agent.clone();
|
|
276
|
+
use_effect_with((), move |_| {
|
|
277
|
+
let sub = agent
|
|
278
|
+
.on_update
|
|
279
|
+
.add_notify_listener(&Callback::from(move |_| update.force_update()));
|
|
280
|
+
|
|
281
|
+
move || drop(sub)
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
let button = if presentation.agent.is_configured() {
|
|
285
|
+
let on_select_column = props.on_select_column.clone();
|
|
286
|
+
let set_chat = {
|
|
287
|
+
let on_select_tab = props.on_select_tab.clone();
|
|
288
|
+
Callback::from(move |_: PointerEvent| {
|
|
289
|
+
on_select_tab.emit(SelectedTab::Chat);
|
|
290
|
+
on_select_column.emit(None)
|
|
291
|
+
})
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
html! {
|
|
295
|
+
<div
|
|
296
|
+
id="chat_tabbar_tab"
|
|
297
|
+
class={tab_class(selected, SelectedTab::Chat)}
|
|
298
|
+
onpointerdown={set_chat}
|
|
299
|
+
/>
|
|
300
|
+
}
|
|
301
|
+
} else {
|
|
302
|
+
html! {}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
let body = html! {
|
|
306
|
+
<crate::components::chat_panel::ChatPanel agent={presentation.agent.clone()} />
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
(button, body)
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
#[cfg(not(feature = "llm-agent"))]
|
|
313
|
+
let (chat_tab_button, chat_body) = (html! {}, html! {});
|
|
314
|
+
|
|
240
315
|
let on_open_expr_panel = use_callback(props.on_select_column.clone(), |c, on_select| {
|
|
241
316
|
on_select.emit(Some(c))
|
|
242
317
|
});
|
|
@@ -270,6 +345,7 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
270
345
|
class={tab_class(selected, SelectedTab::Debug)}
|
|
271
346
|
onpointerdown={set_debug}
|
|
272
347
|
/>
|
|
348
|
+
{ chat_tab_button }
|
|
273
349
|
</div>
|
|
274
350
|
if selected == SelectedTab::Query {
|
|
275
351
|
<ColumnSelector
|
|
@@ -278,6 +354,7 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
278
354
|
{selected_column}
|
|
279
355
|
has_table={props.has_table.clone()}
|
|
280
356
|
named_column_count={props.named_column_count}
|
|
357
|
+
plugin_static_config={props.plugin_static_config.clone()}
|
|
281
358
|
view_config={props.view_config.clone()}
|
|
282
359
|
drag_column={props.drag_column.clone()}
|
|
283
360
|
metadata={props.metadata.clone()}
|
|
@@ -298,11 +375,14 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
298
375
|
// initial_width={width}
|
|
299
376
|
// on_auto_width={on_auto_width.clone()}
|
|
300
377
|
/>
|
|
378
|
+
} else if selected == SelectedTab::Chat {
|
|
379
|
+
{ chat_body }
|
|
301
380
|
} else {
|
|
302
381
|
<DebugPanel
|
|
303
382
|
{presentation}
|
|
304
383
|
{renderer}
|
|
305
384
|
{session}
|
|
385
|
+
workspace={props.workspace.clone()}
|
|
306
386
|
initial_width={width}
|
|
307
387
|
on_auto_width={on_auto_width.clone()}
|
|
308
388
|
/>
|
|
@@ -310,7 +390,10 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
310
390
|
// Sibling sizer keeps the panel width pinned across tab
|
|
311
391
|
// switches; lives outside the tab-body so it survives the
|
|
312
392
|
// tab subtree's unmount.
|
|
313
|
-
<div
|
|
393
|
+
<div
|
|
394
|
+
class="scroll-panel-auto-width"
|
|
395
|
+
style={format!("width:{}px", width)}
|
|
396
|
+
/>
|
|
314
397
|
</div>
|
|
315
398
|
}
|
|
316
399
|
}
|
|
@@ -22,7 +22,9 @@ use wasm_bindgen::JsValue;
|
|
|
22
22
|
|
|
23
23
|
use crate::components::settings_panel::SelectedTab;
|
|
24
24
|
use crate::config::*;
|
|
25
|
-
use crate::presentation::{
|
|
25
|
+
use crate::presentation::{
|
|
26
|
+
ColumnSettingsTab, ColumnSettingsTarget, DragDropProps, PresentationProps,
|
|
27
|
+
};
|
|
26
28
|
use crate::renderer::RendererProps;
|
|
27
29
|
use crate::session::{SessionProps, TableLoadState, ViewStats};
|
|
28
30
|
use crate::utils::Completion;
|
|
@@ -48,17 +50,19 @@ pub enum PerspectiveViewerMsg {
|
|
|
48
50
|
ColumnSettingsPanelSizeUpdate(Option<i32>),
|
|
49
51
|
ColumnSettingsPanelAutoWidth(f64),
|
|
50
52
|
ToggleColumnSettingsPin,
|
|
53
|
+
ToggleColumnSettingsPinComplete(Sender<()>),
|
|
51
54
|
ColumnSettingsTabChanged(ColumnSettingsTab),
|
|
52
55
|
OpenColumnSettings {
|
|
53
|
-
|
|
56
|
+
target: Option<ColumnSettingsTarget>,
|
|
54
57
|
sender: Option<Sender<()>>,
|
|
55
58
|
toggle: bool,
|
|
56
59
|
},
|
|
57
60
|
PreloadFontsUpdate,
|
|
58
61
|
|
|
59
62
|
/// Element-level reset (the public `reset()` API): reset EVERY panel and
|
|
60
|
-
/// clear the cross-filter overlay, symmetric with
|
|
61
|
-
/// `
|
|
63
|
+
/// clear the cross-filter overlay, symmetric with
|
|
64
|
+
/// `saveWorkspace`/`restoreWorkspace`. The `bool` also clears
|
|
65
|
+
/// expressions/column settings.
|
|
62
66
|
Reset(bool, Option<Completion>),
|
|
63
67
|
|
|
64
68
|
/// Reset ONLY the named panel — or the active panel when `None` — to its
|
|
@@ -86,10 +90,10 @@ pub enum PerspectiveViewerMsg {
|
|
|
86
90
|
/// I6) — carrying any teardown error, which was previously dropped.
|
|
87
91
|
ClosePanel(String, Option<Completion>),
|
|
88
92
|
|
|
89
|
-
///
|
|
93
|
+
/// `restoreWorkspace` finished replacing the panel set in the
|
|
90
94
|
/// `Workspace` (new models inserted, old panels ejected, layout staged):
|
|
91
95
|
/// activate the named panel, re-subscribe the per-panel wiring, and
|
|
92
|
-
/// re-render — the SINGLE visible commit of the
|
|
96
|
+
/// re-render — the SINGLE visible commit of the restore.
|
|
93
97
|
CommitWorkspaceRestore(String),
|
|
94
98
|
|
|
95
99
|
/// Duplicate the named panel: snapshot its config into a new independent
|
|
@@ -149,8 +153,34 @@ pub enum PerspectiveViewerMsg {
|
|
|
149
153
|
SettingsPanelTabChanged(SelectedTab),
|
|
150
154
|
SettingsPanelAutoWidth(f64),
|
|
151
155
|
ToggleDebug,
|
|
156
|
+
|
|
157
|
+
/// The toggle choreography's INTERNAL completion leaf: flip the pane
|
|
158
|
+
/// and resolve on the render commit. Never send this to toggle
|
|
159
|
+
/// settings from outside `settings.rs` — it skips the presize/resize
|
|
160
|
+
/// sweep (the pane's `SplitPanel` emits no `before-resize` and the
|
|
161
|
+
/// host box is unchanged, so nothing else resizes the plugins), which
|
|
162
|
+
/// leaves canvas plugins CSS-stretched at their old backing size. API
|
|
163
|
+
/// entry points send [`Self::ToggleSettingsInit`].
|
|
152
164
|
ToggleSettingsComplete(SettingsUpdate, Sender<()>),
|
|
153
|
-
|
|
165
|
+
|
|
166
|
+
/// Toggle (or force) the settings pane with the FULL choreography:
|
|
167
|
+
/// presize every visible plugin to its post-toggle box, commit the
|
|
168
|
+
/// pane, then the exactness-finalizer resize. The `Sender` resolves
|
|
169
|
+
/// after the sweep. The one settings-toggle entry point for both the
|
|
170
|
+
/// toolbar and the element API (`toggleConfig`, `restore({settings})`,
|
|
171
|
+
/// `restoreWorkspace`).
|
|
172
|
+
///
|
|
173
|
+
/// The `bool` is `announce`: `true` when this toggle is the SOLE
|
|
174
|
+
/// carrier of the config change (a user gesture — toolbar,
|
|
175
|
+
/// `toggleConfig`), which emits `toggle-settings` + one
|
|
176
|
+
/// `perspective-config-update`; `false` for the `restore` family,
|
|
177
|
+
/// whose own view-config commit dispatch announces the settings field
|
|
178
|
+
/// — one API call, one config-update.
|
|
179
|
+
ToggleSettingsInit(
|
|
180
|
+
Option<SettingsUpdate>,
|
|
181
|
+
bool,
|
|
182
|
+
Option<Sender<ApiResult<JsValue>>>,
|
|
183
|
+
),
|
|
154
184
|
UpdateSession(Box<SessionProps>),
|
|
155
185
|
UpdateRenderer(Box<RendererProps>),
|
|
156
186
|
UpdatePresentation(Box<PresentationProps>),
|
|
@@ -161,7 +191,16 @@ pub enum PerspectiveViewerMsg {
|
|
|
161
191
|
UpdateIsWorkspace(bool),
|
|
162
192
|
|
|
163
193
|
/// Update only `open_column_settings` in the presentation snapshot.
|
|
194
|
+
/// Handled in `settings.rs` (not `snapshots.rs`): a docked-drawer
|
|
195
|
+
/// mount/unmount defers the snapshot behind a presize sweep.
|
|
164
196
|
UpdateColumnSettings(Box<crate::presentation::OpenColumnSettings>),
|
|
197
|
+
|
|
198
|
+
/// Every visible panel has rendered at its post-transition box — NOW
|
|
199
|
+
/// apply the newest deferred `open_column_settings` target (the
|
|
200
|
+
/// latest-wins slot, not a copy captured at sweep spawn); the `Sender`
|
|
201
|
+
/// resolves on the render commit so the staged presents reveal in the
|
|
202
|
+
/// same paint (mirrors `ToggleSettingsComplete`).
|
|
203
|
+
UpdateColumnSettingsCommit(Sender<()>),
|
|
165
204
|
UpdateDragDrop(Box<DragDropProps>),
|
|
166
205
|
|
|
167
206
|
/// Update only stats-related fields of `session_props` without touching
|
|
@@ -27,7 +27,7 @@ use super::wiring::{
|
|
|
27
27
|
clear_active_callbacks, create_active_subscriptions, inject_active_callbacks,
|
|
28
28
|
subscribe_panel_titles,
|
|
29
29
|
};
|
|
30
|
-
use crate::config::
|
|
30
|
+
use crate::config::ViewerConfigInitial;
|
|
31
31
|
use crate::queries::*;
|
|
32
32
|
use crate::renderer::Renderer;
|
|
33
33
|
use crate::session::*;
|
|
@@ -124,7 +124,7 @@ impl PerspectiveViewer {
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
///
|
|
127
|
+
/// `restoreWorkspace`'s single commit: the `Workspace` already holds
|
|
128
128
|
/// the final panel set (models inserted, olds ejected) and the staged
|
|
129
129
|
/// layout. Re-subscribe the per-panel title wiring (the set changed
|
|
130
130
|
/// wholesale), activate the restored panel, and re-render — `MainPanel`'s
|
|
@@ -193,7 +193,8 @@ impl PerspectiveViewer {
|
|
|
193
193
|
})
|
|
194
194
|
.await?;
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
// TODO(texodus): what the ****?
|
|
197
|
+
let update = ViewerConfigInitial::decode(&config.encode()?)?;
|
|
197
198
|
let client = panel.session.get_client();
|
|
198
199
|
let new_id = create_panel(
|
|
199
200
|
&elem,
|
|
@@ -216,18 +217,18 @@ impl PerspectiveViewer {
|
|
|
216
217
|
|
|
217
218
|
pub(super) fn on_new_panel(&mut self, ctx: &Context<Self>, id: String) -> bool {
|
|
218
219
|
if let Some(panel) = ctx.props().workspace.panel(&PanelId::from(id)) {
|
|
219
|
-
let table_name = panel.session.get_table().map(|t| t.get_name().to_owned())
|
|
220
|
+
let Some(table_name) = panel.session.get_table().map(|t| t.get_name().to_owned())
|
|
221
|
+
else {
|
|
222
|
+
tracing::warn!("Source panel has no `Table` to create a new panel from");
|
|
223
|
+
return false;
|
|
224
|
+
};
|
|
225
|
+
|
|
220
226
|
let elem = ctx.props().elem.clone();
|
|
221
227
|
let presentation = ctx.props().presentation.clone();
|
|
222
228
|
let workspace = ctx.props().workspace.clone();
|
|
223
229
|
let notify = ctx.link().callback(|_: ()| LayoutChanged);
|
|
224
230
|
let activate = ctx.link().callback(|id| SetActivePanel(id, None));
|
|
225
231
|
ApiFuture::spawn(async move {
|
|
226
|
-
let update = ViewerConfigUpdate {
|
|
227
|
-
table: table_name.map(TableUpdate::Update).unwrap_or_default(),
|
|
228
|
-
..Default::default()
|
|
229
|
-
};
|
|
230
|
-
|
|
231
232
|
let client = panel.session.get_client();
|
|
232
233
|
let new_id = create_panel(
|
|
233
234
|
&elem,
|
|
@@ -235,7 +236,7 @@ impl PerspectiveViewer {
|
|
|
235
236
|
&workspace,
|
|
236
237
|
¬ify,
|
|
237
238
|
None,
|
|
238
|
-
|
|
239
|
+
ViewerConfigInitial::new(table_name),
|
|
239
240
|
client,
|
|
240
241
|
)
|
|
241
242
|
.await?;
|
|
@@ -273,18 +274,13 @@ impl PerspectiveViewer {
|
|
|
273
274
|
let notify = ctx.link().callback(|_: ()| LayoutChanged);
|
|
274
275
|
let activate = ctx.link().callback(|id| SetActivePanel(id, None));
|
|
275
276
|
ApiFuture::spawn(async move {
|
|
276
|
-
let update = ViewerConfigUpdate {
|
|
277
|
-
table: TableUpdate::Update(table),
|
|
278
|
-
..Default::default()
|
|
279
|
-
};
|
|
280
|
-
|
|
281
277
|
let new_id = create_panel(
|
|
282
278
|
&elem,
|
|
283
279
|
&presentation,
|
|
284
280
|
&workspace,
|
|
285
281
|
¬ify,
|
|
286
282
|
None,
|
|
287
|
-
|
|
283
|
+
ViewerConfigInitial::new(table),
|
|
288
284
|
Some(client),
|
|
289
285
|
)
|
|
290
286
|
.await?;
|
|
@@ -313,11 +309,12 @@ impl PerspectiveViewer {
|
|
|
313
309
|
let presentation = ctx.props().presentation.clone();
|
|
314
310
|
let workspace = ctx.props().workspace.clone();
|
|
315
311
|
ApiFuture::spawn(async move {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
{
|
|
312
|
+
// Only an EXPLICITLY themed panel mirrors onto the host; an
|
|
313
|
+
// unpinned one inherits whatever the host already shows, so
|
|
314
|
+
// activating it must not restate (and thereby pin) that value.
|
|
315
|
+
if let Some(theme) = workspace.active_renderer().and_then(|x| x.theme()) {
|
|
320
316
|
presentation.set_theme_name(Some(&theme)).await?;
|
|
317
|
+
presentation.publish_theme_config().await?;
|
|
321
318
|
}
|
|
322
319
|
|
|
323
320
|
Ok(())
|
|
@@ -53,7 +53,7 @@ impl PerspectiveViewer {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
let on_open_expr_panel = ctx.link().callback(|c| OpenColumnSettings {
|
|
56
|
-
|
|
56
|
+
target: c,
|
|
57
57
|
sender: None,
|
|
58
58
|
toggle: true,
|
|
59
59
|
});
|
|
@@ -62,7 +62,9 @@ impl PerspectiveViewer {
|
|
|
62
62
|
.link()
|
|
63
63
|
.callback(|(x, _)| ColumnSettingsPanelSizeUpdate(Some(x)));
|
|
64
64
|
|
|
65
|
-
let on_close_settings = ctx
|
|
65
|
+
let on_close_settings = ctx
|
|
66
|
+
.link()
|
|
67
|
+
.callback(|()| ToggleSettingsInit(None, true, None));
|
|
66
68
|
let on_debug = ctx.link().callback(|_| ToggleDebug);
|
|
67
69
|
let selected_column = get_current_column_locator(
|
|
68
70
|
&self.presentation_props.open_column_settings,
|
|
@@ -94,6 +96,7 @@ impl PerspectiveViewer {
|
|
|
94
96
|
{available_plugins}
|
|
95
97
|
{has_table}
|
|
96
98
|
{named_column_count}
|
|
99
|
+
plugin_static_config={self.renderer_props.config.clone()}
|
|
97
100
|
{view_config}
|
|
98
101
|
plugin_config={self.renderer_props.plugin_config.clone()}
|
|
99
102
|
{drag_column}
|
|
@@ -108,13 +111,16 @@ impl PerspectiveViewer {
|
|
|
108
111
|
{presentation}
|
|
109
112
|
{renderer}
|
|
110
113
|
{session}
|
|
114
|
+
workspace={ctx.props().workspace.clone()}
|
|
111
115
|
/>
|
|
112
116
|
}
|
|
113
117
|
} else {
|
|
114
118
|
html! { <></> }
|
|
115
119
|
};
|
|
116
120
|
|
|
117
|
-
let on_settings = ctx
|
|
121
|
+
let on_settings = ctx
|
|
122
|
+
.link()
|
|
123
|
+
.callback(|()| ToggleSettingsInit(None, true, None));
|
|
118
124
|
let on_select_tab = ctx.link().callback(ColumnSettingsTabChanged);
|
|
119
125
|
// Pinning the drawer is a pure CSS positioning flip on `#modal_panel`
|
|
120
126
|
// (absolute overlay over the main panel <-> static flex sibling
|
|
@@ -151,6 +157,7 @@ impl PerspectiveViewer {
|
|
|
151
157
|
{presentation}
|
|
152
158
|
{renderer}
|
|
153
159
|
{session}
|
|
160
|
+
workspace={ctx.props().workspace.clone()}
|
|
154
161
|
/>
|
|
155
162
|
<></>
|
|
156
163
|
</SplitPanel>
|