futuresdr_frontend/ctrl_port/
flowgraph.rs1use reqwasm::http::Request;
2use wasm_bindgen::prelude::*;
3use yew::prelude::*;
4
5use futuresdr_pmt::FlowgraphDescription;
6
7use crate::ctrl_port::mermaid::Mermaid;
8
9#[wasm_bindgen]
10pub fn add_flowgraph(id: String, url: String) {
11 let document = gloo_utils::document();
12 let div = document.query_selector(&id).unwrap().unwrap();
13 yew::start_app_with_props_in_element::<Flowgraph>(div, Props { url });
14}
15
16pub enum Msg {
17 Error,
18 Reply(FlowgraphDescription),
19}
20
21#[derive(Clone, Properties, Default, PartialEq, Eq)]
22pub struct Props {
23 pub url: String,
24}
25
26pub struct Flowgraph {
27 code: String,
28}
29
30impl Flowgraph {
31 fn endpoint(props: &Props) -> String {
32 format!("{}/api/fg/", props.url)
33 }
34
35 fn callback(ctx: &Context<Self>) {
36 let endpoint = Self::endpoint(ctx.props());
37 gloo_console::log!("flowgraph: sending request");
38
39 ctx.link().send_future(async move {
40 let response = Request::get(&endpoint).send().await;
41
42 if let Ok(response) = response {
43 if let Ok(fg) = response.json().await {
44 return Msg::Reply(fg);
45 }
46 }
47
48 Msg::Error
49 });
50 }
51
52 fn flowgraph_to_mermaid(fg: FlowgraphDescription) -> String {
53 let mut g = String::from("graph LR;\n");
54
55 for b in fg.blocks.iter() {
56 g.push_str(&format!(
57 "N{}[{}<br/><b>name:</b>{}<br/><b>is blocking</b>:{}];\n",
58 b.id, b.type_name, b.instance_name, b.blocking
59 ));
60 }
61 for e in fg.stream_edges {
62 g.push_str(&format!("N{}-->N{};\n", e.0, e.2));
63 }
64 for e in fg.message_edges {
65 g.push_str(&format!("N{}-.->N{};\n", e.0, e.2));
66 }
67 g
68 }
69}
70
71impl Component for Flowgraph {
72 type Message = Msg;
73 type Properties = Props;
74
75 fn create(_ctx: &Context<Self>) -> Self {
76 Self {
77 code: "flowchart LR".to_string(),
78 }
79 }
80
81 fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) {
82 if first_render {
83 Self::callback(ctx);
84 }
85 }
86
87 fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
88 match msg {
89 Msg::Error => {
90 self.code = r#"flowchart LR
91 id1(Error)
92 style id1 color:#000,fill:#f00,stroke:#000,stroke-width:4px
93 "#
94 .to_string();
95 }
96 Msg::Reply(fg) => {
97 self.code = Self::flowgraph_to_mermaid(fg);
98 }
99 };
100 true
101 }
102
103 fn view(&self, _ctx: &Context<Self>) -> Html {
104 html! {
105 <Mermaid code={self.code.clone()} />
106 }
107 }
108}