quokka_admin/service/page_loader/
admin_create_form_page_loader.rs1use std::marker::PhantomData;
2
3use axum::http::Method;
4use quokka::{
5 handler::html::TemplateDataLoader,
6 state::{FromState, ProvideState},
7};
8
9use crate::{
10 data::Severity,
11 service::{AdminCreateForm, FormBuilder, FormProperties},
12};
13
14use super::{AdminPageData, AdminPageLoader};
15
16pub struct AdminCreateFormPageLoader<S, F> {
17 form_builder: FormBuilder<S>,
18 admin_page_loader: AdminPageLoader,
19 state: S,
20 _form: PhantomData<F>,
21}
22
23#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
24pub struct AdminFormCreatePageData {
25 form: FormProperties,
26}
27
28impl<S, F> TemplateDataLoader<S> for AdminCreateFormPageLoader<S, F>
29where
30 S: ProvideState<AdminPageLoader>,
31 S: Send + Sync + Clone + 'static,
32 F: Send + Sync + 'static,
33 F: AdminCreateForm<S> + 'static,
34{
35 type Args = (Method, <AdminPageLoader as TemplateDataLoader<S>>::Args);
36
37 type Data = AdminPageData<AdminFormCreatePageData>;
38
39 #[tracing::instrument(
40 skip_all,
41 target = "quokka_admin::service::page_loader::admin_create_form_page_loader::AdminCreateFormPageLoader"
42 )]
43 async fn load_data(&self, (method, base_params): Self::Args) -> quokka::Result<Self::Data> {
44 let mut base = <AdminPageLoader as TemplateDataLoader<S>>::load_data(
45 &self.admin_page_loader,
46 base_params,
47 )
48 .await?;
49
50 if method == Method::POST {
51 tracing::debug!(
52 create_form = std::any::type_name::<F>(),
53 "Received POST method in AdminCreateFormPageLoader::load_data, this indicates a success for us",
54 );
55
56 base = base.message(
57 Severity::Success.message("Entity Created", "Entity created successfully"),
58 );
59 }
60
61 let form = self
62 .form_builder
63 .construct_form_data(F::get_form())
64 .await
65 .inspect_err(|error| {
66 tracing::error!(
67 ?error,
68 create_form = std::any::type_name::<F>(),
69 "Unable to construct form data in create form",
70 );
71 })?;
72
73 Ok(base.page(AdminFormCreatePageData { form }))
74 }
75
76 #[tracing::instrument(
77 skip_all,
78 target = "quokka_admin::service::page_loader::admin_create_form_page_loader::AdminCreateFormPageLoader"
79 )]
80 async fn render_error(&self, error: quokka::Error) -> impl axum::response::IntoResponse {
81 <AdminPageLoader as TemplateDataLoader<S>>::render_error(&self.admin_page_loader, error)
82 .await
83 }
84}
85
86impl<S, F> FromState<S> for AdminCreateFormPageLoader<S, F>
87where
88 S: Clone,
89 S: ProvideState<FormBuilder<S>>,
90 S: ProvideState<AdminPageLoader>,
91{
92 fn from_state(state: &S) -> Self {
93 Self {
94 form_builder: state.provide(),
95 admin_page_loader: state.provide(),
96 state: state.clone(),
97 _form: PhantomData,
98 }
99 }
100}
101
102impl<S: Clone, F> Clone for AdminCreateFormPageLoader<S, F> {
103 fn clone(&self) -> Self {
104 Self {
105 form_builder: self.form_builder.clone(),
106 admin_page_loader: self.admin_page_loader.clone(),
107 state: self.state.clone(),
108 _form: PhantomData,
109 }
110 }
111}