Skip to content

Form System Refactoring Plan

Overview

This document outlines a comprehensive refactoring plan for the form system in both Application-Frontend and Creative-Engine. The goal is to improve maintainability, reduce code duplication, and enhance type safety by creating dedicated components for each input type.

Current Architecture Analysis

Current Structure

  • Single Component: FormInputConfiguration.vue handles all input types (331 lines)
  • Template Conditionals: Uses v-if statements to show type-specific validation sections
  • Mixed Concerns: Combines common styling, layout, and type-specific validation in one file
  • Centralized Logic: All input type handling in one component with complex conditional rendering

Issues Identified

  1. Large Component Size: 331 lines with growing complexity
  2. Template Complexity: Multiple nested v-if conditions for different input types
  3. Maintenance Overhead: Adding new input types requires modifying the main component
  4. Code Duplication: Similar validation patterns repeated across input types
  5. Testing Complexity: Difficult to test individual input type configurations in isolation

Refactoring Strategy

Component Architecture

FormInputConfiguration.vue (Main Container)
├── BaseInputConfiguration.vue (Shared functionality)
├── TextInputConfiguration.vue (Text-specific validation)
├── NumberInputConfiguration.vue (Number-specific validation)
├── DateInputConfiguration.vue (Date-specific validation)
├── EmailInputConfiguration.vue (Email-specific validation)
├── SelectInputConfiguration.vue (Select/dropdown-specific)
└── CheckboxInputConfiguration.vue (Checkbox-specific)

Shared vs Specific Functionality

BaseInputConfiguration (Shared)

  • Basic Properties: Label, placeholder, display name
  • Styling Sections: Background, border, border radius, layout
  • Font Settings: Label font and input font configuration
  • Common Layout: Flex alignment, position, padding, size
  • Mixins: Configuration logic mixin integration

Type-Specific Components

  • Validation Rules: Input type-specific validation fields
  • Custom Properties: Type-specific configuration options
  • Specialized UI: Input type-specific interface elements

Implementation Plan

Phase 1: Foundation Components

1.1 Create Validation Helpers

File: src/pages/Chatbots/components/BuilderVisuals/Configuration/helpers/validationHelpers.ts

typescript
// Validation helper functions
export const validateTextInput = (value: string, rules: TextValidationRules) => { ... }
export const validateNumberInput = (value: number, rules: NumberValidationRules) => { ... }
export const validateDateInput = (value: string, rules: DateValidationRules) => { ... }

// Prop validators
export const textValidationProps = { ... }
export const numberValidationProps = { ... }
export const dateValidationProps = { ... }

1.2 Create BaseInputConfiguration Component

File: src/pages/Chatbots/components/BuilderVisuals/Configuration/components/form/BaseInputConfiguration.vue

Responsibilities:

  • Common input properties (label, placeholder)
  • Shared styling sections (background, border, layout)
  • Font settings for both label and input
  • Base template structure with slots for type-specific content

Props:

typescript
interface BaseInputProps {
  blockData: FormInputBlock;
  path: string;
}

Slots:

  • validation-section: For type-specific validation UI
  • additional-properties: For type-specific additional properties

Phase 2: Type-Specific Components

2.1 TextInputConfiguration Component

File: src/pages/Chatbots/components/BuilderVisuals/Configuration/components/form/TextInputConfiguration.vue

Validation Fields:

  • minLength: Minimum character length
  • maxLength: Maximum character length
  • pattern: Regular expression pattern
  • customErrorMessage: Custom validation error message

2.2 NumberInputConfiguration Component

File: src/pages/Chatbots/components/BuilderVisuals/Configuration/components/form/NumberInputConfiguration.vue

Validation Fields:

  • min: Minimum numeric value
  • max: Maximum numeric value
  • step: Numeric step increment
  • customErrorMessage: Custom validation error message

2.3 DateInputConfiguration Component

File: src/pages/Chatbots/components/BuilderVisuals/Configuration/components/form/DateInputConfiguration.vue

Validation Fields:

  • min: Minimum date (using date input)
  • max: Maximum date (using date input)
  • customErrorMessage: Custom validation error message

Phase 3: Integration and Testing

3.1 Update Main FormInputConfiguration

Approach: Use dynamic component loading based on input type

vue
<template>
  <component
    :is="inputConfigurationComponent"
    :block-data="blockData"
    :path="path"
    v-bind="$attrs"
    v-on="$listeners"
  />
</template>

<script>
computed: {
  inputConfigurationComponent() {
    const type = this.blockData.type || 'text'
    const componentMap = {
      'text': 'TextInputConfiguration',
      'textarea': 'TextInputConfiguration',
      'number': 'NumberInputConfiguration',
      'date': 'DateInputConfiguration',
      'email': 'TextInputConfiguration', // Uses text validation with email pattern
      // ... other mappings
    }
    return componentMap[type] || 'TextInputConfiguration'
  }
}
</script>

3.2 Component Registration

Update component imports and registration in the main configuration file.

Benefits of This Approach

Maintainability

  • Separation of Concerns: Each component handles only its specific input type
  • Smaller Components: Easier to understand and modify individual components
  • Focused Testing: Each component can be tested in isolation

Extensibility

  • Easy Addition: New input types require only creating a new component
  • Type Safety: Better prop validation and TypeScript support
  • Reusability: Components can be reused in other contexts

Code Quality

  • Reduced Duplication: Shared functionality extracted to base component
  • Clear Structure: Explicit component hierarchy and responsibilities
  • Better Documentation: Each component can have focused documentation

Migration Strategy

Incremental Implementation

  1. Start with TextInputConfiguration: Most common and straightforward
  2. Test Thoroughly: Ensure functionality matches current behavior
  3. Implement NumberInputConfiguration: Second most common type
  4. Continue with Remaining Types: Date, email, select, checkbox
  5. Update Main Component: Switch to dynamic component loading
  6. Remove Old Code: Clean up conditional rendering from main component

Backward Compatibility

  • Maintain existing prop interfaces during transition
  • Ensure all existing functionality is preserved
  • Test with existing form configurations

Testing Strategy

  • Unit Tests: Test each new component individually
  • Integration Tests: Test dynamic component loading
  • Visual Regression Tests: Ensure UI remains consistent
  • Functional Tests: Verify form validation still works correctly

File Structure After Refactoring

src/pages/Chatbots/components/BuilderVisuals/Configuration/
├── components/
│   └── form/
│       ├── BaseInputConfiguration.vue
│       ├── TextInputConfiguration.vue
│       ├── NumberInputConfiguration.vue
│       ├── DateInputConfiguration.vue
│       ├── EmailInputConfiguration.vue
│       ├── SelectInputConfiguration.vue
│       └── CheckboxInputConfiguration.vue
├── helpers/
│   └── validationHelpers.ts
└── configs/
    └── FormInputConfiguration.vue (Updated main component)

Success Criteria

  1. Functionality Preservation: All existing form input configurations work identically
  2. Code Reduction: Main FormInputConfiguration.vue reduced by ~60% in size
  3. Component Isolation: Each input type component can be developed/tested independently
  4. Type Safety: Improved prop validation and TypeScript support
  5. Documentation: Clear documentation for each component's purpose and usage
  6. Performance: No performance regression in form configuration rendering

Next Steps for Application-Frontend

  1. Create validation helpers and prop validators
  2. Implement BaseInputConfiguration component
  3. Create TextInputConfiguration component and test thoroughly
  4. Implement remaining type-specific components incrementally
  5. Update main FormInputConfiguration to use dynamic components
  6. Comprehensive testing and documentation updates

Creative-Engine Modularization Plan

Current Issues in Creative-Engine

  • Large Component: CreativeFormBlock.vue is over 600 lines with growing complexity
  • Mixed Rendering Logic: All input types rendered in a single component with many conditionals
  • Styling Complexity: Style generation for all input types in one computed property
  • Limited Testability: Difficult to test individual input rendering in isolation
  • Maintenance Challenges: Adding new input types requires modifying multiple sections

Proposed Architecture

CreativeFormBlock.vue (Main Container)
├── FormInputBase.vue (Shared input functionality)
├── inputs/
│   ├── TextInput.vue (Text input rendering)
│   ├── TextareaInput.vue (Textarea input rendering)
│   ├── SelectInput.vue (Dropdown input rendering)
│   ├── PhoneInput.vue (Phone input with country code)
│   ├── DateInput.vue (Date input rendering)
│   └── NumberInput.vue (Number input rendering)
└── FormSubmitButton.vue (Submit button component)

Implementation Strategy

Phase 1: Extract Shared Logic

  1. Create a utils/formInputUtils.ts file for shared form input utilities:

    • Input validation helpers
    • Style generation functions
    • Class name generation
  2. Create a mixins/FormInputMixin.ts with shared input functionality:

    • Common props and computed properties
    • Event handling for input changes
    • Validation state management

Phase 2: Component Extraction

  1. Create FormInputBase.vue as the base component for all inputs:

    • Common wrapper structure
    • Label rendering
    • Error message display
    • Style application
  2. Extract each input type to its own component:

    • inputs/TextInput.vue
    • inputs/TextareaInput.vue
    • inputs/SelectInput.vue
    • inputs/PhoneInput.vue
    • inputs/DateInput.vue
    • inputs/NumberInput.vue
  3. Update CreativeFormBlock.vue to use dynamic components:

vue
<component
  :is="getInputComponent(input.type)"
  :input="input"
  :index="index"
  :form-store="formStore"
  @update="handleInputUpdate"
/>

Phase 3: Style System Improvements

  1. Modularize style generation:

    • Base styles in FormInputBase.vue
    • Type-specific styles in each input component
    • Common style utilities in a shared module
  2. Improve CSS class naming consistency:

    • Use BEM methodology for component classes
    • Maintain backward compatibility with existing selectors

Benefits

  • Improved Maintainability: Each input type in its own file
  • Better Organization: Clear separation of concerns
  • Enhanced Testability: Components can be tested in isolation
  • Easier Extensions: Adding new input types requires minimal changes
  • Reduced Complexity: Smaller, focused components
  • Better Performance: Potential for optimized rendering

Migration Approach

  1. Start with extracting utility functions and mixins
  2. Create the base input component
  3. Extract one input type at a time, starting with text input
  4. Test thoroughly after each extraction
  5. Update the main component to use dynamic components
  6. Refine the style system
  7. Add comprehensive documentation

This modularization will significantly improve the maintainability and extensibility of the form system in Creative-Engine while preserving all existing functionality.

Internal documentation