aboutsummaryrefslogtreecommitdiff
path: root/src/core/data/asset_fields.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/data/asset_fields.rs')
-rw-r--r--src/core/data/asset_fields.rs1008
1 files changed, 1008 insertions, 0 deletions
diff --git a/src/core/data/asset_fields.rs b/src/core/data/asset_fields.rs
new file mode 100644
index 0000000..c9b6a78
--- /dev/null
+++ b/src/core/data/asset_fields.rs
@@ -0,0 +1,1008 @@
+use crate::api::ApiClient;
+use crate::core::components::form_builder::FormBuilder;
+use crate::core::{EditorField, FieldType};
+use serde_json::Value;
+
+/// Struct to hold commonly used dropdown options for assets
+pub struct AssetDropdownOptions {
+ pub asset_types: Vec<(String, String)>,
+ pub status_options: Vec<(String, String)>,
+ pub lending_status_options: Vec<(String, String)>,
+ pub no_scan_options: Vec<(String, String)>,
+ pub zone_plus_options: Vec<(String, String)>,
+ pub category_options: Vec<(String, String)>,
+ pub zone_options: Vec<(String, String)>,
+ pub supplier_options: Vec<(String, String)>,
+ pub label_template_options: Vec<(String, String)>,
+ pub audit_task_options: Vec<(String, String)>,
+}
+
+impl AssetDropdownOptions {
+ /// Create dropdown options by fetching from API
+ pub fn new(api_client: &ApiClient) -> Self {
+ // Static options
+ let asset_types = vec![
+ ("N".to_string(), "Normal".to_string()),
+ ("B".to_string(), "Basic".to_string()),
+ ("L".to_string(), "License".to_string()),
+ ("C".to_string(), "Consumable".to_string()),
+ ];
+
+ // Status options: include full set supported by schema. Some installations may use "Retired" while others use "Scrapped".
+ // We include both to allow selection wherever the backend enum allows it.
+ let status_options = vec![
+ ("Good".to_string(), "Good".to_string()),
+ ("Attention".to_string(), "Attention".to_string()),
+ ("Faulty".to_string(), "Faulty".to_string()),
+ ("Missing".to_string(), "Missing".to_string()),
+ ("In Repair".to_string(), "In Repair".to_string()),
+ ("In Transit".to_string(), "In Transit".to_string()),
+ ("Expired".to_string(), "Expired".to_string()),
+ ("Unmanaged".to_string(), "Unmanaged".to_string()),
+ ("Retired".to_string(), "Retired".to_string()),
+ ("Scrapped".to_string(), "Scrapped".to_string()),
+ ];
+
+ let lending_status_options = vec![
+ ("Available".to_string(), "Available".to_string()),
+ ("Borrowed".to_string(), "Borrowed".to_string()),
+ ("Overdue".to_string(), "Overdue".to_string()),
+ ("Deployed".to_string(), "Deployed".to_string()),
+ (
+ "Illegally Handed Out".to_string(),
+ "Illegally Handed Out".to_string(),
+ ),
+ ("Stolen".to_string(), "Stolen".to_string()),
+ ];
+
+ let no_scan_options = vec![
+ ("No".to_string(), "No".to_string()),
+ ("Ask".to_string(), "Ask".to_string()),
+ ("Yes".to_string(), "Yes".to_string()),
+ ];
+
+ let zone_plus_options = vec![
+ ("".into(), "".into()),
+ ("Floating Local".into(), "Floating Local".into()),
+ ("Floating Global".into(), "Floating Global".into()),
+ ("Clarify".into(), "Clarify".into()),
+ ];
+
+ // Fetch categories from API
+ let mut category_options: Vec<(String, String)> = Vec::new();
+ if let Ok(resp) = api_client.select(
+ "categories",
+ Some(vec!["id".into(), "category_name".into()]),
+ None,
+ Some(vec![crate::models::OrderBy {
+ column: "category_name".into(),
+ direction: "ASC".into(),
+ }]),
+ None,
+ ) {
+ if resp.success {
+ if let Some(data) = resp.data {
+ for row in data {
+ let id = row
+ .get("id")
+ .and_then(|v| v.as_i64())
+ .map(|n| n.to_string())
+ .unwrap_or_default();
+ let name = row
+ .get("category_name")
+ .and_then(|v| v.as_str())
+ .unwrap_or("")
+ .to_string();
+ category_options.push((id, name));
+ }
+ }
+ }
+ }
+
+ // Fetch zones from API
+ let mut zone_options: Vec<(String, String)> = Vec::new();
+ if let Ok(resp) = api_client.select(
+ "zones",
+ Some(vec!["id".into(), "zone_code".into(), "zone_name".into()]),
+ None,
+ Some(vec![crate::models::OrderBy {
+ column: "zone_code".into(),
+ direction: "ASC".into(),
+ }]),
+ None,
+ ) {
+ if resp.success {
+ if let Some(data) = resp.data {
+ for row in data {
+ let id = row
+ .get("id")
+ .and_then(|v| v.as_i64())
+ .map(|n| n.to_string())
+ .unwrap_or_default();
+ let code = row
+ .get("zone_code")
+ .and_then(|v| v.as_str())
+ .unwrap_or("")
+ .to_string();
+ let name = row
+ .get("zone_name")
+ .and_then(|v| v.as_str())
+ .unwrap_or("")
+ .to_string();
+ zone_options.push((id, format!("{} - {}", code, name)));
+ }
+ }
+ }
+ }
+
+ // Fetch suppliers from API
+ let mut supplier_options: Vec<(String, String)> = Vec::new();
+ if let Ok(resp) = api_client.select(
+ "suppliers",
+ Some(vec!["id".into(), "name".into()]),
+ None,
+ Some(vec![crate::models::OrderBy {
+ column: "name".into(),
+ direction: "ASC".into(),
+ }]),
+ None,
+ ) {
+ if resp.success {
+ if let Some(data) = resp.data {
+ for row in data {
+ let id = row
+ .get("id")
+ .and_then(|v| v.as_i64())
+ .map(|n| n.to_string())
+ .unwrap_or_default();
+ let name = row
+ .get("name")
+ .and_then(|v| v.as_str())
+ .unwrap_or("")
+ .to_string();
+ supplier_options.push((id, name));
+ }
+ }
+ }
+ }
+
+ // Fetch label templates for dropdown
+ let mut label_template_options: Vec<(String, String)> = Vec::new();
+ if let Ok(resp) = api_client.select(
+ "label_templates",
+ Some(vec!["id".into(), "template_name".into()]),
+ None,
+ Some(vec![crate::models::OrderBy {
+ column: "template_name".into(),
+ direction: "ASC".into(),
+ }]),
+ None,
+ ) {
+ if resp.success {
+ if let Some(data) = resp.data {
+ for row in data {
+ let id = row
+ .get("id")
+ .and_then(|v| v.as_i64())
+ .map(|n| n.to_string())
+ .unwrap_or_default();
+ let name = row
+ .get("template_name")
+ .and_then(|v| v.as_str())
+ .unwrap_or("")
+ .to_string();
+ label_template_options.push((id, name));
+ }
+ }
+ }
+ }
+
+ // Fetch audit tasks and add default "None" option
+ let mut audit_task_options: Vec<(String, String)> =
+ vec![(String::new(), "-- None --".to_string())];
+ if let Ok(resp) = api_client.select(
+ "audit_tasks",
+ Some(vec!["id".into(), "task_name".into()]),
+ None,
+ Some(vec![crate::models::OrderBy {
+ column: "task_name".into(),
+ direction: "ASC".into(),
+ }]),
+ None,
+ ) {
+ if resp.success {
+ if let Some(data) = resp.data {
+ for row in data {
+ if let Some(id) = row.get("id").and_then(|v| v.as_i64()) {
+ let name = row
+ .get("task_name")
+ .and_then(|v| v.as_str())
+ .unwrap_or("")
+ .to_string();
+ audit_task_options.push((id.to_string(), name));
+ }
+ }
+ }
+ }
+ }
+
+ Self {
+ asset_types,
+ status_options,
+ lending_status_options,
+ no_scan_options,
+ zone_plus_options,
+ category_options,
+ zone_options,
+ supplier_options,
+ label_template_options,
+ audit_task_options,
+ }
+ }
+}
+
+/// Asset field configuration builder - provides standardized field definitions for asset forms
+pub struct AssetFieldBuilder;
+
+impl AssetFieldBuilder {
+ /// Create a Full Add dialog that shows (nearly) all asset fields similar to Advanced Edit,
+ /// but configured for inserting a new asset (no ID fields, audit fields stay read-only).
+ pub fn create_full_add_dialog(api_client: &ApiClient) -> FormBuilder {
+ let options = AssetDropdownOptions::new(api_client);
+
+ let fields: Vec<EditorField> = vec![
+ // Core identifiers for new record
+ EditorField {
+ name: "asset_tag".into(),
+ label: "Asset Tag".into(),
+ field_type: FieldType::Text,
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "asset_type".into(),
+ label: "Type".into(),
+ field_type: FieldType::Dropdown(options.asset_types.clone()),
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "name".into(),
+ label: "Name".into(),
+ field_type: FieldType::Text,
+ required: true,
+ read_only: false,
+ },
+ // Classification
+ EditorField {
+ name: "category_id".into(),
+ label: "Category".into(),
+ field_type: FieldType::Dropdown(options.category_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Quick add category
+ EditorField {
+ name: "new_category_name".into(),
+ label: "Add Category - Name".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "new_category_code".into(),
+ label: "Add Category - Code".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ // Location
+ EditorField {
+ name: "zone_id".into(),
+ label: "Zone".into(),
+ field_type: FieldType::Dropdown(options.zone_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Quick add zone
+ EditorField {
+ name: "new_zone_parent_id".into(),
+ label: "Add Zone - Parent".into(),
+ field_type: FieldType::Dropdown(options.zone_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "new_zone_mini_code".into(),
+ label: "Add Zone - Mini Code".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "new_zone_name".into(),
+ label: "Add Zone - Name".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "zone_plus".into(),
+ label: "Zone Plus".into(),
+ field_type: FieldType::Dropdown(options.zone_plus_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "no_scan".into(),
+ label: "No Scan".into(),
+ field_type: FieldType::Dropdown(options.no_scan_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Make/model
+ EditorField {
+ name: "manufacturer".into(),
+ label: "Manufacturer".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "model".into(),
+ label: "Model".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "serial_number".into(),
+ label: "Serial Number".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ // Status
+ EditorField {
+ name: "status".into(),
+ label: "Status".into(),
+ field_type: FieldType::Dropdown(options.status_options.clone()),
+ required: true,
+ read_only: false,
+ },
+ // Financial / dates
+ EditorField {
+ name: "price".into(),
+ label: "Price".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "purchase_date".into(),
+ label: "Purchase Date".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "warranty_until".into(),
+ label: "Warranty Until".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "expiry_date".into(),
+ label: "Expiry Date".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ // Lendable
+ EditorField {
+ name: "lendable".into(),
+ label: "Lendable".into(),
+ field_type: FieldType::Checkbox,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "lending_status".into(),
+ label: "Lending Status".into(),
+ field_type: FieldType::Dropdown(options.lending_status_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "due_date".into(),
+ label: "Due Date".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ // Supplier
+ EditorField {
+ name: "supplier_id".into(),
+ label: "Supplier".into(),
+ field_type: FieldType::Dropdown(options.supplier_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Quick add supplier
+ EditorField {
+ name: "new_supplier_name".into(),
+ label: "Add Supplier - Name".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ // Label template
+ EditorField {
+ name: "label_template_id".into(),
+ label: "Label Template".into(),
+ field_type: FieldType::Dropdown(options.label_template_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Notes
+ EditorField {
+ name: "notes".into(),
+ label: "Notes".into(),
+ field_type: FieldType::MultilineText,
+ required: false,
+ read_only: false,
+ },
+ // Optional: print on add toggle
+ EditorField {
+ name: "print_label".into(),
+ label: "Print Label".into(),
+ field_type: FieldType::Checkbox,
+ required: false,
+ read_only: false,
+ },
+ // Audit/meta (read-only informational)
+ EditorField {
+ name: "created_date".into(),
+ label: "Created Date".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "created_by_username".into(),
+ label: "Created By".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "last_modified_date".into(),
+ label: "Last Modified".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "last_modified_by_username".into(),
+ label: "Modified By".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ ];
+
+ let mut dialog = FormBuilder::new("Add Asset (Full)", fields);
+
+ // Prefill sensible defaults
+ let mut preset = serde_json::Map::new();
+ preset.insert("asset_type".to_string(), Value::String("N".to_string()));
+ preset.insert("status".to_string(), Value::String("Good".to_string()));
+ preset.insert("lendable".to_string(), Value::Bool(true));
+ preset.insert("print_label".to_string(), Value::Bool(true));
+ dialog.open_new(Some(&preset));
+
+ dialog
+ }
+ /// Create a comprehensive Advanced Edit dialog with all asset fields
+ pub fn create_advanced_edit_dialog(api_client: &ApiClient) -> FormBuilder {
+ let options = AssetDropdownOptions::new(api_client);
+
+ let fields: Vec<EditorField> = vec![
+ // Identifiers (read-only)
+ EditorField {
+ name: "id".into(),
+ label: "ID".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "asset_numeric_id".into(),
+ label: "Numeric ID".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "asset_tag".into(),
+ label: "Asset Tag".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ // Core fields
+ EditorField {
+ name: "asset_type".into(),
+ label: "Type".into(),
+ field_type: FieldType::Dropdown(options.asset_types),
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "name".into(),
+ label: "Name".into(),
+ field_type: FieldType::Text,
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "description".into(),
+ label: "Description".into(),
+ field_type: FieldType::MultilineText,
+ required: false,
+ read_only: false,
+ },
+ // Classification
+ EditorField {
+ name: "category_id".into(),
+ label: "Category".into(),
+ field_type: FieldType::Dropdown(options.category_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Quick add category
+ EditorField {
+ name: "new_category_name".into(),
+ label: "Add Category - Name".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "new_category_code".into(),
+ label: "Add Category - Code".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ // Location
+ EditorField {
+ name: "zone_id".into(),
+ label: "Zone".into(),
+ field_type: FieldType::Dropdown(options.zone_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Quick add zone
+ EditorField {
+ name: "new_zone_parent_id".into(),
+ label: "Add Zone - Parent".into(),
+ field_type: FieldType::Dropdown(options.zone_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "new_zone_mini_code".into(),
+ label: "Add Zone - Mini Code".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "new_zone_name".into(),
+ label: "Add Zone - Name".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "zone_plus".into(),
+ label: "Zone Plus".into(),
+ field_type: FieldType::Dropdown(options.zone_plus_options),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "no_scan".into(),
+ label: "No Scan".into(),
+ field_type: FieldType::Dropdown(options.no_scan_options),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "audit_task_id".into(),
+ label: "Audit Task".into(),
+ field_type: FieldType::Dropdown(options.audit_task_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Make/model
+ EditorField {
+ name: "manufacturer".into(),
+ label: "Manufacturer".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "model".into(),
+ label: "Model".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "serial_number".into(),
+ label: "Serial Number".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ // Status
+ EditorField {
+ name: "status".into(),
+ label: "Status".into(),
+ field_type: FieldType::Dropdown(options.status_options),
+ required: true,
+ read_only: false,
+ },
+ // Financial / dates
+ EditorField {
+ name: "price".into(),
+ label: "Price".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "purchase_date".into(),
+ label: "Purchase Date".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "warranty_until".into(),
+ label: "Warranty Until".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "expiry_date".into(),
+ label: "Expiry Date".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ // Lendable
+ EditorField {
+ name: "lendable".into(),
+ label: "Lendable".into(),
+ field_type: FieldType::Checkbox,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "lending_status".into(),
+ label: "Lending Status".into(),
+ field_type: FieldType::Dropdown(options.lending_status_options),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "due_date".into(),
+ label: "Due Date".into(),
+ field_type: FieldType::Date,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "supplier_id".into(),
+ label: "Supplier".into(),
+ field_type: FieldType::Dropdown(options.supplier_options),
+ required: false,
+ read_only: false,
+ },
+ // Quick add supplier
+ EditorField {
+ name: "new_supplier_name".into(),
+ label: "Add Supplier - Name".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ // Borrowers (read-only historical)
+ EditorField {
+ name: "previous_borrower_id".into(),
+ label: "Prev Borrower".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "current_borrower_id".into(),
+ label: "Current Borrower".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ // Label template selection
+ EditorField {
+ name: "label_template_id".into(),
+ label: "Label Template".into(),
+ field_type: FieldType::Dropdown(options.label_template_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Notes / images
+ EditorField {
+ name: "notes".into(),
+ label: "Notes".into(),
+ field_type: FieldType::MultilineText,
+ required: false,
+ read_only: false,
+ },
+ // Audit/meta (read-only)
+ EditorField {
+ name: "created_date".into(),
+ label: "Created Date".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "created_by_username".into(),
+ label: "Created By".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "last_modified_date".into(),
+ label: "Last Modified".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ EditorField {
+ name: "last_modified_by_username".into(),
+ label: "Modified By".into(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: true,
+ },
+ ];
+
+ FormBuilder::new("Advanced Edit Asset", fields)
+ }
+
+ /// Create an Easy Edit dialog with essential asset fields only
+ pub fn create_easy_edit_dialog(api_client: &ApiClient) -> FormBuilder {
+ let options = AssetDropdownOptions::new(api_client);
+
+ let fields = vec![
+ EditorField {
+ name: "asset_tag".to_string(),
+ label: "Asset Tag".to_string(),
+ field_type: FieldType::Text,
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "asset_type".to_string(),
+ label: "Type".to_string(),
+ field_type: FieldType::Dropdown(options.asset_types),
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "name".to_string(),
+ label: "Name".to_string(),
+ field_type: FieldType::Text,
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "category_id".to_string(),
+ label: "Category".to_string(),
+ field_type: FieldType::Dropdown(options.category_options),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "manufacturer".to_string(),
+ label: "Manufacturer".to_string(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "model".to_string(),
+ label: "Model".to_string(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "zone_id".to_string(),
+ label: "Zone".to_string(),
+ field_type: FieldType::Dropdown(options.zone_options),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "status".to_string(),
+ label: "Status".to_string(),
+ field_type: FieldType::Dropdown(options.status_options),
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "lendable".to_string(),
+ label: "Lendable".to_string(),
+ field_type: FieldType::Checkbox,
+ required: false,
+ read_only: false,
+ },
+ ];
+
+ FormBuilder::new("Easy Edit Asset", fields)
+ }
+
+ /// Create an Add Asset dialog with quick-add functionality for categories/zones/suppliers
+ pub fn create_add_dialog_with_preset(api_client: &ApiClient) -> FormBuilder {
+ let options = AssetDropdownOptions::new(api_client);
+
+ let fields = vec![
+ EditorField {
+ name: "asset_tag".to_string(),
+ label: "Asset Tag".to_string(),
+ field_type: FieldType::Text,
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "asset_type".to_string(),
+ label: "Type".to_string(),
+ field_type: FieldType::Dropdown(options.asset_types),
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "name".to_string(),
+ label: "Name".to_string(),
+ field_type: FieldType::Text,
+ required: true,
+ read_only: false,
+ },
+ // Category dropdown + add-new placeholders
+ EditorField {
+ name: "category_id".to_string(),
+ label: "Category".to_string(),
+ field_type: FieldType::Dropdown(options.category_options),
+ required: false,
+ read_only: false,
+ },
+ // Label template selection
+ EditorField {
+ name: "label_template_id".to_string(),
+ label: "Label Template".to_string(),
+ field_type: FieldType::Dropdown(options.label_template_options.clone()),
+ required: false,
+ read_only: false,
+ },
+ // Print label option
+ EditorField {
+ name: "print_label".to_string(),
+ label: "Print Label".to_string(),
+ field_type: FieldType::Checkbox,
+ required: false,
+ read_only: false,
+ },
+ // Add new category name/code as text fields
+ EditorField {
+ name: "new_category_name".to_string(),
+ label: "Add New Category - Name".to_string(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "new_category_code".to_string(),
+ label: "Add New Category - Code".to_string(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "manufacturer".to_string(),
+ label: "Manufacturer".to_string(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "model".to_string(),
+ label: "Model".to_string(),
+ field_type: FieldType::Text,
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "zone_id".to_string(),
+ label: "Zone".to_string(),
+ field_type: FieldType::Dropdown(options.zone_options),
+ required: false,
+ read_only: false,
+ },
+ EditorField {
+ name: "status".to_string(),
+ label: "Status".to_string(),
+ field_type: FieldType::Dropdown(options.status_options),
+ required: true,
+ read_only: false,
+ },
+ EditorField {
+ name: "lendable".to_string(),
+ label: "Lendable".to_string(),
+ field_type: FieldType::Checkbox,
+ required: false,
+ read_only: false,
+ },
+ ];
+
+ let mut dialog = FormBuilder::new("Add Asset", fields);
+
+ // Open with sensible defaults
+ let mut preset = serde_json::Map::new();
+ preset.insert("asset_type".to_string(), Value::String("N".to_string()));
+ preset.insert("status".to_string(), Value::String("Good".to_string()));
+ preset.insert("lendable".to_string(), Value::Bool(true));
+ // Default to printing a label after adding when possible
+ preset.insert("print_label".to_string(), Value::Bool(true));
+
+ dialog.open_new(Some(&preset));
+ dialog
+ }
+
+ /// Get the list of fields that are allowed to be updated via API
+ #[allow(dead_code)]
+ pub fn get_allowed_update_fields() -> Vec<String> {
+ vec![
+ "asset_tag".to_string(),
+ "asset_type".to_string(),
+ "name".to_string(),
+ "description".to_string(),
+ "category_id".to_string(),
+ "zone_id".to_string(),
+ "zone_plus".to_string(),
+ "no_scan".to_string(),
+ "manufacturer".to_string(),
+ "model".to_string(),
+ "serial_number".to_string(),
+ "status".to_string(),
+ "price".to_string(),
+ "purchase_date".to_string(),
+ "warranty_until".to_string(),
+ "expiry_date".to_string(),
+ "lendable".to_string(),
+ "lending_status".to_string(),
+ "due_date".to_string(),
+ "supplier_id".to_string(),
+ "notes".to_string(),
+ "label_template_id".to_string(),
+ ]
+ }
+}