parse datetime and bool correctly
This commit is contained in:
parent
5aa8bc809d
commit
fb4cd9f7d7
@ -7,6 +7,7 @@ edition = "2021"
|
|||||||
actix-web = "4.0.1"
|
actix-web = "4.0.1"
|
||||||
actix-multipart = "0.4.0"
|
actix-multipart = "0.4.0"
|
||||||
futures-util = "0.3.21"
|
futures-util = "0.3.21"
|
||||||
|
chrono = "0.4.20"
|
||||||
tera = "1.16.0"
|
tera = "1.16.0"
|
||||||
actix_admin_macros = { path = "actix_admin_macros" }
|
actix_admin_macros = { path = "actix_admin_macros" }
|
||||||
async-trait = "0.1.53"
|
async-trait = "0.1.53"
|
||||||
|
@ -211,12 +211,17 @@ pub fn derive_crud_fns(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (field_name, html_input_type, select_list, is_option_list, fields_type_path) in izip!(&field_names, &html_input_types, &field_select_lists, is_option_lists, fields_type_paths) {
|
for (field_name, html_input_type, select_list, is_option_list, fields_type_path) in izip!(&field_names, &html_input_types, &field_select_lists, is_option_lists, fields_type_paths) {
|
||||||
|
|
||||||
|
let select_list = select_list.replace('"', "").replace(' ', "").to_string();
|
||||||
|
let field_name = field_name.replace('"', "").replace(' ', "").to_string();
|
||||||
|
let html_input_type = html_input_type.replace('"', "").replace(' ', "").to_string();
|
||||||
|
|
||||||
vec.push(ActixAdminViewModelField {
|
vec.push(ActixAdminViewModelField {
|
||||||
field_name: field_name.replace('"', "").replace(' ', "").to_string(),
|
field_name: field_name,
|
||||||
html_input_type: html_input_type.replace('"', "").replace(' ', "").to_string(),
|
html_input_type: html_input_type,
|
||||||
select_list: select_list.replace('"', "").replace(' ', "").to_string(),
|
select_list: select_list.clone(),
|
||||||
is_option: is_option_list,
|
is_option: is_option_list,
|
||||||
field_type: ActixAdminViewModelFieldType::from(fields_type_path)
|
field_type: ActixAdminViewModelFieldType::get_field_type(fields_type_path, select_list)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
vec
|
vec
|
||||||
|
@ -254,22 +254,36 @@ pub fn get_fields_for_validate_model(fields: &Vec<ModelField>) -> Vec<TokenStrea
|
|||||||
.map(|model_field| {
|
.map(|model_field| {
|
||||||
let ident_name = model_field.ident.to_string();
|
let ident_name = model_field.ident.to_string();
|
||||||
let ty = model_field.ty.to_owned();
|
let ty = model_field.ty.to_owned();
|
||||||
|
let type_path = model_field.get_type_path_string();
|
||||||
|
|
||||||
let is_option_or_string = model_field.is_option() || model_field.is_string();
|
let is_option_or_string = model_field.is_option() || model_field.is_string();
|
||||||
|
|
||||||
match model_field.is_option() {
|
let res = match (model_field.is_option(), type_path.as_str()) {
|
||||||
true => {
|
(_, "DateTime") => {
|
||||||
|
quote! {
|
||||||
|
model.get_datetime(#ident_name, #is_option_or_string).map_err(|err| errors.insert(#ident_name.to_string(), err)).ok()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(_, "bool") => {
|
||||||
|
quote! {
|
||||||
|
model.get_bool(#ident_name, #is_option_or_string).map_err(|err| errors.insert(#ident_name.to_string(), err)).ok()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// generic
|
||||||
|
(true, _) => {
|
||||||
let inner_ty = model_field.inner_type.to_owned().unwrap();
|
let inner_ty = model_field.inner_type.to_owned().unwrap();
|
||||||
quote! {
|
quote! {
|
||||||
model.get_value::<#inner_ty>(#ident_name, #is_option_or_string).map_err(|err| errors.insert(#ident_name.to_string(), err)).ok()
|
model.get_value::<#inner_ty>(#ident_name, #is_option_or_string).map_err(|err| errors.insert(#ident_name.to_string(), err)).ok()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
false => {
|
(false, _) => {
|
||||||
quote! {
|
quote! {
|
||||||
model.get_value::<#ty>(#ident_name, #is_option_or_string).map_err(|err| errors.insert(#ident_name.to_string(), err)).ok()
|
model.get_value::<#ty>(#ident_name, #is_option_or_string).map_err(|err| errors.insert(#ident_name.to_string(), err)).ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
res
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
@ -283,30 +297,49 @@ pub fn get_fields_for_create_model(fields: &Vec<ModelField>) -> Vec<TokenStream>
|
|||||||
let ident_name = model_field.ident.to_string();
|
let ident_name = model_field.ident.to_string();
|
||||||
let ident = model_field.ident.to_owned();
|
let ident = model_field.ident.to_owned();
|
||||||
let ty = model_field.ty.to_owned();
|
let ty = model_field.ty.to_owned();
|
||||||
|
let type_path = model_field.get_type_path_string();
|
||||||
|
|
||||||
let is_option_or_string = model_field.is_option() || model_field.is_string();
|
let is_option_or_string = model_field.is_option() || model_field.is_string();
|
||||||
|
|
||||||
match model_field.is_option() {
|
let res = match (model_field.is_option(), model_field.is_string(), type_path.as_str()) {
|
||||||
true => {
|
// is DateTime
|
||||||
|
(true , _, "DateTime") => {
|
||||||
|
quote! {
|
||||||
|
#ident: Set(model.get_datetime(#ident_name, #is_option_or_string).unwrap())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(false , _, "DateTime") => {
|
||||||
|
quote! {
|
||||||
|
#ident: Set(model.get_datetime(#ident_name, #is_option_or_string).unwrap().unwrap())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(_ , _, "bool") => {
|
||||||
|
quote! {
|
||||||
|
#ident: Set(model.get_bool(#ident_name, #is_option_or_string).unwrap().unwrap())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Default fields
|
||||||
|
(true, _, _) => {
|
||||||
let inner_ty = model_field.inner_type.to_owned().unwrap();
|
let inner_ty = model_field.inner_type.to_owned().unwrap();
|
||||||
quote! {
|
quote! {
|
||||||
#ident: Set(model.get_value::<#inner_ty>(#ident_name, #is_option_or_string).unwrap())
|
#ident: Set(model.get_value::<#inner_ty>(#ident_name, #is_option_or_string).unwrap())
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
// TODO: this fails for empty string as it returns None which then cannot be unwrapped
|
// is string which can be empty
|
||||||
// Should do maybe typecheck and if it is string return "" instead of None
|
(false, true, _) => {
|
||||||
false => {
|
|
||||||
if model_field.is_string() {
|
|
||||||
quote! {
|
quote! {
|
||||||
#ident: Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap_or(String::new()))
|
#ident: Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap_or(String::new()))
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
|
// no string
|
||||||
|
(false, false, _) => {
|
||||||
quote! {
|
quote! {
|
||||||
#ident: Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap())
|
#ident: Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
res
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
@ -320,28 +353,45 @@ pub fn get_fields_for_edit_model(fields: &Vec<ModelField>) -> Vec<TokenStream> {
|
|||||||
let ident_name = model_field.ident.to_string();
|
let ident_name = model_field.ident.to_string();
|
||||||
let ident = model_field.ident.to_owned();
|
let ident = model_field.ident.to_owned();
|
||||||
let ty = model_field.ty.to_owned();
|
let ty = model_field.ty.to_owned();
|
||||||
|
let type_path = model_field.get_type_path_string();
|
||||||
|
|
||||||
let is_option_or_string = model_field.is_option() || model_field.is_string();
|
let is_option_or_string = model_field.is_option() || model_field.is_string();
|
||||||
|
|
||||||
match model_field.is_option() {
|
let res = match (model_field.is_option(), model_field.is_string(), type_path.as_str()) {
|
||||||
true => {
|
(_, _, "bool") => {
|
||||||
|
quote! {
|
||||||
|
entity.#ident = Set(model.get_bool(#ident_name, #is_option_or_string).unwrap().unwrap())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(true , _, "DateTime") => {
|
||||||
|
quote! {
|
||||||
|
entity.#ident = Set(model.get_datetime(#ident_name, #is_option_or_string).unwrap())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(false , _, "DateTime") => {
|
||||||
|
quote! {
|
||||||
|
entity.#ident = Set(model.get_datetime(#ident_name, #is_option_or_string).unwrap().unwrap())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(true, _, _) => {
|
||||||
let inner_ty = model_field.inner_type.to_owned().unwrap();
|
let inner_ty = model_field.inner_type.to_owned().unwrap();
|
||||||
quote! {
|
quote! {
|
||||||
entity.#ident = Set(model.get_value::<#inner_ty>(#ident_name, #is_option_or_string).unwrap())
|
entity.#ident = Set(model.get_value::<#inner_ty>(#ident_name, #is_option_or_string).unwrap())
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
false => {
|
(false, true, _) => {
|
||||||
if model_field.is_string() {
|
|
||||||
quote! {
|
quote! {
|
||||||
entity.#ident = Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap_or(String::new()))
|
entity.#ident = Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap_or(String::new()))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
else {
|
(false, false, _) => {
|
||||||
quote! {
|
quote! {
|
||||||
entity.#ident = Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap())
|
entity.#ident = Set(model.get_value::<#ty>(#ident_name, #is_option_or_string).unwrap().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
res
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use sea_orm::DatabaseConnection;
|
use sea_orm::DatabaseConnection;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tera::{Tera, Result, Value, to_value, try_get_value };
|
use tera::{Tera, Result, to_value, try_get_value };
|
||||||
use std::{ hash::BuildHasher};
|
use std::{ hash::BuildHasher};
|
||||||
|
|
||||||
pub mod view_model;
|
pub mod view_model;
|
||||||
@ -35,6 +35,7 @@ lazy_static! {
|
|||||||
let mut tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
let mut tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
||||||
tera.register_filter("get_html_input_type", get_html_input_type);
|
tera.register_filter("get_html_input_type", get_html_input_type);
|
||||||
tera.register_filter("get_html_input_class", get_html_input_class);
|
tera.register_filter("get_html_input_class", get_html_input_class);
|
||||||
|
tera.register_filter("get_icon", get_icon);
|
||||||
tera
|
tera
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -49,6 +50,17 @@ pub fn get_html_input_class<S: BuildHasher>(value: &tera::Value, _: &HashMap<Str
|
|||||||
Ok(to_value(html_input_type).unwrap())
|
Ok(to_value(html_input_type).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_icon<S: BuildHasher>(value: &tera::Value, _: &HashMap<String, tera::Value, S>) -> Result<tera::Value> {
|
||||||
|
let field = try_get_value!("get_icon", "value", String, value);
|
||||||
|
let font_awesome_icon = match field.as_str() {
|
||||||
|
"true" => "<i class=\"fa-solid fa-check\"></i>",
|
||||||
|
"false" => "<i class=\"fa-solid fa-xmark\"></i>",
|
||||||
|
_ => panic!("not implemented icon")
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(to_value(font_awesome_icon).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_html_input_type<S: BuildHasher>(value: &tera::Value, _: &HashMap<String, tera::Value, S>) -> Result<tera::Value> {
|
pub fn get_html_input_type<S: BuildHasher>(value: &tera::Value, _: &HashMap<String, tera::Value, S>) -> Result<tera::Value> {
|
||||||
let field = try_get_value!("get_html_input_type", "value", ActixAdminViewModelField, value);
|
let field = try_get_value!("get_html_input_type", "value", ActixAdminViewModelField, value);
|
||||||
|
|
||||||
@ -60,6 +72,7 @@ pub fn get_html_input_type<S: BuildHasher>(value: &tera::Value, _: &HashMap<Stri
|
|||||||
let html_input_type = match field.field_type {
|
let html_input_type = match field.field_type {
|
||||||
ActixAdminViewModelFieldType::Text => "text",
|
ActixAdminViewModelFieldType::Text => "text",
|
||||||
ActixAdminViewModelFieldType::DateTime => "datetime-local",
|
ActixAdminViewModelFieldType::DateTime => "datetime-local",
|
||||||
|
ActixAdminViewModelFieldType::Date => "date",
|
||||||
ActixAdminViewModelFieldType::Checkbox => "checkbox",
|
ActixAdminViewModelFieldType::Checkbox => "checkbox",
|
||||||
_ => "text"
|
_ => "text"
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,10 @@ use serde::Serialize;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use actix_multipart:: {Multipart, MultipartError} ;
|
use actix_multipart:: {Multipart, MultipartError} ;
|
||||||
use futures_util::stream::StreamExt as _;
|
use futures_util::stream::StreamExt as _;
|
||||||
|
use chrono::{NaiveDateTime, NaiveDate};
|
||||||
|
use sea_orm::prelude::*;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait ActixAdminModelTrait {
|
pub trait ActixAdminModelTrait {
|
||||||
@ -29,6 +33,7 @@ pub struct ActixAdminModel {
|
|||||||
pub errors: HashMap<String, String>,
|
pub errors: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl ActixAdminModel {
|
impl ActixAdminModel {
|
||||||
pub fn create_empty() -> ActixAdminModel {
|
pub fn create_empty() -> ActixAdminModel {
|
||||||
ActixAdminModel {
|
ActixAdminModel {
|
||||||
@ -65,6 +70,23 @@ impl ActixAdminModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_value<T: std::str::FromStr>(&self, key: &str, is_option_or_string: bool) -> Result<Option<T>, String> {
|
pub fn get_value<T: std::str::FromStr>(&self, key: &str, is_option_or_string: bool) -> Result<Option<T>, String> {
|
||||||
|
self.get_value_by_closure(key, is_option_or_string, |val| val.parse::<T>())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_datetime(&self, key: &str, is_option_or_string: bool) -> Result<Option<DateTime>, String> {
|
||||||
|
self.get_value_by_closure(key, is_option_or_string, |val| NaiveDateTime::parse_from_str(val, "%Y-%m-%dT%H:%M"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bool(&self, key: &str, is_option_or_string: bool) -> Result<Option<bool>, String> {
|
||||||
|
let val = self.get_value_by_closure(key, is_option_or_string, |val| if !val.is_empty() { Ok(true) } else { Ok(false) });
|
||||||
|
// not selected bool field equals to false and not to missing
|
||||||
|
match val {
|
||||||
|
Ok(val) => Ok(val),
|
||||||
|
Err(_) => Ok(Some(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_value_by_closure<T: std::str::FromStr>(&self, key: &str, is_option_or_string: bool, f: impl Fn(&String) -> Result<T, <T as std::str::FromStr>::Err>) -> Result<Option<T>, String> {
|
||||||
let value = self.values.get(key);
|
let value = self.values.get(key);
|
||||||
|
|
||||||
let res: Result<Option<T>, String> = match value {
|
let res: Result<Option<T>, String> = match value {
|
||||||
@ -73,7 +95,7 @@ impl ActixAdminModel {
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let parsed_val = val.parse::<T>();
|
let parsed_val = f(val);
|
||||||
println!("{:?}", val);
|
println!("{:?}", val);
|
||||||
|
|
||||||
match parsed_val {
|
match parsed_val {
|
||||||
|
@ -47,20 +47,6 @@ pub enum ActixAdminViewModelFieldType {
|
|||||||
SelectList
|
SelectList
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for ActixAdminViewModelFieldType {
|
|
||||||
fn from(input: &str) -> ActixAdminViewModelFieldType {
|
|
||||||
match input {
|
|
||||||
"i32" => ActixAdminViewModelFieldType::Number,
|
|
||||||
"i64" => ActixAdminViewModelFieldType::Number,
|
|
||||||
"usize" => ActixAdminViewModelFieldType::Number,
|
|
||||||
"String" => ActixAdminViewModelFieldType::Text,
|
|
||||||
"bool" => ActixAdminViewModelFieldType::Checkbox,
|
|
||||||
"DateTimeWithTimeZone" => ActixAdminViewModelFieldType::DateTime,
|
|
||||||
_ => ActixAdminViewModelFieldType::Text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct ActixAdminViewModelField {
|
pub struct ActixAdminViewModelField {
|
||||||
pub field_name: String,
|
pub field_name: String,
|
||||||
@ -69,3 +55,24 @@ pub struct ActixAdminViewModelField {
|
|||||||
pub is_option: bool,
|
pub is_option: bool,
|
||||||
pub field_type: ActixAdminViewModelFieldType
|
pub field_type: ActixAdminViewModelFieldType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ActixAdminViewModelFieldType {
|
||||||
|
pub fn get_field_type(type_path: &str, select_list: String) -> ActixAdminViewModelFieldType {
|
||||||
|
if !select_list.is_empty() {
|
||||||
|
println!("field_type {} {}", type_path, select_list);
|
||||||
|
return ActixAdminViewModelFieldType::SelectList;
|
||||||
|
}
|
||||||
|
|
||||||
|
match type_path {
|
||||||
|
"i32" => ActixAdminViewModelFieldType::Number,
|
||||||
|
"i64" => ActixAdminViewModelFieldType::Number,
|
||||||
|
"usize" => ActixAdminViewModelFieldType::Number,
|
||||||
|
"String" => ActixAdminViewModelFieldType::Text,
|
||||||
|
"bool" => ActixAdminViewModelFieldType::Checkbox,
|
||||||
|
"DateTimeWithTimeZone" => ActixAdminViewModelFieldType::DateTime,
|
||||||
|
"DateTime" => ActixAdminViewModelFieldType::DateTime,
|
||||||
|
"Date" => ActixAdminViewModelFieldType::Date,
|
||||||
|
_ => ActixAdminViewModelFieldType::Text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,35 +7,16 @@
|
|||||||
<label class="{{ model_field | get_html_input_type }}" for="{{ model_field.field_name }}">
|
<label class="{{ model_field | get_html_input_type }}" for="{{ model_field.field_name }}">
|
||||||
{{ model_field.field_name | split(pat="_") | join(sep=" ") | title }}
|
{{ model_field.field_name | split(pat="_") | join(sep=" ") | title }}
|
||||||
</label>
|
</label>
|
||||||
{% if model_field.select_list != "" %}
|
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<div class="select {% if model.errors | get(key=model_field.field_name, default="" ) !="" %}is-danger{% endif %}">
|
{% if model_field.field_type == "SelectList" %}
|
||||||
<select name="{{ model_field.field_name }}">
|
{% include "form_elements/selectlist.html" %}
|
||||||
{% if model_field.is_option %}
|
{% elif model_field.field_type == "Checkbox" %}
|
||||||
<option value=""></option>
|
{% include "form_elements/checkbox.html" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<option value="" selected disabled>Select</option>
|
{% include "form_elements/input.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for select_list_item in select_lists[model_field.field_name] -%}
|
|
||||||
<option {% if select_list_item[0]==model.values | get(key=model_field.field_name, default="" ) %}
|
|
||||||
selected {% endif %} value="{{ select_list_item[0] }}">{{ select_list_item[1] | split(pat="_") |
|
|
||||||
join(sep=" ") | title }}</option>
|
|
||||||
{%- endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<div class="control">
|
|
||||||
<input class="{{ model_field | get_html_input_class }} {% if model.errors | get(key=model_field.field_name,default="" ) !="" %}is-danger{% endif %}"
|
|
||||||
type="{{ model_field | get_html_input_type }}"
|
|
||||||
value="{{ model.values | get(key=model_field.field_name, default="") | split(pat=" _") | join(sep=" " ) | title }}"
|
|
||||||
name="{{ model_field.field_name }}"
|
|
||||||
placeholder="{{ model_field.field_name }}"
|
|
||||||
aria-label="{{ model_field.field_name }}"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
<div class="field is-grouped">
|
<div class="field is-grouped">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
|
9
actix_admin/templates/form_elements/checkbox.html
Normal file
9
actix_admin/templates/form_elements/checkbox.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<input
|
||||||
|
class="{{ model_field | get_html_input_class }}"
|
||||||
|
type="{{ model_field | get_html_input_type }}"
|
||||||
|
value="true"
|
||||||
|
name="{{ model_field.field_name }}"
|
||||||
|
placeholder="{{ model_field.field_name }}"
|
||||||
|
aria-label="{{ model_field.field_name }}"
|
||||||
|
{% if model.values | get(key=model_field.field_name) == "true" %}checked{% endif %}
|
||||||
|
>
|
8
actix_admin/templates/form_elements/input.html
Normal file
8
actix_admin/templates/form_elements/input.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<input
|
||||||
|
class="{{ model_field | get_html_input_class }} {% if model.errors | get(key=model_field.field_name,default="" ) !="" %}is-danger{% endif %}"
|
||||||
|
type="{{ model_field | get_html_input_type }}"
|
||||||
|
value="{{ model.values | get(key=model_field.field_name, default="") | split(pat=" _") | join(sep=" " ) | title }}"
|
||||||
|
name="{{ model_field.field_name }}"
|
||||||
|
placeholder="{{ model_field.field_name }}"
|
||||||
|
aria-label="{{ model_field.field_name }}"
|
||||||
|
>
|
14
actix_admin/templates/form_elements/selectlist.html
Normal file
14
actix_admin/templates/form_elements/selectlist.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<div class="select {% if model.errors | get(key=model_field.field_name, default="" ) !="" %}is-danger{% endif %}">
|
||||||
|
<select name="{{ model_field.field_name }}">
|
||||||
|
{% if model_field.is_option %}
|
||||||
|
<option value=""></option>
|
||||||
|
{% else %}
|
||||||
|
<option value="" selected disabled>Select</option>
|
||||||
|
{% endif %}
|
||||||
|
{% for select_list_item in select_lists[model_field.field_name] -%}
|
||||||
|
<option {% if select_list_item[0]==model.values | get(key=model_field.field_name, default="" ) %} selected {%
|
||||||
|
endif %} value="{{ select_list_item[0] }}">{{ select_list_item[1] | split(pat="_") |
|
||||||
|
join(sep=" ") | title }}</option>
|
||||||
|
{%- endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
@ -86,7 +86,11 @@
|
|||||||
<td><input type="checkbox" name="ids" value="{{ entity.primary_key }}"></td>
|
<td><input type="checkbox" name="ids" value="{{ entity.primary_key }}"></td>
|
||||||
<td>{{ entity.primary_key }}</td>
|
<td>{{ entity.primary_key }}</td>
|
||||||
{% for model_field in view_model.fields -%}
|
{% for model_field in view_model.fields -%}
|
||||||
|
{% if model_field.field_type == "Checkbox" %}
|
||||||
|
<td>{{ entity.values | get(key=model_field.field_name) | get_icon | safe }}</td>
|
||||||
|
{% else %}
|
||||||
<td>{{ entity.values | get(key=model_field.field_name) }}</td>
|
<td>{{ entity.values | get(key=model_field.field_name) }}</td>
|
||||||
|
{% endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
<td>
|
<td>
|
||||||
<a href="edit/{{ entity.primary_key }}"><i class="fa-solid fa-pen-to-square"></i></a>
|
<a href="edit/{{ entity.primary_key }}"><i class="fa-solid fa-pen-to-square"></i></a>
|
||||||
|
BIN
database.db-wal
BIN
database.db-wal
Binary file not shown.
@ -14,7 +14,7 @@ pub struct Model {
|
|||||||
#[actix_admin(html_input_type = "email")]
|
#[actix_admin(html_input_type = "email")]
|
||||||
pub user: String,
|
pub user: String,
|
||||||
#[sea_orm(column_type = "DateTime")]
|
#[sea_orm(column_type = "DateTime")]
|
||||||
pub insert_date: DateTimeWithTimeZone,
|
pub insert_date: DateTime,
|
||||||
pub is_visible: bool
|
pub is_visible: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user