@perspective-dev/viewer 5.0.0 → 5.2.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 +2 -0
- package/dist/esm/perspective-viewer.inline.js +8 -8
- 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/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 +43 -1
- 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/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 +43 -1
- package/dist/esm/ts-rs/ViewerConfigInitial.d.ts +175 -0
- package/dist/esm/ts-rs/ViewerConfigUpdate.d.ts +72 -0
- package/dist/esm/ts-rs/WindowSort.d.ts +7 -0
- package/dist/esm/ts-rs/WindowSortDir.d.ts +6 -0
- package/dist/esm/ts-rs/WindowSpec.d.ts +47 -0
- package/dist/esm/ts-rs/Windows.d.ts +10 -0
- package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +7 -6
- package/dist/wasm/perspective-viewer.d.ts +222 -26
- package/dist/wasm/perspective-viewer.js +378 -125
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +18 -15
- package/package.json +2 -1
- package/src/css/_viewer_bundle.css +1 -0
- package/src/css/column-selector.css +9 -0
- package/src/css/column-settings-panel.css +67 -2
- package/src/css/column-style.css +4 -3
- package/src/css/config-selector.css +60 -4
- package/src/css/containers/context-menu.css +12 -6
- package/src/css/containers/tabs.css +2 -2
- package/src/css/form/code-editor.css +2 -3
- package/src/css/form/mirrored-textarea.css +81 -0
- package/src/css/viewer.css +336 -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 +1110 -0
- package/src/rust/components/chat_panel.rs +289 -0
- package/src/rust/components/column_selector/active_column.rs +21 -27
- package/src/rust/components/column_selector/column_selector_column_row.rs +73 -0
- package/src/rust/components/column_selector/config_selector.rs +83 -8
- package/src/rust/components/column_selector/expr_edit_button.rs +7 -1
- package/src/rust/components/column_selector/inactive_column.rs +8 -1
- package/src/rust/components/column_selector.rs +27 -3
- package/src/rust/components/column_settings_sidebar/style_tab.rs +2 -1
- package/src/rust/components/column_settings_sidebar/window_tab.rs +34 -0
- package/src/rust/components/column_settings_sidebar.rs +163 -16
- package/src/rust/components/containers/dragdrop_list.rs +110 -3
- package/src/rust/components/containers/sidebar.rs +99 -22
- package/src/rust/components/containers/split_panel.rs +6 -0
- package/src/rust/components/editable_header.rs +2 -0
- package/src/rust/components/form/code_editor.rs +14 -23
- package/src/rust/components/form/debug.rs +8 -5
- package/src/rust/components/form/mirrored_textarea.rs +165 -0
- package/src/rust/components/form/mod.rs +1 -0
- package/src/rust/components/main_panel.rs +5 -0
- package/src/rust/components/mod.rs +3 -0
- package/src/rust/components/panel_menu.rs +7 -0
- package/src/rust/components/panel_tab.rs +5 -0
- package/src/rust/components/portal.rs +7 -0
- package/src/rust/components/settings_panel.rs +80 -2
- package/src/rust/components/viewer/msg.rs +2 -0
- package/src/rust/components/viewer/panels.rs +9 -14
- package/src/rust/components/viewer/render.rs +14 -0
- package/src/rust/components/viewer/settings.rs +33 -1
- package/src/rust/components/viewer.rs +2 -0
- package/src/rust/components/window_editor.rs +985 -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/number_string_format.rs +33 -0
- package/src/rust/config/options.rs +18 -0
- package/src/rust/config/plugin_static_config.rs +120 -5
- package/src/rust/config/viewer_config.rs +220 -1
- package/src/rust/config/workspace_config.rs +7 -6
- package/src/rust/custom_elements/viewer.rs +209 -18
- package/src/rust/custom_events.rs +29 -0
- package/src/rust/lib.rs +17 -1
- package/src/rust/presentation/column_locator.rs +16 -1
- package/src/rust/presentation.rs +8 -0
- package/src/rust/queries/columns_iter_set.rs +7 -1
- package/src/rust/queries/get_viewer_config.rs +5 -1
- package/src/rust/renderer/dispatch.rs +85 -58
- package/src/rust/renderer.rs +34 -1
- package/src/rust/session/column_defaults_update.rs +18 -0
- package/src/rust/session/drag_drop_update.rs +18 -0
- package/src/rust/session/metadata.rs +64 -9
- package/src/rust/session/replace_expression_update.rs +2 -0
- package/src/rust/session.rs +7 -5
- package/src/rust/tasks/create_panel.rs +18 -8
- package/src/rust/tasks/edit_window.rs +155 -0
- package/src/rust/tasks/mod.rs +2 -0
- package/src/rust/tasks/restore_panel.rs +34 -17
- package/src/rust/tasks/sync_update_panels.rs +7 -23
- package/src/rust/utils/browser/dragdrop.rs +12 -0
- package/src/rust/utils/browser/tests/debounce.rs +49 -0
- package/src/rust/utils/debounce.rs +76 -27
- package/src/rust/workspace.rs +112 -20
- package/src/svg/pin-icon.svg +5 -0
- package/src/themes/icons.css +1 -0
- package/src/themes/intl/de.css +23 -0
- package/src/themes/intl/es.css +23 -0
- package/src/themes/intl/fr.css +23 -0
- package/src/themes/intl/ja.css +23 -0
- package/src/themes/intl/pt.css +23 -0
- package/src/themes/intl/zh.css +23 -0
- package/src/themes/intl.css +26 -1
- package/src/ts/column-format.ts +67 -46
- package/src/ts/perspective-viewer.ts +2 -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 -1
- 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/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 -1
- package/src/ts/ts-rs/ViewerConfigInitial.ts +164 -0
- package/src/ts/ts-rs/ViewerConfigUpdate.ts +81 -2
- package/src/ts/ts-rs/WindowSort.ts +9 -0
- package/src/ts/ts-rs/WindowSortDir.ts +8 -0
- package/src/ts/ts-rs/WindowSpec.ts +47 -0
- package/src/ts/ts-rs/Windows.ts +10 -0
- package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +7 -6
- /package/dist/wasm/snippets/{perspective-viewer-daeef4ceb066e6c7 → perspective-viewer-02e461f3d7062b26}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-daeef4ceb066e6c7 → perspective-viewer-02e461f3d7062b26}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-daeef4ceb066e6c7 → perspective-viewer-02e461f3d7062b26}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-daeef4ceb066e6c7 → perspective-viewer-02e461f3d7062b26}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-daeef4ceb066e6c7 → perspective-viewer-02e461f3d7062b26}/inline4.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-daeef4ceb066e6c7 → perspective-viewer-02e461f3d7062b26}/inline5.js +0 -0
|
@@ -299,6 +299,7 @@ impl PanelMenu {
|
|
|
299
299
|
|
|
300
300
|
html! {
|
|
301
301
|
<PortalModal
|
|
302
|
+
key="perspective-context-menu"
|
|
302
303
|
tag_name="perspective-context-menu"
|
|
303
304
|
surface={StyleSurface::ContextMenu}
|
|
304
305
|
target={Some(self.anchor.clone())}
|
|
@@ -453,7 +454,13 @@ impl PanelMenu {
|
|
|
453
454
|
};
|
|
454
455
|
|
|
455
456
|
html! {
|
|
457
|
+
// Keyed by host tag: the menu→picker swap happens at the same
|
|
458
|
+
// vdom position, and `PortalModal`'s host element + adopted
|
|
459
|
+
// surface sheet are create-time-only — unkeyed reuse would leave
|
|
460
|
+
// the picker inside the `<perspective-context-menu>` host with
|
|
461
|
+
// the context-menu sheet.
|
|
456
462
|
<PortalModal
|
|
463
|
+
key={tag_name}
|
|
457
464
|
{tag_name}
|
|
458
465
|
surface={StyleSurface::DropdownMenu}
|
|
459
466
|
{target}
|
|
@@ -316,6 +316,11 @@ impl Component for PanelTab {
|
|
|
316
316
|
|
|
317
317
|
let link = ctx.link().clone();
|
|
318
318
|
let contextmenu = Closure::wrap(Box::new(move |event: MouseEvent| {
|
|
319
|
+
// Shift+right-click passes through to the native browser menu.
|
|
320
|
+
if event.shift_key() {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
319
324
|
event.prevent_default();
|
|
320
325
|
event.stop_propagation();
|
|
321
326
|
link.send_message(PanelTabMsg::ContextMenu(
|
|
@@ -170,6 +170,13 @@ impl Component for PortalModal {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
fn changed(&mut self, ctx: &Context<Self>, old_props: &Self::Properties) -> bool {
|
|
173
|
+
// The host element (`tag_name`) and its adopted sheet (`surface`) are
|
|
174
|
+
// fixed at `create` — a swap at the same vdom position must be keyed
|
|
175
|
+
// so Yew recreates the component (see `PanelMenu`'s menu→picker
|
|
176
|
+
// stages).
|
|
177
|
+
debug_assert_eq!(ctx.props().tag_name, old_props.tag_name);
|
|
178
|
+
debug_assert_eq!(ctx.props().surface, old_props.surface);
|
|
179
|
+
|
|
173
180
|
let new_target = &ctx.props().target;
|
|
174
181
|
let old_target = &old_props.target;
|
|
175
182
|
|
|
@@ -21,13 +21,14 @@ 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;
|
|
24
|
+
use crate::config::{PluginStaticConfig, PluginUpdate};
|
|
25
25
|
use crate::presentation::{ColumnLocator, OpenColumnSettings, Presentation};
|
|
26
26
|
use crate::renderer::*;
|
|
27
27
|
use crate::session::column_defaults_update::*;
|
|
28
28
|
use crate::session::*;
|
|
29
29
|
use crate::tasks::update_plugin_and_render;
|
|
30
30
|
use crate::utils::*;
|
|
31
|
+
use crate::workspace::Workspace;
|
|
31
32
|
|
|
32
33
|
#[derive(Clone, Properties)]
|
|
33
34
|
pub struct SettingsPanelProps {
|
|
@@ -42,6 +43,15 @@ pub struct SettingsPanelProps {
|
|
|
42
43
|
pub available_plugins: PtrEqRc<Vec<String>>,
|
|
43
44
|
pub has_table: Option<TableLoadState>,
|
|
44
45
|
pub named_column_count: usize,
|
|
46
|
+
|
|
47
|
+
/// The ACTIVE plugin's declared contract, threaded as a value prop so
|
|
48
|
+
/// that switching plugins re-renders the panes that read it. The
|
|
49
|
+
/// renderer handle cannot serve this: it is excluded from prop
|
|
50
|
+
/// equality (it is a handle, not a value), so a plugin swap that
|
|
51
|
+
/// leaves the view config untouched — Y Line back to Datagrid, both
|
|
52
|
+
/// of which name one column slot — would otherwise change nothing any
|
|
53
|
+
/// component compares.
|
|
54
|
+
pub plugin_static_config: Rc<PluginStaticConfig>,
|
|
45
55
|
pub view_config: PtrEqRc<ViewConfig>,
|
|
46
56
|
|
|
47
57
|
/// Snapshot of the active plugin's `plugin_config` bucket, threaded
|
|
@@ -90,6 +100,7 @@ pub struct SettingsPanelProps {
|
|
|
90
100
|
pub session: Session,
|
|
91
101
|
pub renderer: Renderer,
|
|
92
102
|
pub presentation: Presentation,
|
|
103
|
+
pub workspace: Workspace,
|
|
93
104
|
}
|
|
94
105
|
|
|
95
106
|
impl PartialEq for SettingsPanelProps {
|
|
@@ -99,6 +110,7 @@ impl PartialEq for SettingsPanelProps {
|
|
|
99
110
|
&& self.available_plugins == rhs.available_plugins
|
|
100
111
|
&& self.has_table == rhs.has_table
|
|
101
112
|
&& self.named_column_count == rhs.named_column_count
|
|
113
|
+
&& self.plugin_static_config == rhs.plugin_static_config
|
|
102
114
|
&& self.view_config == rhs.view_config
|
|
103
115
|
&& self.plugin_config == rhs.plugin_config
|
|
104
116
|
&& self.drag_column == rhs.drag_column
|
|
@@ -116,6 +128,11 @@ pub enum SelectedTab {
|
|
|
116
128
|
Query,
|
|
117
129
|
Plugin,
|
|
118
130
|
Debug,
|
|
131
|
+
|
|
132
|
+
/// The embedded LLM agent's chat panel. The variant exists in every
|
|
133
|
+
/// build; its tab button and body render only under the `llm-agent`
|
|
134
|
+
/// feature, and only once `agentConfig()` has been called.
|
|
135
|
+
Chat,
|
|
119
136
|
}
|
|
120
137
|
|
|
121
138
|
#[function_component]
|
|
@@ -186,8 +203,15 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
186
203
|
.unwrap();
|
|
187
204
|
|
|
188
205
|
let group_rollups = plugin_config.get_group_rollups(&rollup_features);
|
|
206
|
+
let split_rollup_features = session_metadata
|
|
207
|
+
.get_features()
|
|
208
|
+
.map(|x| x.get_split_rollup_modes())
|
|
209
|
+
.unwrap();
|
|
210
|
+
|
|
211
|
+
let split_rollups = plugin_config.get_split_rollups(&split_rollup_features);
|
|
189
212
|
let mut update = ViewConfigUpdate {
|
|
190
213
|
group_rollup_mode: group_rollups.first().cloned(),
|
|
214
|
+
split_rollup_mode: split_rollups.first().cloned(),
|
|
191
215
|
..ViewConfigUpdate::default()
|
|
192
216
|
};
|
|
193
217
|
|
|
@@ -237,6 +261,52 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
237
261
|
}
|
|
238
262
|
};
|
|
239
263
|
|
|
264
|
+
// The chat tab is zero-affordance until `agentConfig()` is called; the
|
|
265
|
+
// subscription re-renders this panel when that happens (and as the
|
|
266
|
+
// transcript updates while the chat body is mounted).
|
|
267
|
+
#[cfg(feature = "llm-agent")]
|
|
268
|
+
let (chat_tab_button, chat_body) = {
|
|
269
|
+
let update = use_force_update();
|
|
270
|
+
let agent = presentation.agent.clone();
|
|
271
|
+
use_effect_with((), move |_| {
|
|
272
|
+
let sub = agent
|
|
273
|
+
.on_update
|
|
274
|
+
.add_notify_listener(&Callback::from(move |_| update.force_update()));
|
|
275
|
+
|
|
276
|
+
move || drop(sub)
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
let button = if presentation.agent.is_configured() {
|
|
280
|
+
let on_select_column = props.on_select_column.clone();
|
|
281
|
+
let set_chat = {
|
|
282
|
+
let on_select_tab = props.on_select_tab.clone();
|
|
283
|
+
Callback::from(move |_: PointerEvent| {
|
|
284
|
+
on_select_tab.emit(SelectedTab::Chat);
|
|
285
|
+
on_select_column.emit(None)
|
|
286
|
+
})
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
html! {
|
|
290
|
+
<div
|
|
291
|
+
id="chat_tabbar_tab"
|
|
292
|
+
class={tab_class(selected, SelectedTab::Chat)}
|
|
293
|
+
onpointerdown={set_chat}
|
|
294
|
+
/>
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
html! {}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
let body = html! {
|
|
301
|
+
<crate::components::chat_panel::ChatPanel agent={presentation.agent.clone()} />
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
(button, body)
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
#[cfg(not(feature = "llm-agent"))]
|
|
308
|
+
let (chat_tab_button, chat_body) = (html! {}, html! {});
|
|
309
|
+
|
|
240
310
|
let on_open_expr_panel = use_callback(props.on_select_column.clone(), |c, on_select| {
|
|
241
311
|
on_select.emit(Some(c))
|
|
242
312
|
});
|
|
@@ -270,6 +340,7 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
270
340
|
class={tab_class(selected, SelectedTab::Debug)}
|
|
271
341
|
onpointerdown={set_debug}
|
|
272
342
|
/>
|
|
343
|
+
{ chat_tab_button }
|
|
273
344
|
</div>
|
|
274
345
|
if selected == SelectedTab::Query {
|
|
275
346
|
<ColumnSelector
|
|
@@ -278,6 +349,7 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
278
349
|
{selected_column}
|
|
279
350
|
has_table={props.has_table.clone()}
|
|
280
351
|
named_column_count={props.named_column_count}
|
|
352
|
+
plugin_static_config={props.plugin_static_config.clone()}
|
|
281
353
|
view_config={props.view_config.clone()}
|
|
282
354
|
drag_column={props.drag_column.clone()}
|
|
283
355
|
metadata={props.metadata.clone()}
|
|
@@ -298,11 +370,14 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
298
370
|
// initial_width={width}
|
|
299
371
|
// on_auto_width={on_auto_width.clone()}
|
|
300
372
|
/>
|
|
373
|
+
} else if selected == SelectedTab::Chat {
|
|
374
|
+
{ chat_body }
|
|
301
375
|
} else {
|
|
302
376
|
<DebugPanel
|
|
303
377
|
{presentation}
|
|
304
378
|
{renderer}
|
|
305
379
|
{session}
|
|
380
|
+
workspace={props.workspace.clone()}
|
|
306
381
|
initial_width={width}
|
|
307
382
|
on_auto_width={on_auto_width.clone()}
|
|
308
383
|
/>
|
|
@@ -310,7 +385,10 @@ pub fn SettingsPanel(props: &SettingsPanelProps) -> Html {
|
|
|
310
385
|
// Sibling sizer keeps the panel width pinned across tab
|
|
311
386
|
// switches; lives outside the tab-body so it survives the
|
|
312
387
|
// tab subtree's unmount.
|
|
313
|
-
<div
|
|
388
|
+
<div
|
|
389
|
+
class="scroll-panel-auto-width"
|
|
390
|
+
style={format!("width:{}px", width)}
|
|
391
|
+
/>
|
|
314
392
|
</div>
|
|
315
393
|
}
|
|
316
394
|
}
|
|
@@ -46,6 +46,8 @@ pub struct MasterSelection {
|
|
|
46
46
|
#[derive(Debug)]
|
|
47
47
|
pub enum PerspectiveViewerMsg {
|
|
48
48
|
ColumnSettingsPanelSizeUpdate(Option<i32>),
|
|
49
|
+
ColumnSettingsPanelAutoWidth(f64),
|
|
50
|
+
ToggleColumnSettingsPin,
|
|
49
51
|
ColumnSettingsTabChanged(ColumnSettingsTab),
|
|
50
52
|
OpenColumnSettings {
|
|
51
53
|
locator: Option<ColumnLocator>,
|
|
@@ -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, ViewerConfigUpdate};
|
|
31
31
|
use crate::queries::*;
|
|
32
32
|
use crate::renderer::Renderer;
|
|
33
33
|
use crate::session::*;
|
|
@@ -216,18 +216,18 @@ impl PerspectiveViewer {
|
|
|
216
216
|
|
|
217
217
|
pub(super) fn on_new_panel(&mut self, ctx: &Context<Self>, id: String) -> bool {
|
|
218
218
|
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())
|
|
219
|
+
let Some(table_name) = panel.session.get_table().map(|t| t.get_name().to_owned())
|
|
220
|
+
else {
|
|
221
|
+
tracing::warn!("Source panel has no `Table` to create a new panel from");
|
|
222
|
+
return false;
|
|
223
|
+
};
|
|
224
|
+
|
|
220
225
|
let elem = ctx.props().elem.clone();
|
|
221
226
|
let presentation = ctx.props().presentation.clone();
|
|
222
227
|
let workspace = ctx.props().workspace.clone();
|
|
223
228
|
let notify = ctx.link().callback(|_: ()| LayoutChanged);
|
|
224
229
|
let activate = ctx.link().callback(|id| SetActivePanel(id, None));
|
|
225
230
|
ApiFuture::spawn(async move {
|
|
226
|
-
let update = ViewerConfigUpdate {
|
|
227
|
-
table: table_name.map(TableUpdate::Update).unwrap_or_default(),
|
|
228
|
-
..Default::default()
|
|
229
|
-
};
|
|
230
|
-
|
|
231
231
|
let client = panel.session.get_client();
|
|
232
232
|
let new_id = create_panel(
|
|
233
233
|
&elem,
|
|
@@ -235,7 +235,7 @@ impl PerspectiveViewer {
|
|
|
235
235
|
&workspace,
|
|
236
236
|
¬ify,
|
|
237
237
|
None,
|
|
238
|
-
|
|
238
|
+
ViewerConfigInitial::new(table_name).into(),
|
|
239
239
|
client,
|
|
240
240
|
)
|
|
241
241
|
.await?;
|
|
@@ -273,18 +273,13 @@ impl PerspectiveViewer {
|
|
|
273
273
|
let notify = ctx.link().callback(|_: ()| LayoutChanged);
|
|
274
274
|
let activate = ctx.link().callback(|id| SetActivePanel(id, None));
|
|
275
275
|
ApiFuture::spawn(async move {
|
|
276
|
-
let update = ViewerConfigUpdate {
|
|
277
|
-
table: TableUpdate::Update(table),
|
|
278
|
-
..Default::default()
|
|
279
|
-
};
|
|
280
|
-
|
|
281
276
|
let new_id = create_panel(
|
|
282
277
|
&elem,
|
|
283
278
|
&presentation,
|
|
284
279
|
&workspace,
|
|
285
280
|
¬ify,
|
|
286
281
|
None,
|
|
287
|
-
|
|
282
|
+
ViewerConfigInitial::new(table).into(),
|
|
288
283
|
Some(client),
|
|
289
284
|
)
|
|
290
285
|
.await?;
|
|
@@ -94,6 +94,7 @@ impl PerspectiveViewer {
|
|
|
94
94
|
{available_plugins}
|
|
95
95
|
{has_table}
|
|
96
96
|
{named_column_count}
|
|
97
|
+
plugin_static_config={self.renderer_props.config.clone()}
|
|
97
98
|
{view_config}
|
|
98
99
|
plugin_config={self.renderer_props.plugin_config.clone()}
|
|
99
100
|
{drag_column}
|
|
@@ -108,6 +109,7 @@ impl PerspectiveViewer {
|
|
|
108
109
|
{presentation}
|
|
109
110
|
{renderer}
|
|
110
111
|
{session}
|
|
112
|
+
workspace={ctx.props().workspace.clone()}
|
|
111
113
|
/>
|
|
112
114
|
}
|
|
113
115
|
} else {
|
|
@@ -116,10 +118,18 @@ impl PerspectiveViewer {
|
|
|
116
118
|
|
|
117
119
|
let on_settings = ctx.link().callback(|()| ToggleSettingsInit(None, None));
|
|
118
120
|
let on_select_tab = ctx.link().callback(ColumnSettingsTabChanged);
|
|
121
|
+
// Pinning the drawer is a pure CSS positioning flip on `#modal_panel`
|
|
122
|
+
// (absolute overlay over the main panel <-> static flex sibling
|
|
123
|
+
// between the main panel and the settings pane) - the drawer NEVER
|
|
124
|
+
// reparents, so neither `MainPanel` nor the drawer subtree remounts
|
|
125
|
+
// on toggle, and the divider/width-override machinery is identical
|
|
126
|
+
// in both modes.
|
|
127
|
+
let is_pinned = self.settings_geometry.column_settings_pinned;
|
|
119
128
|
let column_settings_panel = html! {
|
|
120
129
|
if let Some(selected_column) = selected_column {
|
|
121
130
|
<SplitPanel
|
|
122
131
|
id="modal_panel"
|
|
132
|
+
class={classes!(is_pinned.then_some("pinned"))}
|
|
123
133
|
reverse=true
|
|
124
134
|
initial_size={self.settings_geometry.column_settings_width_override}
|
|
125
135
|
on_reset={ctx.link().callback(|_| ColumnSettingsPanelSizeUpdate(None))}
|
|
@@ -130,6 +140,10 @@ impl PerspectiveViewer {
|
|
|
130
140
|
{selected_tab}
|
|
131
141
|
on_close={self.on_close_column_settings.clone()}
|
|
132
142
|
width_override={self.settings_geometry.column_settings_width_override}
|
|
143
|
+
auto_width={self.settings_geometry.column_settings_auto_width}
|
|
144
|
+
on_auto_width={ctx.link().callback(ColumnSettingsPanelAutoWidth)}
|
|
145
|
+
{is_pinned}
|
|
146
|
+
on_toggle_pin={ctx.link().callback(|()| ToggleColumnSettingsPin)}
|
|
133
147
|
{on_select_tab}
|
|
134
148
|
plugin_name={self.renderer_props.plugin_name.clone()}
|
|
135
149
|
{metadata}
|
|
@@ -57,6 +57,18 @@ pub(super) struct SettingsGeometry {
|
|
|
57
57
|
|
|
58
58
|
/// User-dragged column-settings drawer width override.
|
|
59
59
|
pub column_settings_width_override: Option<i32>,
|
|
60
|
+
|
|
61
|
+
/// High-water-mark auto width reported by the column-settings drawer -
|
|
62
|
+
/// the trap-door shared across its Style/Attributes/Window tabs, lifted
|
|
63
|
+
/// here (like `auto_width`) so it survives drawer re-opens and clears
|
|
64
|
+
/// on divider reset.
|
|
65
|
+
pub column_settings_auto_width: f64,
|
|
66
|
+
|
|
67
|
+
/// Whether the column-settings drawer is PINNED - laid out as a static
|
|
68
|
+
/// flex sibling between the main panel and the settings panel - rather
|
|
69
|
+
/// than FLOATING over the main panel (the default absolute overlay).
|
|
70
|
+
/// Session UI state, not part of the saved config.
|
|
71
|
+
pub column_settings_pinned: bool,
|
|
60
72
|
}
|
|
61
73
|
|
|
62
74
|
impl PerspectiveViewer {
|
|
@@ -373,7 +385,27 @@ impl PerspectiveViewer {
|
|
|
373
385
|
|
|
374
386
|
pub(super) fn on_column_settings_panel_size_update(&mut self, x: Option<i32>) -> bool {
|
|
375
387
|
self.settings_geometry.column_settings_width_override = x;
|
|
376
|
-
|
|
388
|
+
if x.is_none() {
|
|
389
|
+
self.settings_geometry.column_settings_auto_width = 0.0;
|
|
390
|
+
true
|
|
391
|
+
} else {
|
|
392
|
+
false
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
pub(super) fn on_column_settings_panel_auto_width(&mut self, w: f64) -> bool {
|
|
397
|
+
if w > self.settings_geometry.column_settings_auto_width {
|
|
398
|
+
self.settings_geometry.column_settings_auto_width = w;
|
|
399
|
+
true
|
|
400
|
+
} else {
|
|
401
|
+
false
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
pub(super) fn on_toggle_column_settings_pin(&mut self) -> bool {
|
|
406
|
+
self.settings_geometry.column_settings_pinned =
|
|
407
|
+
!self.settings_geometry.column_settings_pinned;
|
|
408
|
+
true
|
|
377
409
|
}
|
|
378
410
|
|
|
379
411
|
pub(super) fn on_column_settings_tab_changed(
|
|
@@ -338,6 +338,8 @@ impl Component for PerspectiveViewer {
|
|
|
338
338
|
toggle,
|
|
339
339
|
} => self.on_open_column_settings(ctx, locator, sender, toggle),
|
|
340
340
|
ColumnSettingsPanelSizeUpdate(x) => self.on_column_settings_panel_size_update(x),
|
|
341
|
+
ColumnSettingsPanelAutoWidth(w) => self.on_column_settings_panel_auto_width(w),
|
|
342
|
+
ToggleColumnSettingsPin => self.on_toggle_column_settings_pin(),
|
|
341
343
|
ColumnSettingsTabChanged(tab) => self.on_column_settings_tab_changed(ctx, tab),
|
|
342
344
|
ToggleDebug => self.on_toggle_debug(ctx),
|
|
343
345
|
|