@perspective-dev/viewer 5.2.0 → 5.3.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 +8 -8
- package/dist/cdn/perspective-viewer.js.map +3 -3
- package/dist/css/blueprint.css +1 -0
- package/dist/css/botanical.css +1 -1
- package/dist/css/dracula.css +1 -1
- package/dist/css/eggplant.css +1 -0
- package/dist/css/gruvbox-dark.css +1 -1
- package/dist/css/gruvbox.css +1 -1
- package/dist/css/icons.css +1 -1
- package/dist/css/intl/de.css +1 -1
- package/dist/css/intl/es.css +1 -1
- package/dist/css/intl/fr.css +1 -1
- package/dist/css/intl/ja.css +1 -1
- package/dist/css/intl/pt.css +1 -1
- package/dist/css/intl/zh.css +1 -1
- package/dist/css/intl.css +1 -1
- package/dist/css/ledger.css +1 -0
- package/dist/css/monokai.css +1 -1
- package/dist/css/nord.css +1 -0
- package/dist/css/phosphor.css +1 -1
- package/dist/css/pro-dark.css +1 -1
- package/dist/css/pro.css +1 -1
- package/dist/css/solarized-dark.css +1 -1
- package/dist/css/solarized.css +1 -1
- package/dist/css/themes.css +1 -1
- package/dist/css/vaporwave.css +1 -1
- package/dist/css/velvet.css +1 -0
- package/dist/docs/perspective-docs.json +1 -1
- package/dist/esm/column-format.d.ts +16 -3
- package/dist/esm/perspective-viewer.d.ts +1 -0
- package/dist/esm/perspective-viewer.inline.js +9 -9
- package/dist/esm/perspective-viewer.inline.js.map +3 -3
- package/dist/esm/perspective-viewer.js +8 -8
- package/dist/esm/perspective-viewer.js.map +3 -3
- package/dist/esm/plugin.d.ts +10 -0
- package/dist/esm/ts-rs/PanelViewerConfig.d.ts +1 -1
- package/dist/esm/ts-rs/SaveWorkspaceOptions.d.ts +10 -0
- package/dist/esm/ts-rs/ViewerConfig.d.ts +1 -1
- package/dist/esm/ts-rs/WorkspaceConfig.d.ts +9 -1
- package/dist/esm/ts-rs/WorkspaceConfigUpdate.d.ts +13 -3
- package/dist/wasm/perspective-viewer.d.ts +43 -36
- package/dist/wasm/perspective-viewer.js +198 -136
- package/dist/wasm/perspective-viewer.wasm +0 -0
- package/dist/wasm/perspective-viewer.wasm.d.ts +19 -17
- package/package.json +1 -1
- package/src/css/column-settings-panel.css +28 -5
- package/src/css/column-style.css +291 -31
- package/src/css/containers/tabs.css +13 -3
- package/src/css/dom/select.css +21 -9
- package/src/css/form/code-editor.css +4 -4
- package/src/css/plugin-selector.css +1 -0
- package/src/css/plugin-settings-panel.css +72 -0
- package/src/css/viewer.css +0 -5
- package/src/rust/agent/tools.rs +53 -19
- 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 +8 -0
- 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 +48 -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 +330 -234
- package/src/rust/components/column_settings_sidebar.rs +88 -69
- package/src/rust/components/containers/control_group.rs +91 -0
- package/src/rust/components/containers/mod.rs +1 -0
- package/src/rust/components/containers/select.rs +8 -2
- package/src/rust/components/datetime_column_style/simple.rs +15 -4
- package/src/rust/components/datetime_column_style.rs +50 -10
- 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 +16 -6
- package/src/rust/components/form/debug.rs +1 -0
- package/src/rust/components/form/mod.rs +3 -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/plugin_tab.rs +126 -112
- package/src/rust/components/settings_panel.rs +26 -20
- package/src/rust/components/status_bar.rs +0 -1
- package/src/rust/components/style_controls/number_string_format/digits_section.rs +22 -10
- package/src/rust/components/style_controls/number_string_format/misc_section.rs +6 -2
- package/src/rust/components/style_controls/number_string_format/style_section.rs +1 -0
- package/src/rust/components/style_controls/number_string_format/types.rs +24 -0
- package/src/rust/components/style_controls/number_string_format.rs +37 -14
- package/src/rust/components/viewer/msg.rs +46 -7
- package/src/rust/components/viewer/panels.rs +11 -9
- package/src/rust/components/viewer/render.rs +8 -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/config/column_config_schema.rs +435 -45
- package/src/rust/config/css_scale.rs +882 -0
- package/src/rust/config/datetime_column_style.rs +4 -21
- package/src/rust/config/mod.rs +2 -0
- package/src/rust/config/number_string_format.rs +211 -18
- package/src/rust/config/options.rs +10 -0
- package/src/rust/config/viewer_config.rs +49 -55
- package/src/rust/config/workspace_config.rs +132 -5
- package/src/rust/custom_elements/viewer.rs +214 -155
- package/src/rust/custom_events.rs +14 -1
- package/src/rust/js/regular_layout.rs +3 -3
- package/src/rust/lib.rs +2 -0
- package/src/rust/presentation/column_locator.rs +19 -5
- package/src/rust/presentation.rs +209 -36
- package/src/rust/queries/column_locator.rs +74 -44
- package/src/rust/queries/get_viewer_config.rs +0 -3
- 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 +50 -12
- package/src/rust/renderer/plugin_config.rs +362 -53
- package/src/rust/renderer.rs +15 -42
- package/src/rust/session/column_defaults_update.rs +15 -8
- package/src/rust/session/metadata.rs +5 -1
- package/src/rust/session/props.rs +1 -0
- package/src/rust/session.rs +9 -6
- package/src/rust/tasks/create_panel.rs +44 -57
- package/src/rust/tasks/edit_expression.rs +19 -23
- package/src/rust/tasks/edit_window.rs +8 -10
- 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 +11 -13
- package/src/rust/tasks/set_edit_mode.rs +3 -1
- package/src/rust/tasks/sync_update_panels.rs +11 -1
- 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 +435 -272
- package/src/svg/lock.svg +7 -0
- package/src/themes/blueprint.css +190 -0
- package/src/themes/botanical.css +14 -17
- package/src/themes/defaults.css +4 -110
- package/src/themes/dracula.css +19 -14
- package/src/themes/eggplant.css +189 -0
- package/src/themes/gruvbox-dark.css +23 -15
- package/src/themes/gruvbox.css +11 -1
- package/src/themes/icons.css +2 -2
- package/src/themes/intl/de.css +23 -1
- package/src/themes/intl/es.css +23 -1
- package/src/themes/intl/fr.css +23 -1
- package/src/themes/intl/ja.css +23 -1
- package/src/themes/intl/pt.css +23 -1
- package/src/themes/intl/zh.css +23 -1
- package/src/themes/intl.css +26 -4
- package/src/themes/ledger.css +195 -0
- package/src/themes/monokai.css +24 -14
- package/src/themes/nord.css +186 -0
- package/src/themes/phosphor.css +7 -14
- package/src/themes/pro-dark.css +12 -16
- package/src/themes/pro.css +118 -0
- package/src/themes/solarized-dark.css +9 -16
- package/src/themes/solarized.css +7 -0
- package/src/themes/themes.css +10 -5
- package/src/themes/vaporwave.css +22 -14
- package/src/themes/velvet.css +192 -0
- package/src/ts/column-format.ts +52 -2
- package/src/ts/perspective-viewer.ts +1 -0
- package/src/ts/plugin.ts +14 -0
- package/src/ts/ts-rs/PanelViewerConfig.ts +1 -1
- package/src/ts/ts-rs/SaveWorkspaceOptions.ts +11 -0
- package/src/ts/ts-rs/ViewerConfig.ts +1 -1
- package/src/ts/ts-rs/WorkspaceConfig.ts +8 -2
- package/src/ts/ts-rs/WorkspaceConfigUpdate.ts +11 -3
- package/src/rust/components/form/color_range_selector.rs +0 -137
- package/src/svg/dropdown-selector-light.svg +0 -3
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline0.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline1.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline2.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline3.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline4.js +0 -0
- /package/dist/wasm/snippets/{perspective-viewer-02e461f3d7062b26 → perspective-viewer-87bd21b215d0631a}/inline5.js +0 -0
|
@@ -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,
|
|
@@ -235,7 +236,7 @@ impl PerspectiveViewer {
|
|
|
235
236
|
&workspace,
|
|
236
237
|
¬ify,
|
|
237
238
|
None,
|
|
238
|
-
ViewerConfigInitial::new(table_name)
|
|
239
|
+
ViewerConfigInitial::new(table_name),
|
|
239
240
|
client,
|
|
240
241
|
)
|
|
241
242
|
.await?;
|
|
@@ -279,7 +280,7 @@ impl PerspectiveViewer {
|
|
|
279
280
|
&workspace,
|
|
280
281
|
¬ify,
|
|
281
282
|
None,
|
|
282
|
-
ViewerConfigInitial::new(table)
|
|
283
|
+
ViewerConfigInitial::new(table),
|
|
283
284
|
Some(client),
|
|
284
285
|
)
|
|
285
286
|
.await?;
|
|
@@ -308,11 +309,12 @@ impl PerspectiveViewer {
|
|
|
308
309
|
let presentation = ctx.props().presentation.clone();
|
|
309
310
|
let workspace = ctx.props().workspace.clone();
|
|
310
311
|
ApiFuture::spawn(async move {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
{
|
|
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()) {
|
|
315
316
|
presentation.set_theme_name(Some(&theme)).await?;
|
|
317
|
+
presentation.publish_theme_config().await?;
|
|
316
318
|
}
|
|
317
319
|
|
|
318
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,
|
|
@@ -116,7 +118,9 @@ impl PerspectiveViewer {
|
|
|
116
118
|
html! { <></> }
|
|
117
119
|
};
|
|
118
120
|
|
|
119
|
-
let on_settings = ctx
|
|
121
|
+
let on_settings = ctx
|
|
122
|
+
.link()
|
|
123
|
+
.callback(|()| ToggleSettingsInit(None, true, None));
|
|
120
124
|
let on_select_tab = ctx.link().callback(ColumnSettingsTabChanged);
|
|
121
125
|
// Pinning the drawer is a pure CSS positioning flip on `#modal_panel`
|
|
122
126
|
// (absolute overlay over the main panel <-> static flex sibling
|
|
@@ -153,6 +157,7 @@ impl PerspectiveViewer {
|
|
|
153
157
|
{presentation}
|
|
154
158
|
{renderer}
|
|
155
159
|
{session}
|
|
160
|
+
workspace={ctx.props().workspace.clone()}
|
|
156
161
|
/>
|
|
157
162
|
<></>
|
|
158
163
|
</SplitPanel>
|
|
@@ -25,7 +25,8 @@ use super::msg::PerspectiveViewerMsg::*;
|
|
|
25
25
|
use crate::components::font_loader::FontLoaderStatus;
|
|
26
26
|
use crate::components::settings_panel::SelectedTab;
|
|
27
27
|
use crate::config::*;
|
|
28
|
-
use crate::presentation::{
|
|
28
|
+
use crate::presentation::{ColumnSettingsTab, ColumnSettingsTarget, OpenColumnSettings};
|
|
29
|
+
use crate::queries::get_current_column_locator;
|
|
29
30
|
use crate::tasks::*;
|
|
30
31
|
|
|
31
32
|
/// The settings sidebar's geometry state, folded into one field on
|
|
@@ -69,6 +70,19 @@ pub(super) struct SettingsGeometry {
|
|
|
69
70
|
/// than FLOATING over the main panel (the default absolute overlay).
|
|
70
71
|
/// Session UI state, not part of the saved config.
|
|
71
72
|
pub column_settings_pinned: bool,
|
|
73
|
+
|
|
74
|
+
/// Latest-wins deferred `open_column_settings` snapshot: the newest
|
|
75
|
+
/// target not yet applied while a docked-drawer presize sweep is in
|
|
76
|
+
/// flight. `UpdateColumnSettingsCommit` applies THIS slot (not a copy
|
|
77
|
+
/// captured at spawn), so a newer target arriving mid-sweep wins and
|
|
78
|
+
/// out-of-order commits are inexpressible.
|
|
79
|
+
pub column_settings_target: Option<OpenColumnSettings>,
|
|
80
|
+
pub column_settings_commit_pending: bool,
|
|
81
|
+
|
|
82
|
+
/// The docked drawer's span, cached whenever it is measurable (pin
|
|
83
|
+
/// toggle, docked unmount) - used to presize for a drawer that MOUNTS
|
|
84
|
+
/// directly into pinned mode, when it isn't in the DOM to measure.
|
|
85
|
+
pub column_settings_docked_width: Option<f64>,
|
|
72
86
|
}
|
|
73
87
|
|
|
74
88
|
impl PerspectiveViewer {
|
|
@@ -76,6 +90,7 @@ impl PerspectiveViewer {
|
|
|
76
90
|
&mut self,
|
|
77
91
|
ctx: &Context<Self>,
|
|
78
92
|
update: Option<SettingsUpdate>,
|
|
93
|
+
announce: bool,
|
|
79
94
|
resolve: Option<Sender<ApiResult<JsValue>>>,
|
|
80
95
|
) -> bool {
|
|
81
96
|
match (update, resolve) {
|
|
@@ -85,15 +100,15 @@ impl PerspectiveViewer {
|
|
|
85
100
|
false
|
|
86
101
|
},
|
|
87
102
|
(Some(SettingsUpdate::SetDefault), resolve) => {
|
|
88
|
-
self.init_toggle_settings_task(ctx, Some(false), resolve);
|
|
103
|
+
self.init_toggle_settings_task(ctx, Some(false), announce, resolve);
|
|
89
104
|
false
|
|
90
105
|
},
|
|
91
106
|
(Some(SettingsUpdate::Update(force)), resolve) => {
|
|
92
|
-
self.init_toggle_settings_task(ctx, Some(force), resolve);
|
|
107
|
+
self.init_toggle_settings_task(ctx, Some(force), announce, resolve);
|
|
93
108
|
false
|
|
94
109
|
},
|
|
95
110
|
(None, resolve) => {
|
|
96
|
-
self.init_toggle_settings_task(ctx, None, resolve);
|
|
111
|
+
self.init_toggle_settings_task(ctx, None, announce, resolve);
|
|
97
112
|
false
|
|
98
113
|
},
|
|
99
114
|
}
|
|
@@ -150,10 +165,10 @@ impl PerspectiveViewer {
|
|
|
150
165
|
&mut self,
|
|
151
166
|
ctx: &Context<Self>,
|
|
152
167
|
force: Option<bool>,
|
|
168
|
+
announce: bool,
|
|
153
169
|
sender: Option<Sender<ApiResult<JsValue>>>,
|
|
154
170
|
) {
|
|
155
171
|
let is_open = ctx.props().presentation.is_settings_open();
|
|
156
|
-
ctx.props().presentation.set_settings_before_open(!is_open);
|
|
157
172
|
match force {
|
|
158
173
|
Some(force) if is_open == force => {
|
|
159
174
|
if let Some(sender) = sender {
|
|
@@ -161,6 +176,7 @@ impl PerspectiveViewer {
|
|
|
161
176
|
}
|
|
162
177
|
},
|
|
163
178
|
Some(_) | None => {
|
|
179
|
+
ctx.props().presentation.set_settings_before_open(!is_open);
|
|
164
180
|
let force = !is_open;
|
|
165
181
|
let callback = ctx.link().callback(move |resolve| {
|
|
166
182
|
let update = SettingsUpdate::Update(force);
|
|
@@ -195,7 +211,7 @@ impl PerspectiveViewer {
|
|
|
195
211
|
let presents = presize_visible_panels_grown(&workspace, &elem).await;
|
|
196
212
|
let (notify, rendered) = channel::<()>();
|
|
197
213
|
callback.emit(notify);
|
|
198
|
-
presentation.set_settings_open(false);
|
|
214
|
+
presentation.set_settings_open(false, announce);
|
|
199
215
|
rendered.await?;
|
|
200
216
|
// `notify` fires in `rendered()` (same task as the
|
|
201
217
|
// Yew DOM patch) and this future resumes as one of
|
|
@@ -219,7 +235,7 @@ impl PerspectiveViewer {
|
|
|
219
235
|
|
|
220
236
|
let (notify, rendered) = channel::<()>();
|
|
221
237
|
callback.emit(notify);
|
|
222
|
-
presentation.set_settings_open(true);
|
|
238
|
+
presentation.set_settings_open(true, announce);
|
|
223
239
|
rendered.await?;
|
|
224
240
|
presents.reveal();
|
|
225
241
|
resize_visible_panels(&workspace).await;
|
|
@@ -339,36 +355,34 @@ impl PerspectiveViewer {
|
|
|
339
355
|
pub(super) fn on_open_column_settings(
|
|
340
356
|
&mut self,
|
|
341
357
|
ctx: &Context<Self>,
|
|
342
|
-
|
|
358
|
+
target: Option<ColumnSettingsTarget>,
|
|
343
359
|
sender: Option<Sender<()>>,
|
|
344
360
|
toggle: bool,
|
|
345
361
|
) -> bool {
|
|
346
362
|
let mut open_column_settings = ctx.props().presentation.get_open_column_settings();
|
|
347
|
-
if
|
|
363
|
+
if target == open_column_settings.target {
|
|
348
364
|
if toggle {
|
|
349
365
|
ctx.props().presentation.set_open_column_settings(None);
|
|
350
366
|
}
|
|
351
367
|
} else {
|
|
352
|
-
open_column_settings.
|
|
353
|
-
open_column_settings.tab =
|
|
354
|
-
Some(ColumnSettingsTab::Attributes)
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
} else {
|
|
361
|
-
ColumnSettingsTab::Attributes
|
|
362
|
-
}
|
|
368
|
+
open_column_settings.target.clone_from(&target);
|
|
369
|
+
open_column_settings.tab = match &target {
|
|
370
|
+
Some(ColumnSettingsTarget::NewExpression) => Some(ColumnSettingsTab::Attributes),
|
|
371
|
+
Some(ColumnSettingsTarget::Column(name)) => {
|
|
372
|
+
Some(if self.session_props.is_column_active(name) {
|
|
373
|
+
ColumnSettingsTab::Style
|
|
374
|
+
} else {
|
|
375
|
+
ColumnSettingsTab::Attributes
|
|
363
376
|
})
|
|
364
|
-
}
|
|
377
|
+
},
|
|
378
|
+
None => None,
|
|
365
379
|
};
|
|
366
380
|
|
|
367
381
|
ctx.props()
|
|
368
382
|
.presentation
|
|
369
383
|
.set_open_column_settings(Some(open_column_settings));
|
|
370
384
|
|
|
371
|
-
if
|
|
385
|
+
if target.is_some() {
|
|
372
386
|
self.settings_geometry.selected_tab = SelectedTab::Query;
|
|
373
387
|
}
|
|
374
388
|
}
|
|
@@ -402,9 +416,135 @@ impl PerspectiveViewer {
|
|
|
402
416
|
}
|
|
403
417
|
}
|
|
404
418
|
|
|
405
|
-
pub(super) fn on_toggle_column_settings_pin(&mut self) -> bool {
|
|
419
|
+
pub(super) fn on_toggle_column_settings_pin(&mut self, ctx: &Context<Self>) -> bool {
|
|
420
|
+
let is_pinned = self.settings_geometry.column_settings_pinned;
|
|
421
|
+
let delta_w = measure_column_settings_pin_delta(&ctx.props().elem, is_pinned);
|
|
422
|
+
if let Some(delta_w) = delta_w {
|
|
423
|
+
self.settings_geometry.column_settings_docked_width = Some(delta_w.abs());
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
self.presize_column_settings_shift(ctx, delta_w, ToggleColumnSettingsPinComplete);
|
|
427
|
+
false
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
pub(super) fn on_toggle_column_settings_pin_complete(&mut self, resolve: Sender<()>) -> bool {
|
|
406
431
|
self.settings_geometry.column_settings_pinned =
|
|
407
432
|
!self.settings_geometry.column_settings_pinned;
|
|
433
|
+
self.on_rendered.push(resolve);
|
|
434
|
+
true
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/// Shared presize choreography for a column-settings geometry shift:
|
|
438
|
+
/// pre-size every visible panel by `delta_w` (`None` = no sweep, commit
|
|
439
|
+
/// only), send `commit_msg` to apply the deferred state on the render
|
|
440
|
+
/// commit, reveal the staged frames in that same paint, then reactively
|
|
441
|
+
/// finalize at the exact settled cells (I6).
|
|
442
|
+
fn presize_column_settings_shift(
|
|
443
|
+
&self,
|
|
444
|
+
ctx: &Context<Self>,
|
|
445
|
+
delta_w: Option<f64>,
|
|
446
|
+
commit_msg: fn(Sender<()>) -> super::msg::PerspectiveViewerMsg,
|
|
447
|
+
) {
|
|
448
|
+
let workspace = ctx.props().workspace.clone();
|
|
449
|
+
let elem = ctx.props().elem.clone();
|
|
450
|
+
let callback = ctx.link().callback(commit_msg);
|
|
451
|
+
ApiFuture::spawn(async move {
|
|
452
|
+
let presents = match delta_w {
|
|
453
|
+
Some(delta_w) => presize_visible_panels_open(&workspace, &elem, delta_w, 0.0).await,
|
|
454
|
+
None => StagedPresents::default(),
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
let (notify, rendered) = channel::<()>();
|
|
458
|
+
callback.emit(notify);
|
|
459
|
+
rendered.await?;
|
|
460
|
+
presents.reveal();
|
|
461
|
+
resize_visible_panels(&workspace).await;
|
|
462
|
+
Ok(())
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/// Whether the drawer renders for this `open_column_settings` snapshot
|
|
467
|
+
/// (the `render()` mount predicate). Sensitive to the session snapshot
|
|
468
|
+
/// too — `snapshots.rs` re-evaluates it across an `UpdateSession` apply,
|
|
469
|
+
/// which can invalidate the open column's locator (e.g. a drag
|
|
470
|
+
/// replacing it in `columns`) and unmount the drawer without any
|
|
471
|
+
/// `UpdateColumnSettings` traffic.
|
|
472
|
+
pub(super) fn is_column_settings_mounted(&self, ocs: &OpenColumnSettings) -> bool {
|
|
473
|
+
get_current_column_locator(
|
|
474
|
+
ocs,
|
|
475
|
+
&self.active_renderer,
|
|
476
|
+
&self.session_props.config,
|
|
477
|
+
&self.session_props.metadata,
|
|
478
|
+
)
|
|
479
|
+
.is_some()
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/// The `open_column_settings` snapshot handler: mount/unmount of the
|
|
483
|
+
/// DOCKED drawer moves `#main_panel_container`'s flex box just like the
|
|
484
|
+
/// pin toggle — and no `before-resize` fires for it — so those
|
|
485
|
+
/// transitions defer the snapshot behind the presize choreography.
|
|
486
|
+
/// Floating transitions and in-place locator changes apply synchronously
|
|
487
|
+
/// as before, unless a deferred commit is in flight (they queue into the
|
|
488
|
+
/// latest-wins slot to preserve commit order).
|
|
489
|
+
pub(super) fn on_update_column_settings(
|
|
490
|
+
&mut self,
|
|
491
|
+
ctx: &Context<Self>,
|
|
492
|
+
ocs: OpenColumnSettings,
|
|
493
|
+
) -> bool {
|
|
494
|
+
self.refresh_session_snapshot(ctx);
|
|
495
|
+
let effective = self
|
|
496
|
+
.settings_geometry
|
|
497
|
+
.column_settings_target
|
|
498
|
+
.as_ref()
|
|
499
|
+
.unwrap_or(&self.presentation_props.open_column_settings);
|
|
500
|
+
if ocs == *effective {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
let was_mounted =
|
|
505
|
+
self.is_column_settings_mounted(&self.presentation_props.open_column_settings);
|
|
506
|
+
let will_mount = self.is_column_settings_mounted(&ocs);
|
|
507
|
+
let needs_presize =
|
|
508
|
+
self.settings_geometry.column_settings_pinned && was_mounted != will_mount;
|
|
509
|
+
if !needs_presize && !self.settings_geometry.column_settings_commit_pending {
|
|
510
|
+
self.presentation_props.open_column_settings = ocs;
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
self.settings_geometry.column_settings_target = Some(ocs);
|
|
515
|
+
if self.settings_geometry.column_settings_commit_pending {
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
self.settings_geometry.column_settings_commit_pending = true;
|
|
520
|
+
let delta_w = if !needs_presize {
|
|
521
|
+
None
|
|
522
|
+
} else if was_mounted {
|
|
523
|
+
// Unmounting - the docked drawer is still in the DOM, and its
|
|
524
|
+
// freed span is the same measurement as an unpin.
|
|
525
|
+
let delta = measure_column_settings_pin_delta(&ctx.props().elem, true);
|
|
526
|
+
if let Some(delta) = delta {
|
|
527
|
+
self.settings_geometry.column_settings_docked_width = Some(delta.abs());
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
delta
|
|
531
|
+
} else {
|
|
532
|
+
// Mounting directly into pinned mode - not yet in the DOM; the
|
|
533
|
+
// span cached at the last dock/unmount predicts the shrink.
|
|
534
|
+
self.settings_geometry.column_settings_docked_width
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
self.presize_column_settings_shift(ctx, delta_w, UpdateColumnSettingsCommit);
|
|
538
|
+
false
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
pub(super) fn on_update_column_settings_commit(&mut self, resolve: Sender<()>) -> bool {
|
|
542
|
+
self.settings_geometry.column_settings_commit_pending = false;
|
|
543
|
+
self.on_rendered.push(resolve);
|
|
544
|
+
if let Some(ocs) = self.settings_geometry.column_settings_target.take() {
|
|
545
|
+
self.presentation_props.open_column_settings = ocs;
|
|
546
|
+
}
|
|
547
|
+
|
|
408
548
|
true
|
|
409
549
|
}
|
|
410
550
|
|
|
@@ -15,17 +15,45 @@
|
|
|
15
15
|
//! subscriptions/callbacks) into the root's props fields, re-rendering only
|
|
16
16
|
//! on an actual change.
|
|
17
17
|
|
|
18
|
+
use futures::channel::oneshot::channel;
|
|
19
|
+
use perspective_js::utils::ApiFuture;
|
|
18
20
|
use yew::prelude::*;
|
|
19
21
|
|
|
20
22
|
use super::PerspectiveViewer;
|
|
21
|
-
use crate::presentation::{DragDropProps,
|
|
23
|
+
use crate::presentation::{DragDropProps, PresentationProps};
|
|
22
24
|
use crate::renderer::RendererProps;
|
|
23
25
|
use crate::session::{SessionProps, TableLoadState, ViewStats};
|
|
26
|
+
use crate::tasks::resize_visible_panels;
|
|
24
27
|
|
|
25
28
|
impl PerspectiveViewer {
|
|
26
|
-
pub(super) fn
|
|
29
|
+
pub(super) fn refresh_session_snapshot(&mut self, ctx: &Context<Self>) {
|
|
30
|
+
let props = self.active_session.to_props();
|
|
31
|
+
if props != self.session_props {
|
|
32
|
+
self.on_update_session(ctx, props);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
pub(super) fn on_update_session(&mut self, ctx: &Context<Self>, props: SessionProps) -> bool {
|
|
27
37
|
let changed = props != self.session_props;
|
|
38
|
+
let was_mounted =
|
|
39
|
+
self.is_column_settings_mounted(&self.presentation_props.open_column_settings);
|
|
28
40
|
self.session_props = props;
|
|
41
|
+
let now_mounted =
|
|
42
|
+
self.is_column_settings_mounted(&self.presentation_props.open_column_settings);
|
|
43
|
+
if self.settings_geometry.column_settings_pinned
|
|
44
|
+
&& was_mounted != now_mounted
|
|
45
|
+
&& !self.settings_geometry.column_settings_commit_pending
|
|
46
|
+
{
|
|
47
|
+
let (notify, rendered) = channel::<()>();
|
|
48
|
+
self.on_rendered.push(notify);
|
|
49
|
+
let workspace = ctx.props().workspace.clone();
|
|
50
|
+
ApiFuture::spawn(async move {
|
|
51
|
+
rendered.await?;
|
|
52
|
+
resize_visible_panels(&workspace).await;
|
|
53
|
+
Ok(())
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
29
57
|
changed
|
|
30
58
|
}
|
|
31
59
|
|
|
@@ -52,18 +80,17 @@ impl PerspectiveViewer {
|
|
|
52
80
|
ctx: &Context<Self>,
|
|
53
81
|
props: PresentationProps,
|
|
54
82
|
) -> bool {
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
// that
|
|
65
|
-
// nothing
|
|
66
|
-
// gate is state, never call history or DOM state.
|
|
83
|
+
// Boot fill-in: theme discovery resolving turns an empty registry
|
|
84
|
+
// into a real one, and any panel created before that has no theme to
|
|
85
|
+
// stamp. Give those — and ONLY those — the new default, then restyle
|
|
86
|
+
// the ones whose captured `--psp-*` CSS is now stale
|
|
87
|
+
// (`Renderer::needs_restyle`; plugins re-read CSS only at
|
|
88
|
+
// `restyle()`/first-draw, so a plain redraw would not repaint them).
|
|
89
|
+
//
|
|
90
|
+
// A panel that already has a theme is never touched here: `theme` is
|
|
91
|
+
// concrete state, so re-ordering the registry — or any other
|
|
92
|
+
// `resetThemes` that leaves a panel's theme available — must repaint
|
|
93
|
+
// nothing.
|
|
67
94
|
let old_default = self.presentation_props.available_themes.first().cloned();
|
|
68
95
|
let new_default = props.available_themes.first().cloned();
|
|
69
96
|
if old_default != new_default {
|
|
@@ -74,7 +101,11 @@ impl PerspectiveViewer {
|
|
|
74
101
|
.into_iter()
|
|
75
102
|
.filter_map(|id| ctx.props().workspace.panel(&id))
|
|
76
103
|
{
|
|
77
|
-
panel.renderer.
|
|
104
|
+
if panel.renderer.theme().is_some() {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
panel.renderer.set_theme(new_default.clone());
|
|
78
109
|
if panel.renderer.needs_restyle() {
|
|
79
110
|
let renderer = panel.renderer.clone();
|
|
80
111
|
crate::utils::spawn_owned("default-theme-restyle", async move {
|
|
@@ -102,12 +133,6 @@ impl PerspectiveViewer {
|
|
|
102
133
|
changed
|
|
103
134
|
}
|
|
104
135
|
|
|
105
|
-
pub(super) fn on_update_column_settings(&mut self, ocs: OpenColumnSettings) -> bool {
|
|
106
|
-
let changed = ocs != self.presentation_props.open_column_settings;
|
|
107
|
-
self.presentation_props.open_column_settings = ocs;
|
|
108
|
-
changed
|
|
109
|
-
}
|
|
110
|
-
|
|
111
136
|
pub(super) fn on_update_dragdrop(&mut self, props: DragDropProps) -> bool {
|
|
112
137
|
let changed = props != self.dragdrop_props;
|
|
113
138
|
self.dragdrop_props = props;
|
|
@@ -343,7 +343,9 @@ pub(super) fn create_active_subscriptions(
|
|
|
343
343
|
pub(super) fn create_shared_subscriptions(ctx: &Context<PerspectiveViewer>) -> Vec<Subscription> {
|
|
344
344
|
let presentation_props_sub = {
|
|
345
345
|
let presentation = ctx.props().presentation.clone();
|
|
346
|
-
let cb_settings = ctx
|
|
346
|
+
let cb_settings = ctx
|
|
347
|
+
.link()
|
|
348
|
+
.callback(|(open, _): (bool, bool)| UpdateSettingsOpen(open));
|
|
347
349
|
let cb_theme = {
|
|
348
350
|
let pres = presentation.clone();
|
|
349
351
|
ctx.link()
|
|
@@ -368,17 +370,6 @@ pub(super) fn create_shared_subscriptions(ctx: &Context<PerspectiveViewer>) -> V
|
|
|
368
370
|
vec![sub1, sub2, sub3]
|
|
369
371
|
};
|
|
370
372
|
|
|
371
|
-
let dragdrop_props_sub = {
|
|
372
|
-
let cb_clear = ctx.link().callback(|_: ()| UpdateDragDrop(Box::default()));
|
|
373
|
-
let sub1 = ctx
|
|
374
|
-
.props()
|
|
375
|
-
.presentation
|
|
376
|
-
.drop_received
|
|
377
|
-
.add_notify_listener(&cb_clear);
|
|
378
|
-
|
|
379
|
-
vec![sub1]
|
|
380
|
-
};
|
|
381
|
-
|
|
382
373
|
// The `Workspace`-owned global filter set → the root's render snapshot.
|
|
383
374
|
let filters_sub = {
|
|
384
375
|
let cb = ctx.link().callback(|_: ()| UpdateGlobalFilters);
|
|
@@ -388,11 +379,12 @@ pub(super) fn create_shared_subscriptions(ctx: &Context<PerspectiveViewer>) -> V
|
|
|
388
379
|
.add_notify_listener(&cb)
|
|
389
380
|
};
|
|
390
381
|
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
//
|
|
382
|
+
// Panel-phase transitions (`Workspace::insert_panel` at
|
|
383
|
+
// `PanelPhase::Staging` / `Workspace::promote`) → a root re-render for
|
|
384
|
+
// the stage-level chrome (`only-child` class, binding resync).
|
|
385
|
+
// `MainPanel` inserts/reveals promoted panels via its OWN
|
|
386
|
+
// `staged_changed` subscription (`MainPanelMsg::StagedChanged`) — see
|
|
387
|
+
// `WorkspaceData::staged_changed`.
|
|
396
388
|
let staged_sub = {
|
|
397
389
|
let cb = ctx.link().callback(|_: ()| LayoutChanged);
|
|
398
390
|
ctx.props()
|
|
@@ -403,7 +395,6 @@ pub(super) fn create_shared_subscriptions(ctx: &Context<PerspectiveViewer>) -> V
|
|
|
403
395
|
|
|
404
396
|
let mut subscriptions = Vec::new();
|
|
405
397
|
subscriptions.extend(presentation_props_sub);
|
|
406
|
-
subscriptions.extend(dragdrop_props_sub);
|
|
407
398
|
subscriptions.push(filters_sub);
|
|
408
399
|
subscriptions.push(staged_sub);
|
|
409
400
|
subscriptions
|
|
@@ -446,15 +437,13 @@ pub(super) fn inject_active_callbacks(
|
|
|
446
437
|
let cb = ctx.link().batch_callback(move |limits: RenderLimits| {
|
|
447
438
|
let mut msgs = vec![UpdateRenderer(Box::new(r.to_props(Some(limits))))];
|
|
448
439
|
if !limits.is_update {
|
|
449
|
-
let
|
|
450
|
-
|
|
451
|
-
&r,
|
|
452
|
-
|
|
453
|
-
&s.metadata(),
|
|
454
|
-
);
|
|
440
|
+
let ocs = presentation.get_open_column_settings();
|
|
441
|
+
let still_open =
|
|
442
|
+
get_current_column_locator(&ocs, &r, &s.get_view_config(), &s.metadata())
|
|
443
|
+
.is_some();
|
|
455
444
|
|
|
456
445
|
msgs.push(OpenColumnSettings {
|
|
457
|
-
|
|
446
|
+
target: ocs.target.filter(|_| still_open),
|
|
458
447
|
sender: None,
|
|
459
448
|
toggle: false,
|
|
460
449
|
});
|