Skip to main content

shield_dioxus/routes/
action.rs

1use dioxus::prelude::*;
2use serde_json::Value;
3use shield::{ActionForms, ResponseType};
4
5use crate::{query::Query, style::ErasedDioxusStyle};
6
7#[derive(Clone, PartialEq, Props)]
8pub struct ActionProps {
9    #[props(default = "index".to_owned())]
10    action_id: String,
11    query: String,
12}
13
14#[component]
15pub fn Action(props: ActionProps) -> Element {
16    let response = use_server_future({
17        let action_id = props.action_id.clone();
18
19        move || forms(action_id.clone())
20    })?;
21    let style = use_context::<ErasedDioxusStyle>();
22
23    let response_read = response.read();
24    let response = response_read.as_ref().unwrap();
25
26    use_context_provider(|| Query::parse(&props.query));
27
28    match response {
29        Ok(forms) => style.render(forms),
30        Err(err) => rsx! { "{err}" },
31    }
32}
33
34#[get("/api/auth/forms", parts: dioxus::fullstack::http::request::Parts)]
35async fn forms(action_id: String) -> Result<ActionForms> {
36    use anyhow::anyhow;
37
38    use crate::integration::DioxusIntegrationDyn;
39
40    let integration = parts
41        .extensions
42        .get::<DioxusIntegrationDyn>()
43        .ok_or_else(|| anyhow!("Dioxus Shield integration should be extracted."))?;
44    let shield = integration.extract_shield(&parts.extensions)?;
45    let session = integration.extract_session(&parts.extensions)?;
46
47    let forms = shield
48        .action_forms(&action_id, session)
49        .await
50        .context("Failed to get Shield action forms.")?;
51
52    Ok(forms)
53}
54
55#[post("/api/auth/call", parts: dioxus::fullstack::http::request::Parts)]
56pub async fn call(
57    action_id: String,
58    // TODO: Would be nice if this argument could fill up with all unknown keys instead of setting name to `data[...]`.
59    data: Value,
60) -> Result<ResponseType> {
61    use anyhow::anyhow;
62    use serde_json::Value;
63    use shield::Request;
64
65    use crate::integration::DioxusIntegrationDyn;
66
67    tracing::info!("call data {data:#?}");
68
69    let integration = parts
70        .extensions
71        .get::<DioxusIntegrationDyn>()
72        .ok_or_else(|| anyhow!("Dioxus Shield integration should be extracted."))?;
73    let shield = integration.extract_shield(&parts.extensions)?;
74    let session = integration.extract_session(&parts.extensions)?;
75
76    let response = shield
77        .call(
78            &action_id,
79            session,
80            Request {
81                query: Value::Null,
82                form_data: data,
83            },
84        )
85        .await
86        .context("Failed to call Shield action.")?;
87
88    Ok(response)
89}
90
91#[post("/api/auth/call-method", parts: dioxus::fullstack::http::request::Parts)]
92pub async fn call_method(
93    action_id: String,
94    method_id: String,
95    provider_id: Option<String>,
96    // TODO: Would be nice if this argument could fill up with all unknown keys instead of setting name to `data[...]`.
97    data: Value,
98) -> Result<ResponseType> {
99    use anyhow::anyhow;
100    use serde_json::Value;
101    use shield::Request;
102
103    use crate::integration::DioxusIntegrationDyn;
104
105    tracing::info!("call method data {data:#?}");
106
107    let integration = parts
108        .extensions
109        .get::<DioxusIntegrationDyn>()
110        .ok_or_else(|| anyhow!("Dioxus Shield integration should be extracted."))?;
111    let shield = integration.extract_shield(&parts.extensions)?;
112    let session = integration.extract_session(&parts.extensions)?;
113
114    let response = shield
115        .call_method(
116            &action_id,
117            &method_id,
118            provider_id.as_deref(),
119            session,
120            Request {
121                query: Value::Null,
122                form_data: data,
123            },
124        )
125        .await
126        .context("Failed to call Shield method action.")?;
127
128    Ok(response)
129}