@ -123,74 +123,222 @@
< script lang = "ts" >
/ * *
* @ file Contact Import View Component
* @ author Matthew Raymer
* ContactImportView - Contact Import and Batch Processing Page
*
* This component handles the batch import of contacts with comprehensive
* validation , duplicate detection , and field comparison capabilities .
* It provides users with detailed information about each contact before
* importing , allowing them to make informed decisions about their contact list .
*
* # # How the Contact Import Page Works
*
* # # # Page Entry and Data Processing
*
* * * Entry Points * * :
* - * * URL Parameters * * : Direct navigation with contact data in URL
* - * * Contact Input Form * * : Redirected from ContactsView with parsed data
* - * * Manual Entry * * : Users can input contact data directly
*
* * * Data Processing Pipeline * * :
* 1. * * Input Validation * * : Parse and validate contact data format
* 2. * * Contact Analysis * * : Check each contact against existing database
* 3. * * Duplicate Detection * * : Identify existing contacts and compare fields
* 4. * * UI Preparation * * : Prepare contact list with status indicators
*
* # # # Contact Analysis and Display
*
* * * Contact Status Classification * * :
* - * * New Contacts * * ( Green ) : Contacts not in database
* - * * Existing Contacts * * ( Orange ) : Contacts already in database
* - * * Identical Contacts * * : Existing contacts with no field differences
*
* * * Field Comparison System * * :
* - * * Automatic Detection * * : Compare all contact fields
* - * * Difference Display * * : Show old vs new values in table format
* - * * User Decision * * : Allow users to see what will be updated
*
* * * Contact List Structure * * :
* ` ` ` typescript
* interface ContactImportItem {
* did : string ; / / D e c e n t r a l i z e d i d e n t i f i e r
* name ? : string ; / / D i s p l a y n a m e
* publicKey ? : string ; / / P u b l i c k e y
* publicKeyBase64 ? : string ; / / B a s e 6 4 e n c o d e d k e y
* status : 'new' | 'existing' ; / / I m p o r t s t a t u s
* differences ? : FieldDifferences ; / / F i e l d c o m p a r i s o n r e s u l t s
* }
* ` ` `
*
* # # # User Interface Components
*
* * * Header Section * * :
* - * * Back Navigation * * : Return to previous page
* - * * Page Title * * : "Contact Import" heading
* - * * Loading State * * : Spinner during data processing
*
* * * Visibility Settings * * :
* - * * Activity Visibility Checkbox * * : Control activity sharing with imported contacts
* - * * Global Setting * * : Applies to all contacts being imported
*
* This component handles the import of contacts into the TimeSafari app .
* It supports multiple import methods and handles duplicate detection ,
* contact validation , and visibility settings .
* * * Contact List Display * * :
* - * * Contact Cards * * : Individual contact information with :
* - Selection checkbox for import control
* - Contact name and DID display
* - Status indicator ( New / Existing )
* - Field comparison table for existing contacts
*
* Import Methods :
* 1. Direct URL Query Parameters :
* Example : / c o n t a c t - i m p o r t ? c o n t a c t s = [ { " d i d " : " d i d : e x a m p l e : 1 2 3 " , " n a m e " : " A l i c e " } ]
* * * Field Comparison Table * * :
* - * * Three - Column Layout * * : Field name , old value , new value
* - * * Difference Highlighting * * : Clear visual indication of changes
* - * * Comprehensive Coverage * * : All contact fields are compared
*
* 2. JWT in URL Path :
* Example : / c o n t a c t - i m p o r t / e y J h b G c i O i J F U z I 1 N k s i f Q . . .
* - Supports both single and bulk imports
* - JWT payload can be either :
* a ) Array format : { contacts : [ { did : "..." , name : "..." } , ... ] }
* b ) Single contact : { own : true , did : "..." , name : "..." }
* * * Import Controls * * :
* - * * Select All / None * * : Bulk selection controls
* - * * Individual Selection * * : Per - contact import control
* - * * Import Button * * : Execute the selected imports
*
* 3. Manual JWT Input :
* - Accepts pasted JWT strings
* - Validates format and content before processing
* # # # Data Processing Logic
*
* URL Examples :
* * * Contact Validation * * :
* ` ` ` typescript
* / / V a l i d a t e D I D f o r m a t
* const isValidDid = ( did : string ) : boolean => {
* return did . startsWith ( 'did:' ) && did . length > 10 ;
* } ;
*
* / / C h e c k f o r e x i s t i n g c o n t a c t
* const existingContact = await $getContact ( did ) ;
* const isExisting = existingContact !== null ;
* ` ` `
* # Bulk import via query params
* / c o n t a c t - i m p o r t ? c o n t a c t s = [
* { "did" : "did:example:123" , "name" : "Alice" } ,
* { "did" : "did:example:456" , "name" : "Bob" }
* ]
*
* # Single contact via JWT
* / c o n t a c t - i m p o r t / e y J h b G c i O i J F U z I 1 N k s i f Q . e y J v d 2 4 i O n R y d W U s I m R p Z C I 6 I m R p Z D p l e G F t c G x l O j E y M y J 9 . . .
* * * Field Comparison Algorithm * * :
* ` ` ` typescript
* / / C o m p a r e c o n t a c t f i e l d s
* const compareFields = ( existing : Contact , importing : Contact ) => {
* const differences : FieldDifferences = { } ;
*
* # Bulk import via JWT
* / c o n t a c t - i m p o r t / e y J h b G c i O i J F U z I 1 N k s i f Q . e y J j b 2 5 0 Y W N 0 c y I 6 W 3 s i Z G l k I j o i Z G l k O m V 4 Y W 1 w b G U 6 M T I z I n 1 d f Q . . .
* for ( const field of [ 'name' , 'publicKey' , 'publicKeyBase64' ] ) {
* if ( existing [ field ] !== importing [ field ] ) {
* differences [ field ] = {
* old : existing [ field ] || '' ,
* new : importing [ field ] || ''
* } ;
* }
* }
*
* # Redirect to contacts page ( single contact )
* / c o n t a c t s ? c o n t a c t J w t = e y J h b G c i O i J F U z I 1 N k s i f Q . . .
* return differences ;
* } ;
* ` ` `
*
* Features :
* - Automatic duplicate detection
* - Field - by - field comparison for existing contacts
* - Batch visibility settings
* - Auto - import for single new contacts
* - Error handling and validation
*
* State Management :
* - Tracks existing contacts
* - Maintains selection state for bulk imports
* - Records differences for duplicate contacts
* - Manages visibility settings
*
* Security Considerations :
* - JWT validation for imported contacts
* - Visibility control per contact
* - Error handling for malformed data
*
* @ example
* / / C o m p o n e n t u s a g e i n r o u t e r
* {
* path : "/contact-import/:jwt?" ,
* name : "contact-import" ,
* component : ContactImportView
* }
* * * Import Decision Logic * * :
* - * * New Contact * * : Add to database with all provided fields
* - * * Existing Contact with Differences * * : Update with new field values
* - * * Existing Contact without Differences * * : Skip import ( already identical )
* - * * Invalid Contact * * : Skip import and show error
*
* # # # Batch Import Process
*
* * * Pre - Import Validation * * :
* - Verify all selected contacts are valid
* - Check database constraints
* - Validate visibility settings
*
* @ see { @ link Contact } for contact data structure
* @ see { @ link setVisibilityUtil } for visibility management
* * * Database Transaction * * :
* ` ` ` typescript
* / / E x e c u t e b a t c h i m p o r t
* const importContacts = async ( ) => {
* const selectedContacts = contactsImporting . filter ( ( _ , index ) =>
* contactsSelected [ index ]
* ) ;
*
* await $beginTransaction ( ) ;
*
* try {
* for ( const contact of selectedContacts ) {
* if ( contactsExisting [ contact . did ] ) {
* await $updateContact ( contact . did , contact ) ;
* } else {
* await $addContact ( contact ) ;
* }
* }
*
* await $commitTransaction ( ) ;
* notify . success ( 'Contacts imported successfully' ) ;
* } catch ( error ) {
* await $rollbackTransaction ( ) ;
* notify . error ( 'Import failed: ' + error . message ) ;
* }
* } ;
* ` ` `
*
* * * Post - Import Actions * * :
* - Update contact list in parent component
* - Apply visibility settings if enabled
* - Navigate back to contacts list
* - Display success / error notifications
*
* # # # Error Handling and Edge Cases
*
* * * Input Validation Errors * * :
* - Malformed JSON data
* - Invalid DID format
* - Missing required fields
* - Empty contact arrays
*
* * * Database Errors * * :
* - Constraint violations
* - Storage quota exceeded
* - Concurrent access conflicts
* - Transaction failures
*
* * * UI Error Recovery * * :
* - Graceful handling of network failures
* - Retry mechanisms for failed operations
* - Clear error messages for users
* - Fallback options for unsupported features
*
* # # # Performance Optimizations
*
* * * Efficient Processing * * :
* - Batch database operations
* - Optimized field comparison algorithms
* - Lazy loading of contact details
* - Debounced UI updates
*
* * * Memory Management * * :
* - Cleanup of temporary data structures
* - Proper disposal of event listeners
* - Efficient state management
* - Garbage collection optimization
*
* * * UI Responsiveness * * :
* - Asynchronous data processing
* - Progressive loading of contact data
* - Non - blocking UI updates
* - Optimized rendering for large lists
*
* # # # Integration Points
*
* * * Database Integration * * :
* - PlatformServiceMixin for database operations
* - Transaction - based data integrity
* - Optimized queries for contact retrieval
* - Proper error handling and rollback
*
* * * Navigation Integration * * :
* - Route - based data passing
* - Deep linking support
* - Back navigation handling
* - Modal dialog management
*
* * * Notification System * * :
* - Success / error message display
* - Progress indication during import
* - User feedback for all operations
* - Accessibility - compliant notifications
*
* @ author Matthew Raymer
* @ date 2025 - 08 - 04
* /
import * as R from "ramda" ;