use crate::admin::form::{infer_field_type, FieldConfig, FieldType, FormConfig};
#[derive(Debug, Clone)]
pub struct AutoField {
pub name: &'static str,
pub label: &'static str,
pub field_type: Option<FieldType>,
pub required: bool,
pub is_foreign_key: bool,
pub options: Vec<(String, String)>,
}
pub trait FormModel {
fn form_fields() -> Vec<AutoField>;
fn form_title() -> &'static str;
}
pub fn form_from_model<T: FormModel>() -> FormConfig {
let fields = T::form_fields()
.into_iter()
.map(field_config_from)
.collect();
FormConfig {
title: T::form_title().to_string(),
subtitle: String::new(),
fields,
submitted: false,
save_failed: false,
hidden_fields: Vec::new(),
}
}
fn field_config_from(f: AutoField) -> FieldConfig {
let mut ty = match f.field_type {
Some(t) => t,
None => infer_field_type(f.name),
};
if f.is_foreign_key {
ty = FieldType::ForeignKey;
}
FieldConfig {
name: f.name.to_string(),
label: f.label.to_string(),
field_type: ty,
required: f.required,
readonly: false,
placeholder: None,
help: None,
value: None,
options: f.options,
error: None,
}
}
#[derive(Debug, Clone, Default)]
pub struct FieldOverride {
pub field_type: Option<FieldType>,
pub label: Option<String>,
pub help: Option<String>,
}
pub struct FormBuilder {
pub form: FormConfig,
}
impl FormBuilder {
pub fn from_model<T: FormModel>() -> Self {
Self {
form: form_from_model::<T>(),
}
}
pub fn override_field(mut self, name: &str, patch: FieldOverride) -> Self {
if let Some(field) = self.form.fields.iter_mut().find(|f| f.name == name) {
if let Some(ty) = patch.field_type {
field.field_type = ty;
}
if let Some(label) = patch.label {
field.label = label;
}
if let Some(help) = patch.help {
field.help = Some(help);
}
}
self
}
pub fn build(self) -> FormConfig {
self.form
}
}