Added DataForm component for easier edit dialogs.
							parent
							
								
									0f8166913d
								
							
						
					
					
						commit
						a7188e8153
					
				@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					use crate::backend::data::ApiResponse;
 | 
				
			||||||
 | 
					use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog, ModalFooter};
 | 
				
			||||||
 | 
					use leptos::*;
 | 
				
			||||||
 | 
					use leptos_router::*;
 | 
				
			||||||
 | 
					use validator::Validate;
 | 
				
			||||||
 | 
					use crate::components::server_err::ServerErr;
 | 
				
			||||||
 | 
					use crate::components::validation_err::ValidationErr;
 | 
				
			||||||
 | 
					use crate::locales::trl;
 | 
				
			||||||
 | 
					use crate::validator::Validator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait ForValidation {
 | 
				
			||||||
 | 
					    fn entity(&self) -> &dyn Validate;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[component]
 | 
				
			||||||
 | 
					pub fn data_form<T: 'static + server_fn::ServerFn<()> + Clone + ForValidation>(
 | 
				
			||||||
 | 
					    opener: DialogOpener,
 | 
				
			||||||
 | 
					    action: Action<T, Result<ApiResponse<()>, ServerFnError>>,
 | 
				
			||||||
 | 
					    title: &'static str,
 | 
				
			||||||
 | 
					    children: Children
 | 
				
			||||||
 | 
					) -> impl IntoView {
 | 
				
			||||||
 | 
					    let upd_val = action.value();
 | 
				
			||||||
 | 
					    let validator = Validator::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    view! {
 | 
				
			||||||
 | 
					        <ActionForm
 | 
				
			||||||
 | 
					            on:submit=move |ev| {
 | 
				
			||||||
 | 
					                let act = T::from_event(&ev);
 | 
				
			||||||
 | 
					                if !act.is_err() {
 | 
				
			||||||
 | 
					                    validator.check(act.unwrap().entity(), &ev);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            action=action>
 | 
				
			||||||
 | 
					        <ModalDialog opener=opener title=title>
 | 
				
			||||||
 | 
					            <ModalBody>
 | 
				
			||||||
 | 
					                <ServerErr result={upd_val} opener=opener/>
 | 
				
			||||||
 | 
					                <ValidationErr validator=validator />
 | 
				
			||||||
 | 
					                {children()}
 | 
				
			||||||
 | 
					            </ModalBody>
 | 
				
			||||||
 | 
					            <ModalFooter>
 | 
				
			||||||
 | 
					                <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"
 | 
				
			||||||
 | 
					                    on:click=move |_| {validator.reset(); opener.hide()}>
 | 
				
			||||||
 | 
					                    {trl("Close")}
 | 
				
			||||||
 | 
					                </button>
 | 
				
			||||||
 | 
					                <button type="submit" class="btn btn-primary">
 | 
				
			||||||
 | 
					                    {trl("Save changes")}
 | 
				
			||||||
 | 
					                </button>
 | 
				
			||||||
 | 
					            </ModalFooter>
 | 
				
			||||||
 | 
					        </ModalDialog>
 | 
				
			||||||
 | 
					        </ActionForm>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,83 +1,55 @@
 | 
				
			|||||||
use leptos::*;
 | 
					use leptos::*;
 | 
				
			||||||
use leptos_router::*;
 | 
					 | 
				
			||||||
use crate::backend::data::User;
 | 
					use crate::backend::data::User;
 | 
				
			||||||
use crate::backend::user::UpdateProfile;
 | 
					use crate::backend::user::UpdateProfile;
 | 
				
			||||||
use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog, ModalFooter};
 | 
					use crate::components::data_form::DataForm;
 | 
				
			||||||
use crate::components::server_err::ServerErr;
 | 
					use crate::components::modal_box::DialogOpener;
 | 
				
			||||||
use crate::components::validation_err::ValidationErr;
 | 
					 | 
				
			||||||
use crate::locales::trl;
 | 
					 | 
				
			||||||
use crate::validator::Validator;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[component]
 | 
					#[component]
 | 
				
			||||||
pub fn ProfileEdit(user: ReadSignal<User>, opener: DialogOpener) -> impl IntoView {
 | 
					pub fn ProfileEdit(user: ReadSignal<User>, opener: DialogOpener) -> impl IntoView {
 | 
				
			||||||
    let update_user = create_server_action::<UpdateProfile>();
 | 
					    let update_user = create_server_action::<UpdateProfile>();
 | 
				
			||||||
    let upd_val = update_user.value();
 | 
					 | 
				
			||||||
    let validator = Validator::new();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    view! {
 | 
					    view! {
 | 
				
			||||||
        <ActionForm
 | 
					        <DataForm opener=opener action=update_user title="Edit profile">
 | 
				
			||||||
                on:submit=move |ev| {
 | 
					            <input type="hidden" value={move || user.get().login} name="user[login]"/>
 | 
				
			||||||
                    let act = UpdateProfile::from_event(&ev);
 | 
					            <div class="row">
 | 
				
			||||||
                    if !act.is_err() {
 | 
					                <div class="col mb-3">
 | 
				
			||||||
                        validator.check(&act.unwrap().user, &ev);
 | 
					                    <label  for="name" class="form-label">"Full name"</label>
 | 
				
			||||||
                    }
 | 
					                    <input
 | 
				
			||||||
                }
 | 
					                        type="text"
 | 
				
			||||||
                action=update_user>
 | 
					                        id="name"
 | 
				
			||||||
        <ModalDialog opener=opener title="Edit profile">
 | 
					                        class="form-control"
 | 
				
			||||||
            <ModalBody>
 | 
					                        placeholder="Enter Full name"
 | 
				
			||||||
                <ServerErr result={upd_val} opener=opener/>
 | 
					                        prop:value={move || user.get().full_name}
 | 
				
			||||||
                <ValidationErr validator=validator />
 | 
					                        name="user[full_name]"
 | 
				
			||||||
                <input type="hidden" value={move || user.get().login} name="user[login]"/>
 | 
					                    />
 | 
				
			||||||
                <div class="row">
 | 
					 | 
				
			||||||
                    <div class="col mb-3">
 | 
					 | 
				
			||||||
                        <label  for="name" class="form-label">"Full name"</label>
 | 
					 | 
				
			||||||
                        <input
 | 
					 | 
				
			||||||
                            type="text"
 | 
					 | 
				
			||||||
                            id="name"
 | 
					 | 
				
			||||||
                            class="form-control"
 | 
					 | 
				
			||||||
                            placeholder="Enter Full name"
 | 
					 | 
				
			||||||
                            prop:value={move || user.get().full_name}
 | 
					 | 
				
			||||||
                            name="user[full_name]"
 | 
					 | 
				
			||||||
                        />
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="row">
 | 
					            </div>
 | 
				
			||||||
                    <div class="col mb-3">
 | 
					            <div class="row">
 | 
				
			||||||
                        <label  for="email" class="form-label">"Email"</label>
 | 
					                <div class="col mb-3">
 | 
				
			||||||
                        <input
 | 
					                    <label  for="email" class="form-label">"Email"</label>
 | 
				
			||||||
                            type="text"
 | 
					                    <input
 | 
				
			||||||
                            id="name"
 | 
					                        type="text"
 | 
				
			||||||
                            class="form-control"
 | 
					                        id="name"
 | 
				
			||||||
                            placeholder="Enter email"
 | 
					                        class="form-control"
 | 
				
			||||||
                            prop:value={move || user.get().email.unwrap_or("".to_string())}
 | 
					                        placeholder="Enter email"
 | 
				
			||||||
                            name="user[email]"
 | 
					                        prop:value={move || user.get().email.unwrap_or("".to_string())}
 | 
				
			||||||
                        />
 | 
					                        name="user[email]"
 | 
				
			||||||
                    </div>
 | 
					                    />
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="row">
 | 
					            </div>
 | 
				
			||||||
                    <div class="col mb-3">
 | 
					            <div class="row">
 | 
				
			||||||
                        <input
 | 
					                <div class="col mb-3">
 | 
				
			||||||
                            class="form-check-input"
 | 
					                    <input
 | 
				
			||||||
                            type="checkbox"
 | 
					                        class="form-check-input"
 | 
				
			||||||
                            id="getMail"
 | 
					                        type="checkbox"
 | 
				
			||||||
                            prop:value={move || if user.get().get_emails {"true"} else {"false"}}
 | 
					                        id="getMail"
 | 
				
			||||||
                            prop:checked={move || user.get().get_emails}
 | 
					                        prop:value={move || if user.get().get_emails {"true"} else {"false"}}
 | 
				
			||||||
                            name="user[get_emails]"
 | 
					                        prop:checked={move || user.get().get_emails}
 | 
				
			||||||
                        />
 | 
					                        name="user[get_emails]"
 | 
				
			||||||
                        <label class="form-check-label" for="getMail">"Get emails"</label>
 | 
					                    />
 | 
				
			||||||
                    </div>
 | 
					                    <label class="form-check-label" for="getMail">"Get emails"</label>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </ModalBody>
 | 
					            </div>
 | 
				
			||||||
            <ModalFooter>
 | 
					        </DataForm>
 | 
				
			||||||
                <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"
 | 
					 | 
				
			||||||
                    on:click=move |_| {validator.reset(); opener.hide()}>
 | 
					 | 
				
			||||||
                    {trl("Close")}
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
                <button type="submit" class="btn btn-primary">
 | 
					 | 
				
			||||||
                    {trl("Save changes")}
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
            </ModalFooter>
 | 
					 | 
				
			||||||
        </ModalDialog>
 | 
					 | 
				
			||||||
        </ActionForm>
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
					Loading…
					
					
				
		Reference in New Issue