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)]
|
#[derive(Error, Debug)]
|
||||||
pub enum RepositoryError {
|
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}")]
|
#[error("an unknown occurred: {0}")]
|
||||||
UnknownError(String),
|
UnknownError(String),
|
||||||
#[error("key not found in downcast?")]
|
|
||||||
KeyNotFound,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RepositoryResult = Result<RepositoryResponse, RepositoryError>;
|
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>() {
|
if let Some(key) = id.as_any().downcast_ref::<T::Key>() {
|
||||||
self.inner.get(context, key).await
|
self.inner.get(context, key).await
|
||||||
} else {
|
} 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>() {
|
if let Some(key) = id.as_any().downcast_ref::<T::Key>() {
|
||||||
self.inner.update(context, key, data).await
|
self.inner.update(context, key, data).await
|
||||||
} else {
|
} 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>() {
|
if let Some(key) = id.as_any().downcast_ref::<T::Key>() {
|
||||||
self.inner.replace(context, key, data).await
|
self.inner.replace(context, key, data).await
|
||||||
} else {
|
} else {
|
||||||
Err(RepositoryError::KeyNotFound)
|
Err(RepositoryError::WrapperDowncastError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,15 +36,15 @@ impl Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn default() -> Self {
|
pub fn default() -> Self {
|
||||||
Self::widget("/admin/widgets/input_text.jinja")
|
Self::widget("/depot/widgets/input_text.jinja")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn textarea() -> Self {
|
pub fn textarea() -> Self {
|
||||||
Self::widget("/admin/widgets/input_textarea.jinja")
|
Self::widget("/depot/widgets/input_textarea.jinja")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn checkbox() -> Self {
|
pub fn checkbox() -> Self {
|
||||||
Self::widget("/admin/widgets/checkbox_toggle.jinja")
|
Self::widget("/depot/widgets/checkbox_toggle.jinja")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn required(mut self) -> Self {
|
pub fn required(mut self) -> Self {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::debug;
|
use log::{debug, warn};
|
||||||
use rear::depot::prelude::*;
|
use rear::depot::prelude::*;
|
||||||
use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, ModelTrait, Set};
|
use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, ModelTrait, Set};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@ -136,8 +136,8 @@ impl DepotRepository for UserRepository {
|
|||||||
let user: Option<entity::user::Model> = entity::User::find_by_id(id)
|
let user: Option<entity::user::Model> = entity::User::find_by_id(id)
|
||||||
.one(&self.connection)
|
.one(&self.connection)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.map_err(|e| RepositoryError::DatabaseError(Box::new(e)))?;
|
||||||
let mut user: entity::user::ActiveModel = user.unwrap().into();
|
let mut user: entity::user::ActiveModel = user.ok_or(RepositoryError::ItemNotFound)?.into();
|
||||||
|
|
||||||
// should we really allow username change?
|
// should we really allow username change?
|
||||||
if let Some(value) = data.get("username") {
|
if let Some(value) = data.get("username") {
|
||||||
@ -170,14 +170,18 @@ impl DepotRepository for UserRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update
|
// update
|
||||||
if let Ok(user) = user.update(&self.connection).await {
|
match user.update(&self.connection).await {
|
||||||
|
Ok(user) => {
|
||||||
let id = user.id.to_string();
|
let id = user.id.to_string();
|
||||||
return Ok(RepositoryResponse::ItemOnly(
|
return Ok(RepositoryResponse::ItemOnly(
|
||||||
model.build_item(&*id, serde_json::to_value(&user).unwrap()),
|
model.build_item(&*id, serde_json::to_value(&user).unwrap()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
Err(err) => {
|
||||||
Ok(RepositoryResponse::NoItem)
|
warn!("Error updating user");
|
||||||
|
return Err(RepositoryError::DatabaseError(Box::new(err)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn replace(
|
async fn replace(
|
||||||
@ -197,6 +201,7 @@ impl DepotRepository for UserRepository {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
if let Some(user) = user {
|
if let Some(user) = user {
|
||||||
let delete_result = user.delete(&self.connection).await.unwrap();
|
let delete_result = user.delete(&self.connection).await.unwrap();
|
||||||
|
// .ok_or(RepositoryError::DatabaseError(Box::new(err)))?;
|
||||||
debug!("deleted rows: {}", delete_result.rows_affected);
|
debug!("deleted rows: {}", delete_result.rows_affected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,16 @@ impl DepotRepository for MyStaticRepository {
|
|||||||
.content
|
.content
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.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(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,6 +126,7 @@ impl DepotRepository for MyStaticRepository {
|
|||||||
if let Some(index) = item_index {
|
if let Some(index) = item_index {
|
||||||
let item = &mut self.content[index];
|
let item = &mut self.content[index];
|
||||||
*item = data.clone();
|
*item = data.clone();
|
||||||
|
item["id"] = (*id).into();
|
||||||
|
|
||||||
if let Some(item_id) = item.get("id") {
|
if let Some(item_id) = item.get("id") {
|
||||||
return Ok(RepositoryResponse::ItemOnly(
|
return Ok(RepositoryResponse::ItemOnly(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends base|none("admin/base.jinja") %}
|
{% extends base|none("depot/base.jinja") %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="message-box-area" class="ui message" _="init wait 3s then transition opacity to 0 then remove me">
|
<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>
|
<h1>Update {{item_model.name}} in {{item_info.name}}</h1>
|
||||||
{% set fields = item_info.fields %}
|
{% set fields = item_info.fields %}
|
||||||
{% set form = { 'action': item.change_url, 'method': 'PATCH' } %}
|
{% set form = { 'action': item.change_url, 'method': 'PATCH' } %}
|
||||||
{% include "/admin/items/item_change_form.jinja" %}
|
{% include "/depot/items/item_change_form.jinja" %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
@ -10,10 +10,10 @@
|
|||||||
{% elif form.method|upper == 'PUT' %}
|
{% elif form.method|upper == 'PUT' %}
|
||||||
hx-put="{{ form.action }}"
|
hx-put="{{ form.action }}"
|
||||||
{% else %}
|
{% else %}
|
||||||
unknown-form-method={{form.method}}
|
unknown-form-method="{{ form.method }}"
|
||||||
{% endif %}>
|
{% endif %}>
|
||||||
|
|
||||||
{% from "/admin/items/items.jinja" import field_widget %}
|
{% from "/depot/items/items.jinja" import field_widget %}
|
||||||
{% for field_name, field_defs in fields %}
|
{% for field_name, field_defs in fields %}
|
||||||
{% if item %}
|
{% if item %}
|
||||||
{% set field_value = item.fields[field_name]|none("") %}
|
{% 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 %}
|
{% block content %}
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
@ -12,6 +12,6 @@
|
|||||||
|
|
||||||
{% set fields = item_info.fields %}
|
{% set fields = item_info.fields %}
|
||||||
{% set form = { 'action': item_model.add_url } %}
|
{% set form = { 'action': item_model.add_url } %}
|
||||||
{% include "/admin/items/item_change_form.jinja" %}
|
{% include "/depot/items/item_change_form.jinja" %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
@ -1,4 +1,4 @@
|
|||||||
{% extends base|none("admin/base.jinja") %}
|
{% extends base|none("depot/base.jinja") %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends base|none("admin/base.jinja") %}
|
{% extends base|none("depot/base.jinja") %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
|
Loading…
Reference in New Issue
Block a user