Overview

The Questionnaire Create/Edit V2 module in @admin-lite represents a significant evolution of the questionnaire creation interface. Built with modern React patterns and TypeScript, it maintains full compatibility with existing question types while introducing substantial improvements in user experience, performance, and developer maintainability.

For detailed information about question types and core concepts, please refer to Questionnaire Create Admin Frontend and question-types.

Key Improvements from V1

  • Tabbed Interface: Organized workflow with Editor, Preview, Usage, and Settings tabs
  • Live Preview: Real-time preview of the questionnaire as you build
  • Enhanced Drag & Drop: Smooth reordering of questions and categories
  • Modern Assignment UI: Intuitive three-tier assignment configuration
  • TypeScript: Full type safety and better developer experience
  • Performance: Optimized rendering and state management

Architecture

Component Structure

questionnaire-editor/
├── editor-form.tsx              # Main form orchestration
├── category-manager.tsx         # Category CRUD operations
├── conditional-questions.tsx    # Conditional logic handler
├── assignment-modal.tsx         # Assignment configuration
├── live-question-preview.tsx    # Real-time preview
├── live-title-preview.tsx       # Title preview
└── category-attributes-modal.tsx # Category settings

State Management

The V2 editor uses local React state with controlled components, eliminating the Redux dependency:

// V2: Simple state management
const [questionnaire, setQuestionnaire] = useState<QuestionnaireEntity>({
  title: '',
  departments: [],
  categories: []
});
 
// V1: Complex Redux setup
dispatch(updateQuestionnaireField({ field: 'title', value }));

New Features in V2

1. Tabbed Interface

The new tabbed layout provides better organization and workflow:

Editor Tab

  • Main questionnaire configuration
  • Question and category management
  • Drag-and-drop interface

Preview Tab

  • Real-time preview of the questionnaire
  • Mobile and desktop view toggle
  • Interactive preview for testing flows

Usage Tab

The Usage tab provides comprehensive visibility into questionnaire deployment:

Key Information Displayed:

  • Sites Using Questionnaire: List of all sites where the questionnaire is scheduled
  • Schedule Count: Number of active schedules per site
  • Usage Summary: Total sites and schedules using the questionnaire

Features:

  • Dual View Modes: Toggle between list (table) and card view
  • Quick Navigation: Click any site to navigate directly to site details
  • Real-time Data: Shows current deployment status across the organization
  • Impact Assessment: Understand the scope before making changes

Purpose:

  • Visibility into questionnaire adoption
  • Impact analysis for proposed changes
  • Quick access to related sites
  • Usage metrics at a glance

Settings Tab

  • Advanced configuration options
  • Scoring settings (when enabled)
  • Publishing controls

2. Live Preview System

Real-time preview updates as you type:

// Preview component updates automatically
<LiveQuestionPreview
  question={currentQuestion}
  onChange={handleQuestionChange}
/>

Features:

  • Instant Updates: See changes immediately
  • Mobile View: Preview how it appears on mobile devices
  • Interactive Elements: Test conditional logic in preview
  • Accurate Representation: Exact match to mobile app rendering

3. Enhanced Drag & Drop

Improved drag-and-drop functionality using @dnd-kit:

// Smooth drag operations with visual feedback
<SortableContext items={categories}>
  {categories.map((category) => (
    <SortableCategory key={category.id} category={category}>
      <SortableContext items={category.questions}>
        {category.questions.map((question) => (
          <SortableQuestion key={question.id} question={question} />
        ))}
      </SortableContext>
    </SortableCategory>
  ))}
</SortableContext>

Features:

  • Visual Feedback: Clear indicators during drag
  • Auto-scroll: Automatic scrolling when dragging
  • Touch Support: Works on touch devices
  • Nested Sorting: Sort within categories

4. Modern Assignment Modal

Completely redesigned assignment interface:

interface AssignmentConfig {
  type: 'SPECIFIC_USER' | 'SCHEDULE_DEPT' | 'SPECIFIC_DEPT_USER_SITE';
  level: 'questionnaire' | 'category' | 'question';
  configuration: {
    departmentId?: string;
    userId?: string;
    siteId?: string;
    hierarchyLevel?: number;
  };
}

Features:

  • Three-tier Hierarchy: Questionnaire, category, and question levels
  • Visual Flow: Department → Level → User selection
  • Member Management: Add/remove assignment members
  • Validation: Real-time validation of assignments

5. Improved Conditional Questions

Enhanced conditional question handling:

// Simplified conditional configuration
<ConditionalQuestions
  parentQuestion={question}
  onConditionAdd={(condition, childQuestion) => {
    // Add conditional question
  }}
  onConditionRemove={(conditionId) => {
    // Remove conditional question
  }}
/>

Improvements:

  • Visual Indicators: Clear parent-child relationships
  • Multiple Conditions: Support for complex logic
  • Drag Support: Reorder within conditional groups
  • Validation: Ensures logical consistency

6. Category Attributes (New)

Advanced category configuration:

<CategoryAttributesModal
  category={category}
  onSave={(attributes) => {
    // Save category-specific settings
  }}
/>

Question Type Support

All existing question types are supported with enhanced configuration UI. For detailed question type documentation, see question-types.

Enhanced Question Configuration

Each question type now has:

  • Live Preview: See the question as users will
  • Inline Help: Contextual guidance
  • Validation Feedback: Real-time validation
  • Quick Actions: Common operations readily accessible

Developer Experience Improvements

1. TypeScript Throughout

Full type safety for all components:

interface QuestionEntity {
  id: string;
  type: QuestionType;
  content: string;
  required: boolean;
  category: string;
  categoryId: string;
  // ... fully typed properties
}

2. Modular Architecture

Clean separation of concerns:

// Services handle business logic
const questionnaireService = {
  create: async (data: CreateQuestionnaireDto) => {
    const transformed = QuestionnairePayloadTransformer.toPublishDto(data);
    return await questionnaireRepository.create(transformed);
  }
};
 
// Components focus on UI
function QuestionnaireEditor() {
  const createMutation = useMutation({
    mutationFn: questionnaireService.create
  });
  // UI implementation
}

3. Better Testing

Improved testability with:

  • Pure functions for business logic
  • Isolated component testing
  • Mock service layer
  • Comprehensive test coverage

API Compatibility

The V2 editor maintains full compatibility with existing APIs:

Create/Update Payload

// Same API structure as V1
POST /v1.0/questionnaires/
{
  title: string,
  departmentIDs: string[],
  questions: TransformedQuestion[],
  // ... same payload structure
}

Payload Transformation

The QuestionnairePayloadTransformer ensures compatibility:

// Transforms modern UI state to legacy API format
const payload = QuestionnairePayloadTransformer.toPublishDto(questionnaire);

Migration Guide

For Developers

  1. Component Migration

    • Replace class components with functional components
    • Use React Query instead of Redux for data fetching
    • Adopt TypeScript for new code
  2. State Management

    • Remove Redux boilerplate
    • Use local state for form data
    • Leverage React Query for server state
  3. Testing Updates

    • Update tests to use React Testing Library
    • Remove Redux test utilities
    • Focus on user interaction testing

For Users

The V2 editor maintains familiar workflows while improving the experience:

  • Same question types and configuration options
  • Enhanced visual feedback and performance
  • New features like live preview and better assignments
  • No retraining required for existing users

Performance Optimizations

Code Splitting

// Heavy components loaded on demand
const QuestionnaireEditor = dynamic(
  () => import('./_components/questionnaire-editor'),
  { loading: () => <EditorSkeleton /> }
);

Memoization

// Expensive computations cached
const validationErrors = useMemo(() => 
  validateQuestionnaire(questionnaire),
  [questionnaire]
);

Debounced Updates

// Reduced re-renders during typing
const debouncedTitle = useDebounce(title, 300);

Core System

V2 Documentation

Implementation

  • @admin-lite Repository - Full implementation
  • API Documentation - Backend integration
  • Migration Guide - Detailed migration steps