improving depot code for user and static repo examples
This commit is contained in:
parent
843e432ec4
commit
15e60e6325
12
rear/src/depot/depot_cycle.md
Normal file
12
rear/src/depot/depot_cycle.md
Normal file
@ -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
|
@ -99,10 +99,21 @@ impl Into<Option<RepositoryItem>> 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<dyn std::error::Error + Send + Sync>),
|
||||
#[error("external error: {0}")]
|
||||
ExternalError(#[source] Box<dyn std::error::Error + Send + Sync>),
|
||||
|
||||
// to be removed or refactored:
|
||||
#[error("an unknown occurred: {0}")]
|
||||
UnknownError(String),
|
||||
#[error("key not found in downcast?")]
|
||||
KeyNotFound,
|
||||
}
|
||||
|
||||
pub type RepositoryResult = Result<RepositoryResponse, RepositoryError>;
|
||||
@ -332,7 +343,7 @@ impl<T: DepotRepository> DynDepotRepository for DepotRepositoryWrapper<T> {
|
||||
if let Some(key) = id.as_any().downcast_ref::<T::Key>() {
|
||||
self.inner.get(context, key).await
|
||||
} else {
|
||||
Err(RepositoryError::KeyNotFound)
|
||||
Err(RepositoryError::WrapperDowncastError)
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,7 +360,7 @@ impl<T: DepotRepository> DynDepotRepository for DepotRepositoryWrapper<T> {
|
||||
if let Some(key) = id.as_any().downcast_ref::<T::Key>() {
|
||||
self.inner.update(context, key, data).await
|
||||
} else {
|
||||
Err(RepositoryError::KeyNotFound)
|
||||
Err(RepositoryError::WrapperDowncastError)
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,7 +373,7 @@ impl<T: DepotRepository> DynDepotRepository for DepotRepositoryWrapper<T> {
|
||||
if let Some(key) = id.as_any().downcast_ref::<T::Key>() {
|
||||
self.inner.replace(context, key, data).await
|
||||
} else {
|
||||
Err(RepositoryError::KeyNotFound)
|
||||
Err(RepositoryError::WrapperDowncastError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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::Model> = 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 {
|
||||
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()),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(RepositoryResponse::NoItem)
|
||||
Err(err) => {
|
||||
warn!("Error updating user");
|
||||
return Err(RepositoryError::DatabaseError(Box::new(err)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends base|none("admin/base.jinja") %}
|
||||
{% extends base|none("depot/base.jinja") %}
|
||||
|
||||
{% block content %}
|
||||
<div id="message-box-area" class="ui message" _="init wait 3s then transition opacity to 0 then remove me">
|
||||
@ -8,6 +8,6 @@
|
||||
<h1>Update {{item_model.name}} in {{item_info.name}}</h1>
|
||||
{% 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" %}
|
||||
</div>
|
||||
{% endblock content %}
|
@ -10,10 +10,10 @@
|
||||
{% elif form.method|upper == 'PUT' %}
|
||||
hx-put="{{ form.action }}"
|
||||
{% else %}
|
||||
unknown-form-method={{form.method}}
|
||||
unknown-form-method="{{ form.method }}"
|
||||
{% endif %}>
|
||||
|
||||
{% 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("") %}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends base|none("admin/base.jinja") %}
|
||||
{% extends base|none("depot/base.jinja") %}
|
||||
|
||||
{% block content %}
|
||||
<div class="ui container">
|
||||
@ -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" %}
|
||||
</div>
|
||||
{% endblock content %}
|
@ -1,4 +1,4 @@
|
||||
{% extends base|none("admin/base.jinja") %}
|
||||
{% extends base|none("depot/base.jinja") %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends base|none("admin/base.jinja") %}
|
||||
{% extends base|none("depot/base.jinja") %}
|
||||
|
||||
{% block content %}
|
||||
<div class="ui container">
|
||||
|
Loading…
Reference in New Issue
Block a user