validation1 for the form

This commit is contained in:
Priec
2025-09-12 21:25:49 +02:00
parent 9672b9949c
commit cec2361b00
10 changed files with 623 additions and 2 deletions

View File

@@ -1,6 +1,10 @@
// src/pages/forms/state.rs
use canvas::{DataProvider, AppMode};
#[cfg(feature = "validation")]
use canvas::{CharacterLimits, ValidationConfig, ValidationConfigBuilder};
#[cfg(feature = "validation")]
use canvas::validation::limits::CountMode;
use common::proto::komp_ac::search::search_response::Hit;
use std::collections::HashMap;
@@ -39,6 +43,18 @@ pub struct FormState {
pub autocomplete_loading: bool,
pub link_display_map: HashMap<usize, String>,
pub app_mode: AppMode,
// Validation 1 (character limits) per field. None = no validation for that field.
// Leave room for future rules (patterns, masks, etc.).
pub char_limits: Vec<Option<CharLimitsRule>>,
}
#[cfg(feature = "validation")]
#[derive(Debug, Clone)]
pub struct CharLimitsRule {
pub min: Option<usize>,
pub max: Option<usize>,
pub warn_at: Option<usize>,
pub count_mode: CountMode,
}
impl FormState {
@@ -56,6 +72,7 @@ impl FormState {
fields: Vec<FieldDefinition>,
) -> Self {
let values = vec![String::new(); fields.len()];
let len = values.len();
FormState {
id: 0,
profile_name,
@@ -73,6 +90,7 @@ impl FormState {
autocomplete_loading: false,
link_display_map: HashMap::new(),
app_mode: canvas::AppMode::Edit,
char_limits: vec![None; len],
}
}
@@ -256,6 +274,24 @@ impl FormState {
pub fn set_current_cursor_pos(&mut self, pos: usize) {
self.current_cursor_pos = pos;
}
#[cfg(feature = "validation")]
pub fn set_character_limits_rules(
&mut self,
rules: Vec<Option<CharLimitsRule>>,
) {
if rules.len() == self.fields.len() {
self.char_limits = rules;
} else {
tracing::warn!(
"Character limits count {} != field count {} for {}.{}",
rules.len(),
self.fields.len(),
self.profile_name,
self.table_name
);
}
}
}
// Step 2: Implement DataProvider for FormState
@@ -282,4 +318,26 @@ impl DataProvider for FormState {
fn supports_suggestions(&self, field_index: usize) -> bool {
self.fields.get(field_index).map(|f| f.is_link).unwrap_or(false)
}
// Validation 1: Provide character-limit-based validation to canvas
// Only compiled when the "validation" feature is enabled on canvas.
#[cfg(feature = "validation")]
fn validation_config(&self, index: usize) -> Option<ValidationConfig> {
let rule = self.char_limits.get(index)?.as_ref()?;
let mut limits = match (rule.min, rule.max) {
(Some(min), Some(max)) => CharacterLimits::new_range(min, max),
(None, Some(max)) => CharacterLimits::new(max),
(Some(min), None) => CharacterLimits::new_range(min, usize::MAX),
(None, None) => CharacterLimits::new(usize::MAX),
};
limits = limits.with_count_mode(rule.count_mode);
if let Some(warn) = rule.warn_at {
limits = limits.with_warning_threshold(warn);
}
Some(
ValidationConfigBuilder::new()
.with_character_limits(limits)
.build(),
)
}
}