Skip to main content

reinhardt_admin/types/
models.rs

1//! Model information types
2
3use serde::{Deserialize, Serialize};
4
5/// Model information for dashboard
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ModelInfo {
8	/// Model name
9	pub name: String,
10	/// List URL
11	pub list_url: String,
12}
13
14/// Field metadata for dynamic form generation
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct FieldInfo {
17	/// Field name (e.g., "username", "email")
18	pub name: String,
19	/// Display label (e.g., "Username", "Email Address")
20	pub label: String,
21	/// Field type
22	pub field_type: FieldType,
23	/// Whether the field is required
24	pub required: bool,
25	/// Whether the field is readonly
26	pub readonly: bool,
27	/// Help text displayed below the field
28	pub help_text: Option<String>,
29	/// Placeholder text for input
30	pub placeholder: Option<String>,
31}
32
33/// Field type for form rendering
34#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
35#[serde(tag = "type", content = "options")]
36pub enum FieldType {
37	/// Text input (single line)
38	Text,
39	/// Textarea (multi-line)
40	TextArea,
41	/// Number input
42	Number,
43	/// Boolean checkbox
44	Boolean,
45	/// Email input
46	Email,
47	/// Date input
48	Date,
49	/// DateTime input
50	DateTime,
51	/// Select dropdown with choices.
52	Select {
53		/// Available choices as `(value, label)` pairs.
54		choices: Vec<(String, String)>,
55	},
56	/// Multiple select.
57	MultiSelect {
58		/// Available choices as `(value, label)` pairs.
59		choices: Vec<(String, String)>,
60	},
61	/// File upload
62	File,
63	/// Hidden field
64	Hidden,
65}
66
67/// Rendering specification for a form field.
68///
69/// This type preserves the structural information needed to emit the
70/// correct HTML element (e.g., `<input>`, `<textarea>`, `<select>`),
71/// along with any choices required for `<select>` options. It is derived
72/// from `FieldType` via `From<&FieldType>`.
73#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74#[serde(tag = "kind", content = "data")]
75pub enum FormFieldSpec {
76	/// Plain `<input>` element with the given HTML `type` attribute.
77	Input {
78		/// Value for the HTML `type` attribute (e.g., "text", "email",
79		/// "number", "checkbox", "date", "datetime-local").
80		///
81		/// Owned `String` (not `&'static str`) so the variant can round-trip
82		/// through `serde` deserialization at API boundaries — borrowed
83		/// `'static` strings cannot be reconstructed from incoming JSON.
84		html_type: String,
85	},
86	/// `<textarea>` element for multi-line text.
87	TextArea,
88	/// `<select>` dropdown with the given `(value, label)` choices.
89	Select {
90		/// Available choices as `(value, label)` pairs.
91		choices: Vec<(String, String)>,
92	},
93	/// `<select multiple>` dropdown with the given `(value, label)` choices.
94	MultiSelect {
95		/// Available choices as `(value, label)` pairs.
96		choices: Vec<(String, String)>,
97	},
98	/// `<input type="file">` for file uploads.
99	File,
100	/// `<input type="hidden">` for hidden values.
101	Hidden,
102}
103
104impl From<&FieldType> for FormFieldSpec {
105	fn from(field_type: &FieldType) -> Self {
106		match field_type {
107			FieldType::Text => FormFieldSpec::Input {
108				html_type: "text".to_string(),
109			},
110			FieldType::Number => FormFieldSpec::Input {
111				html_type: "number".to_string(),
112			},
113			FieldType::Boolean => FormFieldSpec::Input {
114				html_type: "checkbox".to_string(),
115			},
116			FieldType::Email => FormFieldSpec::Input {
117				html_type: "email".to_string(),
118			},
119			FieldType::Date => FormFieldSpec::Input {
120				html_type: "date".to_string(),
121			},
122			FieldType::DateTime => FormFieldSpec::Input {
123				html_type: "datetime-local".to_string(),
124			},
125			FieldType::TextArea => FormFieldSpec::TextArea,
126			FieldType::Select { choices } => FormFieldSpec::Select {
127				choices: choices.clone(),
128			},
129			FieldType::MultiSelect { choices } => FormFieldSpec::MultiSelect {
130				choices: choices.clone(),
131			},
132			FieldType::File => FormFieldSpec::File,
133			FieldType::Hidden => FormFieldSpec::Hidden,
134		}
135	}
136}
137
138/// Filter type for UI rendering
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140#[serde(tag = "type", content = "options")]
141pub enum FilterType {
142	/// Boolean filter (Yes/No checkbox)
143	Boolean,
144	/// Choice filter (dropdown with predefined options).
145	Choice {
146		/// Available filter choices.
147		choices: Vec<FilterChoice>,
148	},
149	/// Date range filter (predefined ranges like "Today", "Last 7 days").
150	DateRange {
151		/// Available date range options.
152		ranges: Vec<FilterChoice>,
153	},
154	/// Number range filter (predefined ranges).
155	NumberRange {
156		/// Available number range options.
157		ranges: Vec<FilterChoice>,
158	},
159}
160
161/// Filter choice for Choice/DateRange/NumberRange filters
162#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
163pub struct FilterChoice {
164	/// Value to send to API
165	pub value: String,
166	/// Display label for UI
167	pub label: String,
168}
169
170/// Filter metadata sent from backend to frontend
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct FilterInfo {
173	/// Field name (e.g., "status", "is_active")
174	pub field: String,
175	/// Display title (e.g., "Status", "Active")
176	pub title: String,
177	/// Filter type and options
178	pub filter_type: FilterType,
179	/// Current value (if filter is active)
180	pub current_value: Option<String>,
181}
182
183/// Column metadata for list view display
184#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct ColumnInfo {
186	/// Field name to extract from data
187	pub field: String,
188	/// Display label for column header
189	pub label: String,
190	/// Whether column is sortable
191	pub sortable: bool,
192}