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, ViewerConfigInitial};
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::restoreWorkspace`]. Mirrors
63/// [`WorkspaceConfig`], but `panels` entries are [`ViewerConfigInitial`]s —
64/// every entry creates a NEW panel, so `table` is required by type (a
65/// stray per-panel `settings` key is ignored; it is element-level state,
66/// carried by the top-level `active` field).
67#[derive(serde::Deserialize, ts_rs::TS)]
68pub struct WorkspaceConfigUpdate {
69    #[serde(default)]
70    #[ts(optional)]
71    pub active: Option<String>,
72
73    #[serde(default)]
74    #[ts(optional)]
75    pub layout: Option<crate::js::Layout>,
76
77    pub panels: BTreeMap<String, ViewerConfigInitial>,
78
79    /// The element-level global (master/detail cross-) filters to re-apply as
80    /// a transient overlay on every DETAIL panel. Restored as one
81    /// unattributed bucket: the next selection on any master replaces it.
82    #[serde(default)]
83    #[ts(as = "Option<_>")]
84    #[ts(optional)]
85    pub global_filters: Vec<Filter>,
86
87    /// The master (filter-source) panels, by saved `panels` key. An id not in
88    /// `panels` warns and is dropped.
89    #[serde(default)]
90    #[ts(as = "Option<_>")]
91    #[ts(optional)]
92    pub masters: Vec<String>,
93}