Skip to main content

perspective_viewer/config/
workspace_config.rs

1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
3// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
4// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
5// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
6// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
8// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9// ┃ This file is part of the Perspective library, distributed under the terms ┃
10// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13use std::collections::BTreeMap;
14
15use perspective_client::config::Filter;
16
17use crate::config::{PanelViewerConfig, ViewerConfigUpdate};
18
19/// The whole-element config format (`{version, active?, layout, panels}`) —
20/// the multi-panel counterpart of the single-panel [`ViewerConfig`] — as
21/// emitted by [`PerspectiveViewerElement::save`].
22///
23/// - `panels` entries are [`PanelViewerConfig`]s: per-panel state only, no
24///   `settings` key (element-level state).
25/// - `active` names the panel targeted by the *open* settings sidebar; it is
26///   omitted when the sidebar is closed.
27#[derive(serde::Serialize, ts_rs::TS)]
28pub struct WorkspaceConfig {
29    pub version: String,
30
31    #[serde(skip_serializing_if = "Option::is_none")]
32    #[ts(optional)]
33    pub active: Option<String>,
34
35    pub layout: Option<crate::js::Layout>,
36
37    /// `BTreeMap` (not `HashMap`) so `save()` serializes panels in a
38    /// DETERMINISTIC (sorted) key order — a fresh `HashMap` per call
39    /// iterates in a per-instance random order, which made consecutive
40    /// `save()` outputs byte-unstable.
41    pub panels: BTreeMap<String, PanelViewerConfig>,
42
43    /// The element-level global (master/detail cross-) filters. A transient
44    /// overlay on every detail panel's view — persisted here, never in a
45    /// per-panel entry. Omitted when empty.
46    #[serde(skip_serializing_if = "Vec::is_empty")]
47    #[ts(as = "Option<_>")]
48    #[ts(optional)]
49    pub global_filters: Vec<Filter>,
50
51    /// The MASTER (filter-source) panels' ids, referencing `panels` keys.
52    /// Roles are layout state (like the panel arrangement), so they persist;
53    /// which master contributed which clause does not — restored
54    /// `global_filters` are one unattributed bucket. Omitted when empty.
55    #[serde(skip_serializing_if = "Vec::is_empty")]
56    #[ts(as = "Option<_>")]
57    #[ts(optional)]
58    pub masters: Vec<String>,
59}
60
61/// The parse target of a whole-element config in
62/// [`PerspectiveViewerElement::restore`]. Mirrors [`WorkspaceConfig`],
63/// but `panels` entries are full [`ViewerConfigUpdate`]s so a stray per-panel
64/// `settings` can be detected (warned, then ignored — `create_panel` strips
65/// it).
66#[derive(serde::Deserialize, ts_rs::TS)]
67pub struct WorkspaceConfigUpdate {
68    #[serde(default)]
69    #[ts(optional)]
70    pub active: Option<String>,
71
72    #[serde(default)]
73    #[ts(optional)]
74    pub layout: Option<crate::js::Layout>,
75
76    pub panels: BTreeMap<String, ViewerConfigUpdate>,
77
78    /// The element-level global (master/detail cross-) filters to re-apply as
79    /// a transient overlay on every DETAIL panel. Restored as one
80    /// unattributed bucket: the next selection on any master replaces it.
81    #[serde(default)]
82    #[ts(as = "Option<_>")]
83    #[ts(optional)]
84    pub global_filters: Vec<Filter>,
85
86    /// The master (filter-source) panels, by saved `panels` key. An id not in
87    /// `panels` warns and is dropped.
88    #[serde(default)]
89    #[ts(as = "Option<_>")]
90    #[ts(optional)]
91    pub masters: Vec<String>,
92}