From 15e60e632560b5a2d8950dcd13734f7ca587a2dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabor=20K=C3=B6rber?= Date: Fri, 26 Jul 2024 12:56:23 +0200 Subject: [PATCH] improving depot code for user and static repo examples --- rear/src/depot/depot_cycle.md | 12 +++++++++ rear/src/depot/repository.rs | 21 ++++++++++++---- rear/src/depot/widgets.rs | 6 ++--- rear_auth/src/user_admin_repository.rs | 25 +++++++++++-------- src/admin_examples/static_repository.rs | 12 ++++++++- templates/depot/items/item_change.jinja | 4 +-- templates/depot/items/item_change_form.jinja | 26 ++++++++++---------- templates/depot/items/item_create.jinja | 4 +-- templates/depot/items/item_detail.jinja | 6 ++--- templates/depot/items/item_list.jinja | 2 +- 10 files changed, 78 insertions(+), 40 deletions(-) create mode 100644 rear/src/depot/depot_cycle.md diff --git a/rear/src/depot/depot_cycle.md b/rear/src/depot/depot_cycle.md new file mode 100644 index 0000000..2abf4e2 --- /dev/null +++ b/rear/src/depot/depot_cycle.md @@ -0,0 +1,12 @@ + + +UPDATE: + - The Item is edited successfully: Success Message + - The Item could not be saved, it needs adjustment: Form Errors, Warning Message? + - The Item could not be saved, there was an Error of some sort: Error Message + +Widget -builds-> Field + + +Validation: https://github.com/tokio-rs/axum/blob/main/examples/validator/src/main.rs +AvoRED PRoject seems similar: https://github.com/avored/avored-rust-cms diff --git a/rear/src/depot/repository.rs b/rear/src/depot/repository.rs index ed7657d..cb62de4 100644 --- a/rear/src/depot/repository.rs +++ b/rear/src/depot/repository.rs @@ -99,10 +99,21 @@ impl Into> for RepositoryResponse { #[derive(Error, Debug)] pub enum RepositoryError { + // used internally. + #[error("key not found in downcast?")] + WrapperDowncastError, + + // to be used by repositories: + #[error("repository item not found")] + ItemNotFound, + #[error("database error: {0}")] + DatabaseError(#[source] Box), + #[error("external error: {0}")] + ExternalError(#[source] Box), + + // to be removed or refactored: #[error("an unknown occurred: {0}")] UnknownError(String), - #[error("key not found in downcast?")] - KeyNotFound, } pub type RepositoryResult = Result; @@ -332,7 +343,7 @@ impl DynDepotRepository for DepotRepositoryWrapper { if let Some(key) = id.as_any().downcast_ref::() { self.inner.get(context, key).await } else { - Err(RepositoryError::KeyNotFound) + Err(RepositoryError::WrapperDowncastError) } } @@ -349,7 +360,7 @@ impl DynDepotRepository for DepotRepositoryWrapper { if let Some(key) = id.as_any().downcast_ref::() { self.inner.update(context, key, data).await } else { - Err(RepositoryError::KeyNotFound) + Err(RepositoryError::WrapperDowncastError) } } @@ -362,7 +373,7 @@ impl DynDepotRepository for DepotRepositoryWrapper { if let Some(key) = id.as_any().downcast_ref::() { self.inner.replace(context, key, data).await } else { - Err(RepositoryError::KeyNotFound) + Err(RepositoryError::WrapperDowncastError) } } diff --git a/rear/src/depot/widgets.rs b/rear/src/depot/widgets.rs index be52349..88f26fb 100644 --- a/rear/src/depot/widgets.rs +++ b/rear/src/depot/widgets.rs @@ -36,15 +36,15 @@ impl Widget { } pub fn default() -> Self { - Self::widget("/admin/widgets/input_text.jinja") + Self::widget("/depot/widgets/input_text.jinja") } pub fn textarea() -> Self { - Self::widget("/admin/widgets/input_textarea.jinja") + Self::widget("/depot/widgets/input_textarea.jinja") } pub fn checkbox() -> Self { - Self::widget("/admin/widgets/checkbox_toggle.jinja") + Self::widget("/depot/widgets/checkbox_toggle.jinja") } pub fn required(mut self) -> Self { diff --git a/rear_auth/src/user_admin_repository.rs b/rear_auth/src/user_admin_repository.rs index eb5d514..bf427f7 100644 --- a/rear_auth/src/user_admin_repository.rs +++ b/rear_auth/src/user_admin_repository.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use log::debug; +use log::{debug, warn}; use rear::depot::prelude::*; use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, ModelTrait, Set}; use serde_json::Value; @@ -136,8 +136,8 @@ impl DepotRepository for UserRepository { let user: Option = entity::User::find_by_id(id) .one(&self.connection) .await - .unwrap(); - let mut user: entity::user::ActiveModel = user.unwrap().into(); + .map_err(|e| RepositoryError::DatabaseError(Box::new(e)))?; + let mut user: entity::user::ActiveModel = user.ok_or(RepositoryError::ItemNotFound)?.into(); // should we really allow username change? if let Some(value) = data.get("username") { @@ -170,14 +170,18 @@ impl DepotRepository for UserRepository { } // update - if let Ok(user) = user.update(&self.connection).await { - let id = user.id.to_string(); - return Ok(RepositoryResponse::ItemOnly( - model.build_item(&*id, serde_json::to_value(&user).unwrap()), - )); + match user.update(&self.connection).await { + Ok(user) => { + let id = user.id.to_string(); + return Ok(RepositoryResponse::ItemOnly( + model.build_item(&*id, serde_json::to_value(&user).unwrap()), + )); + } + Err(err) => { + warn!("Error updating user"); + return Err(RepositoryError::DatabaseError(Box::new(err))); + } } - - Ok(RepositoryResponse::NoItem) } async fn replace( @@ -197,6 +201,7 @@ impl DepotRepository for UserRepository { .unwrap(); if let Some(user) = user { let delete_result = user.delete(&self.connection).await.unwrap(); + // .ok_or(RepositoryError::DatabaseError(Box::new(err)))?; debug!("deleted rows: {}", delete_result.rows_affected); } diff --git a/src/admin_examples/static_repository.rs b/src/admin_examples/static_repository.rs index 8526b83..ca6d68b 100644 --- a/src/admin_examples/static_repository.rs +++ b/src/admin_examples/static_repository.rs @@ -72,7 +72,16 @@ impl DepotRepository for MyStaticRepository { .content .clone() .into_iter() - .map(|item| model.build_item(&*item.get("id").unwrap().to_string(), item)) + .filter_map(|item| match item.get("id") { + Some(id_value) => { + let id_str = id_value.to_string(); + Some(model.build_item(&id_str, item)) + } + None => { + eprintln!("Skipping item due to missing 'id'"); + None + } + }) .collect(), } } @@ -117,6 +126,7 @@ impl DepotRepository for MyStaticRepository { if let Some(index) = item_index { let item = &mut self.content[index]; *item = data.clone(); + item["id"] = (*id).into(); if let Some(item_id) = item.get("id") { return Ok(RepositoryResponse::ItemOnly( diff --git a/templates/depot/items/item_change.jinja b/templates/depot/items/item_change.jinja index 2563510..f1dc33b 100644 --- a/templates/depot/items/item_change.jinja +++ b/templates/depot/items/item_change.jinja @@ -1,4 +1,4 @@ -{% extends base|none("admin/base.jinja") %} +{% extends base|none("depot/base.jinja") %} {% block content %}
@@ -8,6 +8,6 @@

Update {{item_model.name}} in {{item_info.name}}

{% set fields = item_info.fields %} {% set form = { 'action': item.change_url, 'method': 'PATCH' } %} - {% include "/admin/items/item_change_form.jinja" %} + {% include "/depot/items/item_change_form.jinja" %}
{% endblock content %} \ No newline at end of file diff --git a/templates/depot/items/item_change_form.jinja b/templates/depot/items/item_change_form.jinja index 8bfe6f5..2e95485 100644 --- a/templates/depot/items/item_change_form.jinja +++ b/templates/depot/items/item_change_form.jinja @@ -2,27 +2,27 @@
- {% from "/admin/items/items.jinja" import field_widget %} + {% from "/depot/items/items.jinja" import field_widget %} {% for field_name, field_defs in fields %} - {% if item %} - {% set field_value = item.fields[field_name]|none("") %} - {% else %} - {% set field_value = "" %} - {% endif %} -
+ {% if item %} + {% set field_value = item.fields[field_name]|none("") %} + {% else %} + {% set field_value = "" %} + {% endif %} +
{{ field_widget(field_name, field_defs, field_value) }} -
+
{% endfor %}
diff --git a/templates/depot/items/item_create.jinja b/templates/depot/items/item_create.jinja index 0e10d1e..e427500 100644 --- a/templates/depot/items/item_create.jinja +++ b/templates/depot/items/item_create.jinja @@ -1,4 +1,4 @@ -{% extends base|none("admin/base.jinja") %} +{% extends base|none("depot/base.jinja") %} {% block content %}
@@ -12,6 +12,6 @@ {% set fields = item_info.fields %} {% set form = { 'action': item_model.add_url } %} - {% include "/admin/items/item_change_form.jinja" %} + {% include "/depot/items/item_change_form.jinja" %}
{% endblock content %} \ No newline at end of file diff --git a/templates/depot/items/item_detail.jinja b/templates/depot/items/item_detail.jinja index bd273cd..cf80b9f 100644 --- a/templates/depot/items/item_detail.jinja +++ b/templates/depot/items/item_detail.jinja @@ -1,11 +1,11 @@ -{% extends base|none("admin/base.jinja") %} +{% extends base|none("depot/base.jinja") %} {% block content %} {% if item %} - {{item.fields}} +{{item.fields}} {% else %} - No Item found. +No Item found. {% endif %} {% endblock content %} \ No newline at end of file diff --git a/templates/depot/items/item_list.jinja b/templates/depot/items/item_list.jinja index b7ccb20..22fe2b5 100644 --- a/templates/depot/items/item_list.jinja +++ b/templates/depot/items/item_list.jinja @@ -1,4 +1,4 @@ -{% extends base|none("admin/base.jinja") %} +{% extends base|none("depot/base.jinja") %} {% block content %}