pub struct Panel {
pub id: String,
pub kind: PanelKind,
pub namespace: String,
pub props: Props,
pub rows: Vec<Vec<Value>>,
pub source: Option<PanelSource>,
pub fields: Vec<Field>,
pub children: Vec<Panel>,
pub published: bool,
}Expand description
A resolved panel: definition facts plus whatever rows were loaded for it.
Fields§
§id: String§kind: PanelKind§namespace: String§props: Propspanel_prop(Id, Key, Value) pairs, values as sent.
rows: Vec<Vec<Value>>Rows: either the live panel_source result or the panel_data
snapshot. Resolution happens outside this crate — see PanelSource.
source: Option<PanelSource>§fields: Vec<Field>Form fields — parts of a form panel.
children: Vec<Panel>Child panels — parts of a dashboard (or any non-form container).
published: boolWhether the publisher marked this panel published.
Matches the server: published must be true (or "true"); an
absent prop means not published.
Implementations§
Source§impl Panel
impl Panel
Sourcepub fn all_from_facts(facts: &PanelFacts) -> Vec<Panel>
pub fn all_from_facts(facts: &PanelFacts) -> Vec<Panel>
Build every panel present in facts.
Parts (form fields, dashboard children) are folded into their container and removed from the top-level result, so callers get panels, not panels-and-their-parts.
Examples found in repository?
18fn main() {
19 let path = std::env::args()
20 .nth(1)
21 .expect("usage: parse_fixture <facts.json>");
22 let raw = std::fs::read_to_string(&path).expect("read fixture");
23 let doc: BTreeMap<String, Value> =
24 serde_json::from_str(&raw).expect("fixture is a JSON object");
25
26 let rows = |key: &str| -> Vec<Value> {
27 doc.get(key)
28 .and_then(Value::as_array)
29 .cloned()
30 .unwrap_or_default()
31 };
32
33 let facts = PanelFacts {
34 panels: rows("panels"),
35 props: rows("props"),
36 data: rows("data"),
37 sources: rows("sources"),
38 field_inputs: rows("field_inputs"),
39 field_triggers: rows("field_triggers"),
40 field_emits: rows("field_emits"),
41 };
42
43 println!(
44 "input rows: panels={} props={} data={} sources={} fields(in/trig/emit)={}/{}/{}",
45 facts.panels.len(),
46 facts.props.len(),
47 facts.data.len(),
48 facts.sources.len(),
49 facts.field_inputs.len(),
50 facts.field_triggers.len(),
51 facts.field_emits.len()
52 );
53
54 let panels = Panel::all_from_facts(&facts);
55 println!("parsed panels: {}\n", panels.len());
56
57 let mut unknown = 0;
58 for p in &panels {
59 let kind = p.kind.as_str().to_string();
60 if matches!(p.kind, datagrout_panels::PanelKind::Unknown(_)) {
61 unknown += 1;
62 }
63 println!(
64 "{:<24} {:<11} ns={:<20} props={:<2} rows={:<3} cols={:<2} source={} fields={} children={} published={}",
65 p.id,
66 kind,
67 p.namespace,
68 p.props.len(),
69 p.rows.len(),
70 p.rows.first().map(Vec::len).unwrap_or(0),
71 p.source.is_some(),
72 p.fields.len(),
73 p.children.len(),
74 p.published
75 );
76 for c in &p.children {
77 println!(
78 " └ {:<20} {:<11} rows={:<3} columns={:?}",
79 c.id,
80 c.kind.as_str(),
81 c.rows.len(),
82 c.columns()
83 );
84 }
85 }
86
87 // Anything a renderer would fall back on is worth calling out by name.
88 println!("\nunknown kinds: {unknown}");
89 let titled = panels
90 .iter()
91 .filter(|p| p.props.contains_key("title"))
92 .count();
93 println!("panels with a title prop: {titled}/{}", panels.len());
94}Sourcepub fn from_facts(facts: &PanelFacts, id: &str) -> Option<Panel>
pub fn from_facts(facts: &PanelFacts, id: &str) -> Option<Panel>
Build a single panel by id, or None if it is absent.
Sourcepub fn all_from_list(response: &Value) -> Vec<Panel>
pub fn all_from_list(response: &Value) -> Vec<Panel>
Build every panel from a smart_panel.list response.
Accepts either the whole response ({"panels": [...]}) or the bare
array. Each entry carries id, kind, namespace, props, and
optionally data_preview, source_info and field_ids.
Rows are a preview. data_preview holds at most the first few rows;
a renderer that needs the full set still reads panel_data or runs the
live source. Field-level metadata (field_input / field_trigger /
field_emit) is not part of the list output and comes back empty.
Source§impl Panel
impl Panel
pub fn title(&self) -> String
pub fn description(&self) -> Option<String>
Sourcepub fn columns(&self) -> Vec<String>
pub fn columns(&self) -> Vec<String>
Column headers for table panels — the columns prop, a list.
Examples found in repository?
18fn main() {
19 let path = std::env::args()
20 .nth(1)
21 .expect("usage: parse_fixture <facts.json>");
22 let raw = std::fs::read_to_string(&path).expect("read fixture");
23 let doc: BTreeMap<String, Value> =
24 serde_json::from_str(&raw).expect("fixture is a JSON object");
25
26 let rows = |key: &str| -> Vec<Value> {
27 doc.get(key)
28 .and_then(Value::as_array)
29 .cloned()
30 .unwrap_or_default()
31 };
32
33 let facts = PanelFacts {
34 panels: rows("panels"),
35 props: rows("props"),
36 data: rows("data"),
37 sources: rows("sources"),
38 field_inputs: rows("field_inputs"),
39 field_triggers: rows("field_triggers"),
40 field_emits: rows("field_emits"),
41 };
42
43 println!(
44 "input rows: panels={} props={} data={} sources={} fields(in/trig/emit)={}/{}/{}",
45 facts.panels.len(),
46 facts.props.len(),
47 facts.data.len(),
48 facts.sources.len(),
49 facts.field_inputs.len(),
50 facts.field_triggers.len(),
51 facts.field_emits.len()
52 );
53
54 let panels = Panel::all_from_facts(&facts);
55 println!("parsed panels: {}\n", panels.len());
56
57 let mut unknown = 0;
58 for p in &panels {
59 let kind = p.kind.as_str().to_string();
60 if matches!(p.kind, datagrout_panels::PanelKind::Unknown(_)) {
61 unknown += 1;
62 }
63 println!(
64 "{:<24} {:<11} ns={:<20} props={:<2} rows={:<3} cols={:<2} source={} fields={} children={} published={}",
65 p.id,
66 kind,
67 p.namespace,
68 p.props.len(),
69 p.rows.len(),
70 p.rows.first().map(Vec::len).unwrap_or(0),
71 p.source.is_some(),
72 p.fields.len(),
73 p.children.len(),
74 p.published
75 );
76 for c in &p.children {
77 println!(
78 " └ {:<20} {:<11} rows={:<3} columns={:?}",
79 c.id,
80 c.kind.as_str(),
81 c.rows.len(),
82 c.columns()
83 );
84 }
85 }
86
87 // Anything a renderer would fall back on is worth calling out by name.
88 println!("\nunknown kinds: {unknown}");
89 let titled = panels
90 .iter()
91 .filter(|p| p.props.contains_key("title"))
92 .count();
93 println!("panels with a title prop: {titled}/{}", panels.len());
94}