Skip to content

Latest commit

 

History

History
304 lines (240 loc) · 8.67 KB

File metadata and controls

304 lines (240 loc) · 8.67 KB

Multiple Document Upload Implementation

Overview

This implementation extends the existing document upload functionality to support multiple document uploads within a single widget, similar to the IR (Image Recognition) components. The new system allows users to upload multiple documents, images, and camera captures in the same widget while maintaining backward compatibility with existing code.

Key Features

1. Multiple File Support

  • Upload multiple documents in a single widget
  • Support for documents (PDF, DOC, DOCX) and images (JPG, PNG, HEIC, HEIF)
  • Camera capture functionality
  • Gallery selection
  • Configurable maximum file limits

2. Enhanced UI

  • Horizontal scrolling list of uploaded documents
  • Individual file preview with icons
  • Remove functionality for each file
  • File count indicators
  • Modern modal bottom sheet picker

3. Data Structure Changes

  • Before: Single blobKey string
  • After: Array of blobKey strings (List<String>)
  • Backward compatibility maintained via DocumentUploadSingle

Modified Files

1. lib/common/widgets/document_upload.dart

  • New: UploadedDocument model class
  • Modified: DocumentUpload widget to handle multiple files
  • Added: DocumentUploadSingle for backward compatibility

2. lib/sfa/features/outlet_mapping/widgets/outlet_mapping_document.dart

  • Updated: To work with new multiple document structure
  • Changed: From single blobKey to List<String> blobKeys
  • Enhanced: Better handling of document types

3. lib/sfa/features/outlet_mapping/providers/outlet_mapping_provider.dart

  • Added: updateMultipleDocumentField() method
  • Added: updateOutletMappingDetailsWithArray() method
  • Enhanced: Support for array storage in extendedAttributes

4. lib/common/widgets/document_upload_example.dart (New)

  • Created: Usage examples and integration guide

Usage Examples

Basic Multiple Document Upload

DocumentUpload(
  fieldDetails: FormFields(
    widgetId: 'documents',
    label: 'Upload Documents',
    enabled: true,
    extAttrKey: 'documents',
    type: 'document',
  ),
  widgetId: 'documents',
  maxFiles: 5, // Allow up to 5 files
  allowMultiple: true,
  onFilesSelected: (blobKeys) {
    // Handle array of blobKeys
    print('Uploaded documents: $blobKeys');
    // Store in outlet payload as array
    outletPayload.extendedAttributes['documents'] = blobKeys;
  },
)

Outlet Mapping Integration

// In OutletMappingDocument widget
DocumentUpload(
  fieldDetails: widget.fieldDetails,
  existingBlobKeys: currentBlobKeys, // List<String>
  widgetId: widget.fieldDetails.widgetId,
  maxFiles: 5,
  allowMultiple: true,
  onFilesSelected: (blobKeys) {
    // Update outlet payload with array
    outletMappingProvider.outletPayload.extendedAttributes[widgetId] = blobKeys;
    outletMappingProvider.notifyListeners();
  },
)

Backward Compatibility

// For existing code that expects single blobKey
DocumentUploadSingle(
  fieldDetails: fieldDetails,
  existingBlobKey: singleBlobKey, // String?
  onFileSelected: (blobKey) {
    // Handle single blobKey as before
    print('Single document: $blobKey');
  },
)

Data Flow

1. File Selection Process

User taps upload area
    ↓
Modal bottom sheet shows options
    ↓
User selects Camera/Gallery/Documents
    ↓
Files are processed and uploaded
    ↓
BlobKeys are generated
    ↓
UploadedDocument objects created
    ↓
UI updates with file previews
    ↓
Parent callback fired with blobKey array

2. Storage in Outlet Payload

// Regular documents (DNI, CUITCertificate, etc.)
outletPayload.extendedAttributes['DNI'] = ['blobKey1', 'blobKey2', 'blobKey3'];

// Additional documents (contractRental, propertyTax, etc.)
outletPayload.extendedAttributes['additionaldocumentation'] = {
  'contractRental': ['blobKey1', 'blobKey2'],
  'propertyTax': ['blobKey3'],
  'utilityBill': ['blobKey4', 'blobKey5']
};

Configuration Options

DocumentUpload Widget Parameters

Parameter Type Default Description
maxFiles int 10 Maximum number of files allowed
allowMultiple bool true Whether multiple files are allowed
existingBlobKeys List<String>? null Previously uploaded blobKeys
onFilesSelected Function(List<String>) - Callback with selected blobKeys
dontProvideGallery bool false Hide gallery option

Supported File Types

  • Documents: PDF, DOC, DOCX
  • Images: JPG, JPEG, PNG, HEIC, HEIF
  • Camera: Direct photo capture

Migration Guide

For Existing Document Upload Usage

  1. Option 1: Use DocumentUploadSingle (no changes required)
  2. Option 2: Migrate to new DocumentUpload with array handling

Migration Steps

// Before
DocumentUpload(
  existingBlobKey: singleBlobKey,        // String?
  onFileSelected: (blobKey) { ... },     // Single value
)

// After - Option 1 (Backward Compatible)
DocumentUploadSingle(
  existingBlobKey: singleBlobKey,        // String?
  onFileSelected: (blobKey) { ... },     // Single value
)

// After - Option 2 (New Multiple Support)
DocumentUpload(
  existingBlobKeys: blobKeys,            // List<String>?
  onFilesSelected: (blobKeys) { ... },   // Array value
  maxFiles: 5,                           // Configure limit
)

Outlet Payload Changes

// Before
outletPayload.extendedAttributes['document'] = 'single_blob_key';

// After
outletPayload.extendedAttributes['document'] = ['blob_key_1', 'blob_key_2'];

// Access first document (backward compatibility)
String? firstDoc = (outletPayload.extendedAttributes['document'] as List?)?.first;

Technical Implementation Details

UploadedDocument Model

class UploadedDocument {
  final String id;          // Unique identifier
  final String name;        // File name
  final String path;        // Local file path
  final String extension;   // File extension
  final String blobKey;     // Server blob key
  final DateTime uploadTime; // Upload timestamp
  final String type;        // 'image' or 'document'
}

UI Components

  1. Upload Trigger: Main upload area with file count indicator
  2. Document List: Horizontal scrollable list of uploaded files
  3. Document Cards: Individual file previews with remove buttons
  4. Modal Picker: Bottom sheet with camera/gallery/document options

Error Handling

  • File validation for supported formats
  • Size limit checks
  • Upload failure handling
  • Network timeout handling
  • Visual error feedback to users

Testing

Manual Testing Scenarios

  1. Multiple Document Upload

    • Upload multiple PDF files
    • Upload mixed file types (PDF + images)
    • Verify file count limits
    • Test remove functionality
  2. Camera Integration

    • Capture photos from camera
    • Mix camera photos with documents
    • Verify image processing
  3. Backward Compatibility

    • Test DocumentUploadSingle with existing code
    • Verify single file limitation
    • Ensure callback compatibility
  4. Edge Cases

    • Network failures during upload
    • Large file uploads
    • Maximum file limit reached
    • Empty state handling

Benefits

1. User Experience

  • Upload multiple documents at once
  • Visual feedback for each file
  • Easy file management with remove options
  • Familiar UI patterns from IR components

2. Developer Experience

  • Clean API design
  • Backward compatibility
  • Comprehensive error handling
  • Flexible configuration options

3. Data Management

  • Structured storage in arrays
  • Easy iteration over multiple files
  • Simplified server-side processing
  • Better data organization

Future Enhancements

  1. File Preview: Image thumbnails and document previews
  2. Drag & Drop: Desktop/web drag and drop support
  3. Progress Indicators: Upload progress for large files
  4. Cloud Integration: Direct cloud storage uploads
  5. File Compression: Automatic image/document compression
  6. Batch Operations: Select/deselect all functionality

Troubleshooting

Common Issues

  1. Files not appearing: Check maxFiles limit and allowMultiple setting
  2. Callback not firing: Ensure onFilesSelected is properly set
  3. UI not updating: Verify setState() is called in callback
  4. Storage issues: Check extendedAttributes structure in outlet payload

Debug Tips

  • Enable logging to see blobKey arrays
  • Use Flutter Inspector to verify widget tree
  • Check network requests for upload failures
  • Validate file permissions on device

This implementation provides a robust, scalable solution for multiple document uploads while maintaining compatibility with existing systems.