From a7188e81537bbef536138edf5d0bccfbc27043b8 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Thu, 28 Sep 2023 21:42:12 +0200 Subject: [PATCH] Added DataForm component for easier edit dialogs. --- src/backend/company.rs | 8 ++ src/backend/user.rs | 29 +++++++ src/components/data_form.rs | 52 ++++++++++++ src/components/mod.rs | 1 + src/pages/change_pwd.rs | 38 ++------- src/pages/company_edit.rs | 156 +++++++++++++++--------------------- src/pages/company_info.rs | 4 +- src/pages/mod.rs | 2 + src/pages/profile_edit.rs | 110 ++++++++++--------------- src/validator.rs | 2 +- 10 files changed, 204 insertions(+), 198 deletions(-) create mode 100644 src/components/data_form.rs diff --git a/src/backend/company.rs b/src/backend/company.rs index 08d4b8d..5d7de09 100644 --- a/src/backend/company.rs +++ b/src/backend/company.rs @@ -1,5 +1,7 @@ use leptos::*; +use validator::Validate; use crate::backend::data::{ApiResponse, Company}; +use crate::components::data_form::ForValidation; #[server(GetCompany, "/api", "Url", "get_company")] pub async fn get_company() -> Result, ServerFnError> { @@ -44,3 +46,9 @@ pub async fn update_company(company: Company) -> Result, ServerF Ok(ApiResponse::Data(())) } + +impl ForValidation for UpdateCompany { + fn entity(&self) -> &dyn Validate { + &self.company + } +} \ No newline at end of file diff --git a/src/backend/user.rs b/src/backend/user.rs index 326fddd..a5efef3 100644 --- a/src/backend/user.rs +++ b/src/backend/user.rs @@ -1,6 +1,8 @@ use cfg_if::cfg_if; use leptos::*; +use validator::Validate; use crate::backend::data::{ApiResponse, PwdChange, User, UserProfile}; +use crate::components::data_form::ForValidation; cfg_if! { if #[cfg(feature = "ssr")] { use sqlx::{query_as, Error, PgPool, query}; @@ -110,6 +112,21 @@ pub async fn get_user() -> Result, ServerFnError> { Ok(logged_in_user().await) } +#[server(GetUsers, "/api", "Url", "get_users")] +pub async fn get_users() -> Result>, ServerFnError> { + use crate::backend::AppData; + use actix_web::web::Data; + use leptos_actix::extract; + use crate::perm_check; + + perm_check!(is_admin); + + let pool = extract(|data: Data| async move { data.db_pool().clone() }).await?; + let users = sqlx::query_as::<_, User>(r#"SELECT * FROM "user""#).fetch_all(&pool).await?; + + Ok(ApiResponse::Data(users)) +} + #[server] pub async fn update_profile(user: UserProfile) -> Result, ServerFnError> { use crate::backend::AppData; @@ -136,6 +153,12 @@ pub async fn update_profile(user: UserProfile) -> Result, Server Ok(ApiResponse::Data(())) } +impl ForValidation for UpdateProfile { + fn entity(&self) -> &dyn Validate { + &self.user + } +} + #[server] pub async fn change_pwd(new_pw: PwdChange) -> Result, ServerFnError> { use crate::backend::AppData; @@ -162,4 +185,10 @@ pub async fn change_pwd(new_pw: PwdChange) -> Result, ServerFnEr .await?; Ok(ApiResponse::Data(())) +} + +impl ForValidation for ChangePwd { + fn entity(&self) -> &dyn Validate { + &self.new_pw + } } \ No newline at end of file diff --git a/src/components/data_form.rs b/src/components/data_form.rs new file mode 100644 index 0000000..a6f3966 --- /dev/null +++ b/src/components/data_form.rs @@ -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 + Clone + ForValidation>( + opener: DialogOpener, + action: Action, ServerFnError>>, + title: &'static str, + children: Children +) -> impl IntoView { + let upd_val = action.value(); + let validator = Validator::new(); + + view! { + + + + + + {children()} + + + + + + + + } +} diff --git a/src/components/mod.rs b/src/components/mod.rs index 7f3f6f3..199b0db 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -4,4 +4,5 @@ pub mod validation_err; pub mod header; pub mod admin_portal; pub mod user_menu; +pub mod data_form; diff --git a/src/pages/change_pwd.rs b/src/pages/change_pwd.rs index fef25d1..7ce6926 100644 --- a/src/pages/change_pwd.rs +++ b/src/pages/change_pwd.rs @@ -1,40 +1,23 @@ use leptos::*; -use leptos_router::*; use crate::backend::data::{ApiResponse, User}; use crate::backend::user::ChangePwd; -use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog, ModalFooter}; -use crate::components::server_err::ServerErr; -use crate::components::validation_err::ValidationErr; -use crate::locales::trl; -use crate::validator::Validator; +use crate::components::data_form::DataForm; +use crate::components::modal_box::DialogOpener; #[component] pub fn change_password(user: ReadSignal, opener: DialogOpener) -> impl IntoView { let change_pwd = create_server_action::(); - let upd_val = change_pwd.value(); - let validator = Validator::new(); let empty = create_rw_signal("".to_string()); view! { {move || { - if let Some(res) = upd_val.get() { + if let Some(res) = change_pwd.value().get() { if let Ok(r) = res { if let ApiResponse::Data(_) = r { empty.update(|e| *e = "".to_string())} } } view! { - - - - - +
@@ -72,18 +55,7 @@ pub fn change_password(user: ReadSignal, opener: DialogOpener) -> impl Int />
-
- - - - -
-
+ } }} } diff --git a/src/pages/company_edit.rs b/src/pages/company_edit.rs index f68ee9f..f2da0ea 100644 --- a/src/pages/company_edit.rs +++ b/src/pages/company_edit.rs @@ -1,14 +1,8 @@ use crate::backend::data::Company; use crate::backend::company::UpdateCompany; -use crate::components::modal_box::{ - DialogOpener, ModalBody, ModalDialog, ModalFooter, -}; -use crate::components::server_err::ServerErr; -use crate::locales::trl; -use crate::validator::Validator; +use crate::components::modal_box::DialogOpener; use leptos::*; -use leptos_router::*; -use crate::components::validation_err::ValidationErr; +use crate::components::data_form::DataForm; #[component] pub fn CompanyEdit( @@ -16,95 +10,71 @@ pub fn CompanyEdit( opener: DialogOpener, ) -> impl IntoView { let update_company = create_server_action::(); - let upd_val = update_company.value(); - let validator = Validator::new(); view! { - - - - - - -
-
- - -
+ + +
+
+ +
-
-
- - -
-
- - -
+
+
+
+ +
-
-
- - -
-
- - -
+
+ +
- - - - - - - +
+
+
+ + +
+
+ + +
+
+ } } diff --git a/src/pages/company_info.rs b/src/pages/company_info.rs index de41dde..277739c 100644 --- a/src/pages/company_info.rs +++ b/src/pages/company_info.rs @@ -13,7 +13,7 @@ pub fn CompanyInfo() -> impl IntoView { view! { -
+
" "{trl("Company info")}

@@ -41,7 +41,7 @@ pub fn CompanyInfo() -> impl IntoView {

- +
} diff --git a/src/pages/mod.rs b/src/pages/mod.rs index f919cd1..44fa8d5 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -6,3 +6,5 @@ pub mod login; pub mod public; pub mod profile_edit; pub mod change_pwd; +pub mod users; +pub mod user_edit; diff --git a/src/pages/profile_edit.rs b/src/pages/profile_edit.rs index ffb7413..633e1cb 100644 --- a/src/pages/profile_edit.rs +++ b/src/pages/profile_edit.rs @@ -1,83 +1,55 @@ use leptos::*; -use leptos_router::*; use crate::backend::data::User; use crate::backend::user::UpdateProfile; -use crate::components::modal_box::{DialogOpener, ModalBody, ModalDialog, ModalFooter}; -use crate::components::server_err::ServerErr; -use crate::components::validation_err::ValidationErr; -use crate::locales::trl; -use crate::validator::Validator; +use crate::components::data_form::DataForm; +use crate::components::modal_box::DialogOpener; #[component] pub fn ProfileEdit(user: ReadSignal, opener: DialogOpener) -> impl IntoView { let update_user = create_server_action::(); - let upd_val = update_user.value(); - let validator = Validator::new(); view! { - - - - - - -
-
- - -
+ + +
+
+ +
-
-
- - -
+
+
+
+ +
-
-
- - -
+
+
+
+ +
- - - - - - - +
+ } } \ No newline at end of file diff --git a/src/validator.rs b/src/validator.rs index 9ea0e90..deef3c5 100644 --- a/src/validator.rs +++ b/src/validator.rs @@ -26,7 +26,7 @@ impl Validator { } } - pub fn check(&self, entity: &impl Validate, ev: &web_sys::Event) { + pub fn check(&self, entity: &(impl Validate + ?Sized), ev: &web_sys::Event) { if let Err(val_err) = entity.validate() { ev.prevent_default(); //self.set_message.update(|m| *m = Some(val_err.to_string().clone()));