impl textarea

This commit is contained in:
manuel 2022-08-20 23:31:45 +02:00
parent 16e8c36f9f
commit ea93fd6244
9 changed files with 72 additions and 28 deletions

View File

@ -13,7 +13,8 @@ pub mod derive_attr {
pub primary_key: Option<()>, pub primary_key: Option<()>,
pub html_input_type: Option<syn::LitStr>, pub html_input_type: Option<syn::LitStr>,
pub select_list: Option<syn::LitStr>, pub select_list: Option<syn::LitStr>,
pub searchable: Option<()> pub searchable: Option<()>,
pub textarea: Option<()>
//pub inner_type: Option<syn::Type>, //pub inner_type: Option<syn::Type>,
// Anything that implements `syn::parse::Parse` is supported. // Anything that implements `syn::parse::Parse` is supported.

View File

@ -2,14 +2,7 @@ use proc_macro;
use quote::quote; use quote::quote;
mod struct_fields; mod struct_fields;
use struct_fields::{ use struct_fields::*;
get_actix_admin_fields, get_actix_admin_fields_html_input,
get_actix_admin_fields_is_option_list, get_actix_admin_fields_searchable,
get_actix_admin_fields_select_list, get_actix_admin_fields_type_path_string,
get_field_for_primary_key, get_fields_for_create_model, get_fields_for_edit_model,
get_fields_for_from_model, get_fields_for_tokenstream, get_fields_for_validate_model,
get_primary_key_field_name,
};
mod selectlist_fields; mod selectlist_fields;
use selectlist_fields::{get_select_list_from_enum, get_select_list_from_model, get_select_lists}; use selectlist_fields::{get_select_list_from_enum, get_select_list_from_model, get_select_lists};
@ -147,6 +140,7 @@ pub fn derive_actix_admin_model(input: proc_macro::TokenStream) -> proc_macro::T
let fields_for_validate_model = get_fields_for_validate_model(&fields); let fields_for_validate_model = get_fields_for_validate_model(&fields);
let fields_searchable = get_actix_admin_fields_searchable(&fields); let fields_searchable = get_actix_admin_fields_searchable(&fields);
let fields_type_path = get_actix_admin_fields_type_path_string(&fields); let fields_type_path = get_actix_admin_fields_type_path_string(&fields);
let fields_textarea = get_actix_admin_fields_textarea(&fields);
let expanded = quote! { let expanded = quote! {
impl From<Model> for ActixAdminModel { impl From<Model> for ActixAdminModel {
@ -232,7 +226,11 @@ pub fn derive_actix_admin_model(input: proc_macro::TokenStream) -> proc_macro::T
#(#fields_type_path),* #(#fields_type_path),*
]; ];
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 fields_textareas = [
#(#fields_textarea),*
];
for (field_name, html_input_type, select_list, is_option_list, fields_type_path, is_textarea) in izip!(&field_names, &html_input_types, &field_select_lists, is_option_lists, fields_type_paths, fields_textareas) {
let select_list = select_list.replace('"', "").replace(' ', "").to_string(); let select_list = select_list.replace('"', "").replace(' ', "").to_string();
let field_name = field_name.replace('"', "").replace(' ', "").to_string(); let field_name = field_name.replace('"', "").replace(' ', "").to_string();
@ -243,7 +241,7 @@ pub fn derive_actix_admin_model(input: proc_macro::TokenStream) -> proc_macro::T
html_input_type: html_input_type, html_input_type: html_input_type,
select_list: select_list.clone(), select_list: select_list.clone(),
is_option: is_option_list, is_option: is_option_list,
field_type: ActixAdminViewModelFieldType::get_field_type(fields_type_path, select_list) field_type: ActixAdminViewModelFieldType::get_field_type(fields_type_path, select_list, is_textarea)
}); });
} }
vec vec

View File

@ -12,7 +12,8 @@ pub struct ModelField {
pub primary_key: bool, pub primary_key: bool,
pub html_input_type: String, pub html_input_type: String,
pub select_list: String, pub select_list: String,
pub searchable: bool pub searchable: bool,
pub textarea: bool
} }
impl ModelField { impl ModelField {

View File

@ -38,6 +38,9 @@ pub fn filter_fields(fields: &Fields) -> Vec<ModelField> {
let is_searchable = actix_admin_attr let is_searchable = actix_admin_attr
.clone() .clone()
.map_or(false, |attr| attr.searchable.is_some()); .map_or(false, |attr| attr.searchable.is_some());
let is_textarea = actix_admin_attr
.clone()
.map_or(false, |attr| attr.textarea.is_some());
let select_list = actix_admin_attr.clone().map_or("".to_string(), |attr| { let select_list = actix_admin_attr.clone().map_or("".to_string(), |attr| {
attr.select_list.map_or("".to_string(), |attr_field| { attr.select_list.map_or("".to_string(), |attr_field| {
(LitStr::from(attr_field)).value() (LitStr::from(attr_field)).value()
@ -58,7 +61,8 @@ pub fn filter_fields(fields: &Fields) -> Vec<ModelField> {
primary_key: is_primary_key, primary_key: is_primary_key,
html_input_type: html_input_type, html_input_type: html_input_type,
select_list: select_list, select_list: select_list,
searchable: is_searchable searchable: is_searchable,
textarea: is_textarea
}; };
Some(model_field) Some(model_field)
} else { } else {
@ -168,6 +172,20 @@ pub fn get_actix_admin_fields_html_input(fields: &Vec<ModelField>) -> Vec<TokenS
.collect::<Vec<_>>() .collect::<Vec<_>>()
} }
pub fn get_actix_admin_fields_textarea(fields: &Vec<ModelField>) -> Vec<TokenStream> {
fields
.iter()
.filter(|model_field| !model_field.primary_key)
.map(|model_field| {
let is_textarea = model_field.textarea;
quote! {
#is_textarea
}
})
.collect::<Vec<_>>()
}
pub fn get_actix_admin_fields_searchable(fields: &Vec<ModelField>) -> Vec<TokenStream> { pub fn get_actix_admin_fields_searchable(fields: &Vec<ModelField>) -> Vec<TokenStream> {
fields fields
.iter() .iter()

View File

@ -15,7 +15,7 @@ pub struct Model {
#[actix_admin(searchable)] #[actix_admin(searchable)]
pub title: String, pub title: String,
#[sea_orm(column_type = "Text")] #[sea_orm(column_type = "Text")]
#[actix_admin(searchable)] #[actix_admin(searchable, textarea)]
pub text: String, pub text: String,
#[actix_admin(select_list="Tea")] #[actix_admin(select_list="Tea")]
pub tea_mandatory: Tea, pub tea_mandatory: Tea,

View File

@ -45,6 +45,7 @@ lazy_static! {
pub fn get_html_input_class<S: BuildHasher>(value: &tera::Value, _: &HashMap<String, tera::Value, S>) -> Result<tera::Value> { pub fn get_html_input_class<S: BuildHasher>(value: &tera::Value, _: &HashMap<String, tera::Value, S>) -> Result<tera::Value> {
let field = try_get_value!("get_html_input_class", "value", ActixAdminViewModelField, value); let field = try_get_value!("get_html_input_class", "value", ActixAdminViewModelField, value);
let html_input_type = match field.field_type { let html_input_type = match field.field_type {
ActixAdminViewModelFieldType::TextArea => "textarea",
ActixAdminViewModelFieldType::Checkbox => "checkbox", ActixAdminViewModelFieldType::Checkbox => "checkbox",
_ => "input" _ => "input"
}; };

View File

@ -82,10 +82,13 @@ pub struct ActixAdminViewModelField {
} }
impl ActixAdminViewModelFieldType { impl ActixAdminViewModelFieldType {
pub fn get_field_type(type_path: &str, select_list: String) -> ActixAdminViewModelFieldType { pub fn get_field_type(type_path: &str, select_list: String, is_textarea: bool) -> ActixAdminViewModelFieldType {
if !select_list.is_empty() { if !select_list.is_empty() {
return ActixAdminViewModelFieldType::SelectList; return ActixAdminViewModelFieldType::SelectList;
} }
if is_textarea {
return ActixAdminViewModelFieldType::TextArea;
}
match type_path { match type_path {
"i32" => ActixAdminViewModelFieldType::Number, "i32" => ActixAdminViewModelFieldType::Number,

View File

@ -1,13 +1,34 @@
{% if model_field.field_type == "TextArea" %}
<textarea
class="{{ model_field | get_html_input_class }}
{% if model.errors | length > 0 or model.custom_errors | length > 0 %}
{% if
model.errors | get(key=model_field.field_name, default="" ) !=""
or
model.custom_errors | get(key=model_field.field_name, default="" ) !=""
%}is-danger{% else %}is-success{% endif %}
{% endif %}
"
type="{{ model_field | get_html_input_type }}"
name="{{ model_field.field_name }}"
placeholder="{{ model_field.field_name }}"
aria-label="{{ model_field.field_name }}"
>{{ model.values | get(key=model_field.field_name, default="") }}</textarea>
{% else %}
<input <input
class="{{ model_field | get_html_input_class }} class="{{ model_field | get_html_input_class }}
{% if {% if model.errors | length > 0 or model.custom_errors | length > 0 %}
model.errors | get(key=model_field.field_name, default="" ) !="" {% if
or model.errors | get(key=model_field.field_name, default="" ) !=""
model.custom_errors | get(key=model_field.field_name, default="" ) !="" or
%}is-danger{% endif %}" model.custom_errors | get(key=model_field.field_name, default="" ) !=""
%}is-danger{% else %}is-success{% endif %}
{% endif %}
"
type="{{ model_field | get_html_input_type }}" type="{{ model_field | get_html_input_type }}"
value="{{ model.values | get(key=model_field.field_name, default="") }}" value="{{ model.values | get(key=model_field.field_name, default="") }}"
name="{{ model_field.field_name }}" name="{{ model_field.field_name }}"
placeholder="{{ model_field.field_name }}" placeholder="{{ model_field.field_name }}"
aria-label="{{ model_field.field_name }}" aria-label="{{ model_field.field_name }}"
> >
{% endif %}

View File

@ -1,10 +1,11 @@
<div class="select <div class="select
{% if {% if model.errors | length > 0 or model.custom_errors | length > 0 %}
model.errors | get(key=model_field.field_name, default="" ) !="" {% if
or model.errors | get(key=model_field.field_name, default="" ) !=""
model.custom_errors | get(key=model_field.field_name, default="" ) !="" or
%}is-danger{% endif %}" model.custom_errors | get(key=model_field.field_name, default="" ) !=""
> %}is-danger{% else %}is-success{% endif %}
{% endif %}">
<select name="{{ model_field.field_name }}"> <select name="{{ model_field.field_name }}">
{% if model_field.is_option %} {% if model_field.is_option %}
<option value=""></option> <option value=""></option>