shield_dioxus/routes/
action.rs

1use dioxus::prelude::*;
2use serde_json::Value;
3use shield::{ActionForms, ResponseType};
4
5use crate::ErasedDioxusStyle;
6
7#[derive(Clone, PartialEq, Props)]
8pub struct ActionProps {
9    #[props(default = "index".to_owned())]
10    action_id: String,
11}
12
13#[component]
14pub fn Action(props: ActionProps) -> Element {
15    let response = use_server_future({
16        let action_id = props.action_id.clone();
17
18        move || forms(action_id.clone())
19    })?;
20    let style = use_context::<ErasedDioxusStyle>();
21
22    let response_read = response.read();
23    let response = response_read.as_ref().unwrap();
24
25    match response {
26        Ok(forms) => style.render(forms),
27        Err(err) => rsx! { "{err}" },
28    }
29}
30
31// TODO: Figure out a way to access `FromContext` and `extract` without `dioxus/server` feature.
32
33#[cfg_attr(not(feature = "server"), allow(unused_variables))]
34#[server]
35async fn forms(action_id: String) -> Result<ActionForms, ServerFnError> {
36    #[cfg(feature = "server")]
37    {
38        use dioxus::prelude::{FromContext, extract};
39
40        use crate::integration::DioxusIntegrationDyn;
41
42        let FromContext(integration): FromContext<DioxusIntegrationDyn> = extract().await?;
43        let shield = integration.extract_shield().await;
44        let session = integration.extract_session().await;
45
46        let forms = shield.action_forms(&action_id, session).await?;
47
48        Ok(forms)
49    }
50
51    #[cfg(not(feature = "server"))]
52    unreachable!()
53}
54
55#[cfg_attr(not(feature = "server"), allow(unused_variables))]
56#[server]
57pub async fn call(
58    action_id: String,
59    method_id: String,
60    provider_id: Option<String>,
61    // TODO: Would be nice if this argument could fill up with all unknown keys instead of setting name to `data[...]`.
62    data: Value,
63) -> Result<ResponseType, ServerFnError> {
64    #[cfg(feature = "server")]
65    {
66        use dioxus::prelude::{FromContext, extract};
67        use serde_json::Value;
68        use shield::Request;
69
70        use crate::integration::DioxusIntegrationDyn;
71
72        tracing::info!("call data {data:#?}");
73
74        let FromContext(integration): FromContext<DioxusIntegrationDyn> = extract().await?;
75        let shield = integration.extract_shield().await;
76        let session = integration.extract_session().await;
77
78        let response = shield
79            .call(
80                &action_id,
81                &method_id,
82                provider_id.as_deref(),
83                session,
84                Request {
85                    query: Value::Null,
86                    form_data: data,
87                },
88            )
89            .await?;
90
91        Ok(response)
92    }
93
94    #[cfg(not(feature = "server"))]
95    unreachable!()
96}