From 3d9c28f7f7433014cc05d75705f7d7513911f98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20Pe=CC=81rez?= Date: Sun, 28 Dec 2025 19:46:54 +0000 Subject: [PATCH] chore: update backends output for config files changes --- .../typedialog-core/src/backends/web/mod.rs | 164 +++++++++++++++++- crates/typedialog-core/src/nickel/summary.rs | 46 +++-- 2 files changed, 179 insertions(+), 31 deletions(-) diff --git a/crates/typedialog-core/src/backends/web/mod.rs b/crates/typedialog-core/src/backends/web/mod.rs index 515817f..35b03f8 100644 --- a/crates/typedialog-core/src/backends/web/mod.rs +++ b/crates/typedialog-core/src/backends/web/mod.rs @@ -927,6 +927,159 @@ async fn submit_field_handler( (StatusCode::OK, headers, Json(json!({"success": true}))) } +/// Render success HTML for normal (non-roundtrip) mode +#[cfg(feature = "web")] +fn render_success_html(results: &HashMap) -> String { + let field_count = results.len(); + + let fields_html = if field_count > 0 { + let mut html = String::from("
"); + html.push_str("

📋 Form Results:

"); + html.push_str("
"); + + let mut sorted_fields: Vec<_> = results.iter().collect(); + sorted_fields.sort_by_key(|(k, _)| k.as_str()); + + for (field_name, value) in sorted_fields { + let value_str = match value { + Value::String(s) => s.clone(), + Value::Number(n) => n.to_string(), + Value::Bool(b) => b.to_string(), + Value::Array(arr) => { + let items: Vec = arr + .iter() + .map(|v| match v { + Value::String(s) => s.clone(), + other => other.to_string(), + }) + .collect(); + format!("[{}]", items.join(", ")) + } + Value::Null => "(empty)".to_string(), + Value::Object(_) => "{...}".to_string(), + }; + + html.push_str(&format!( + r#"
+
{}
+
{}
+
"#, + html_escape(field_name), + html_escape(&value_str) + )); + } + + html.push_str("
"); + html + } else { + String::from("

No fields submitted

") + }; + + format!( + r#" + + + Form Submitted Successfully + + + + + +
+
+

✅ Form Submitted Successfully!

+
+ +
+ 📊 Fields Submitted: + {} fields +
+ + {} + +
+ + +
+ +
+ ⏱️ This window will auto-close in 30 seconds... +
+
+ +"#, + field_count, fields_html + ) +} + #[cfg(feature = "web")] async fn submit_complete_form_handler( State(state): State>, @@ -995,17 +1148,16 @@ async fn submit_complete_form_handler( .body(Body::from(html)) .unwrap() } else { - // Normal mode: return JSON success + // Normal mode: return HTML success page use axum::body::Body; use axum::response::Response; + let html = render_success_html(&all_results); + Response::builder() .status(StatusCode::OK) - .header("Content-Type", "application/json") - .header("HX-Trigger", "formComplete") - .body(Body::from( - serde_json::to_string(&json!({"success": true})).unwrap(), - )) + .header("Content-Type", "text/html; charset=utf-8") + .body(Body::from(html)) .unwrap() } } diff --git a/crates/typedialog-core/src/nickel/summary.rs b/crates/typedialog-core/src/nickel/summary.rs index 788e4a6..ccb74cc 100644 --- a/crates/typedialog-core/src/nickel/summary.rs +++ b/crates/typedialog-core/src/nickel/summary.rs @@ -96,28 +96,25 @@ impl RoundtripSummary { output.push('\n'); output.push_str("╔════════════════════════════════════════════════════════════╗\n"); - output.push_str("║ ✅ Configuration Saved Successfully! ║\n"); - output.push_str("╠════════════════════════════════════════════════════════════╣\n"); - output.push_str(&format!( - "║ 📄 File: {:<48} ║\n", - truncate(&self.output_path, 48) - )); + output.push_str(" ✅ Configuration Saved Successfully!\n"); + output.push_str("════════════════════════════════════════════════════════════\n"); + output.push_str(&format!(" 📄 File: {}\n", self.output_path)); if let Some(passed) = self.validation_passed { let status = if passed { "✓ PASSED" } else { "✗ FAILED" }; - output.push_str(&format!("║ ✓ Validation: {:<43} ║\n", status)); + output.push_str(&format!(" ✓ Validation: {}\n", status)); } output.push_str(&format!( - "║ 📊 Fields: {}/{} changed, {} unchanged{:<18} ║\n", - self.changed_fields, self.total_fields, self.unchanged_fields, "" + " 📊 Fields: {}/{} changed, {} unchanged\n", + self.changed_fields, self.total_fields, self.unchanged_fields )); - output.push_str("╠════════════════════════════════════════════════════════════╣\n"); + output.push_str("════════════════════════════════════════════════════════════\n"); // Show changes if self.changed_fields > 0 { - output.push_str("║ 📋 What Changed: ║\n"); + output.push_str(" 📋 What Changed:\n"); let mut shown = 0; for change in &self.changes { @@ -128,30 +125,29 @@ impl RoundtripSummary { if !verbose && shown >= 10 { let remaining = self.changed_fields - shown; output.push_str(&format!( - "║ ... and {} more changes (use --verbose to see all){:<4} ║\n", - remaining, "" + " ... and {} more changes (use --verbose to see all)\n", + remaining )); break; } - let line = format!( - " ├─ {}: {} → {}", + output.push_str(&format!( + " ├─ {}: {} → {}\n", change.field_name, - truncate(&change.old_value, 15), - truncate(&change.new_value, 15) - ); - output.push_str(&format!("║ {:<58} ║\n", truncate(&line, 58))); + truncate(&change.old_value, 20), + truncate(&change.new_value, 20) + )); shown += 1; } } else { - output.push_str("║ 📋 No changes made ║\n"); + output.push_str(" 📋 No changes made\n"); } - output.push_str("╠════════════════════════════════════════════════════════════╣\n"); - output.push_str("║ 💡 Next Steps: ║\n"); - output.push_str("║ • Review: cat config.ncl ║\n"); - output.push_str("║ • Apply CI tools: ./setup-ci.sh ║\n"); - output.push_str("║ • Re-configure: ./ci-configure.sh ║\n"); + output.push_str("════════════════════════════════════════════════════════════\n"); + output.push_str(" 💡 Next Steps:\n"); + output.push_str(" • Review: cat config.ncl\n"); + output.push_str(" • Apply CI tools: ./setup-ci.sh\n"); + output.push_str(" • Re-configure: ./ci-configure.sh\n"); output.push_str("╚════════════════════════════════════════════════════════════╝\n"); output.push('\n');