cat-documents-ng 0.2.66 → 0.2.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2266,17 +2266,10 @@ class DocumentUploadService {
2266
2266
  */
2267
2267
  uploadCompleted = new EventEmitter();
2268
2268
  /**
2269
- * Map to track upload progress for multiple files
2270
- */
2271
- uploadProgress = new Map();
2272
- /**
2273
- * Queue for handling multiple file uploads sequentially
2274
- */
2275
- uploadQueue = [];
2276
- /**
2277
- * Flag to indicate if an upload is currently in progress
2269
+ * The file to upload.
2270
+ * @type {*}
2278
2271
  */
2279
- isUploading = false;
2272
+ uploadedFile;
2280
2273
  /**
2281
2274
  * Represent contextId
2282
2275
  * @type {string}
@@ -2310,47 +2303,16 @@ class DocumentUploadService {
2310
2303
  * @returns {void}
2311
2304
  */
2312
2305
  handleTemplatedUpload(file, contextId) {
2313
- console.log(`=== DOCUMENT UPLOAD SERVICE: ADDING TO QUEUE ===`);
2314
- console.log(`File: ${file.name}, Size: ${file.size}, ContextId: ${contextId}`);
2315
- // Add file to upload queue
2316
- this.uploadQueue.push({ file, contextId });
2317
- // If not currently uploading, start processing the queue
2318
- if (!this.isUploading) {
2319
- this.processUploadQueue();
2320
- }
2321
- }
2322
- /**
2323
- * Processes the upload queue sequentially
2324
- */
2325
- processUploadQueue() {
2326
- if (this.uploadQueue.length === 0) {
2327
- this.isUploading = false;
2328
- console.log('=== UPLOAD QUEUE EMPTY ===');
2329
- return;
2330
- }
2331
- this.isUploading = true;
2332
- const { file, contextId } = this.uploadQueue.shift();
2333
- console.log(`=== DOCUMENT UPLOAD SERVICE: PROCESSING QUEUE ITEM ===`);
2334
- console.log(`File: ${file.name}, Size: ${file.size}, ContextId: ${contextId}`);
2335
- console.log(`Remaining in queue: ${this.uploadQueue.length}`);
2336
- // Track this file's upload progress
2337
- this.uploadProgress.set(file, 10);
2338
- console.log(`Upload progress tracking started for: ${file.name}`);
2339
2306
  let formsData = this.handleCreateFormData(file, contextId);
2340
2307
  if (!formsData) {
2341
- console.error(`Failed to create FormData for file: ${file.name}`);
2342
2308
  this.messageService.add({ severity: SHARED.SEVERITY, summary: SHARED.UPLOAD_ERROR_SUMMERY, detail: SHARED.UPLOAD_ERROR_DETAILS });
2343
- this.uploadProgress.delete(file);
2344
- // Continue with next file in queue
2345
- this.processUploadQueue();
2346
2309
  return;
2347
2310
  }
2348
- console.log(`FormData created successfully for file: ${file.name}`);
2311
+ // Update progress to show upload starting
2349
2312
  this.documentUploadStore.setMessage([{
2350
2313
  severity: 'info',
2351
- detail: `Uploading document: ${file.name}...`
2314
+ detail: 'Uploading document...'
2352
2315
  }]);
2353
- console.log(`Calling document service create method for file: ${file.name}`);
2354
2316
  this.documentService.create(formsData)
2355
2317
  .subscribe({
2356
2318
  /**
@@ -2359,19 +2321,16 @@ class DocumentUploadService {
2359
2321
  * @returns {void}
2360
2322
  */
2361
2323
  next: (event) => {
2362
- console.log(`=== UPLOAD SUCCESS FOR FILE: ${file.name} ===`);
2363
- console.log(`Response received:`, event);
2364
2324
  this.documentUploadStore.setUploadedDocumentFiles(event);
2365
2325
  this.documentUploadStore.setMessage([{
2366
2326
  severity: SHARED.SUCCESS_SEVERITY,
2367
- detail: `Successfully uploaded: ${file.name}`
2327
+ detail: SHARED.UPLOAD_SUCCESS
2368
2328
  }]);
2369
- console.log(`Emitting uploadCompleted event for file: ${file.name}`);
2329
+ // Emit upload completion event with file and response
2370
2330
  this.uploadCompleted.emit({ file: file, response: event });
2371
- this.uploadProgress.delete(file);
2372
- console.log(`Upload completed and cleaned up for file: ${file.name}`);
2373
- // Process next file in queue
2374
- this.processUploadQueue();
2331
+ if (this.uploadedFile) {
2332
+ // You can emit an event here to update the UI progress if needed
2333
+ }
2375
2334
  },
2376
2335
  /**
2377
2336
  * Handles the error event during file upload.
@@ -2379,15 +2338,9 @@ class DocumentUploadService {
2379
2338
  * @param {any} error - The error object returned by the upload service.
2380
2339
  */
2381
2340
  error: (error) => {
2382
- console.error(`=== UPLOAD ERROR FOR FILE: ${file.name} ===`);
2383
- console.error('Error details:', error);
2384
2341
  this.messageService.add({ severity: SHARED.SEVERITY, summary: SHARED.UPLOAD_SUMMERY, detail: error?.message });
2385
- this.uploadProgress.delete(file);
2386
- // Continue with next file in queue even on error
2387
- this.processUploadQueue();
2388
2342
  },
2389
2343
  });
2390
- console.log(`=== DOCUMENT UPLOAD SERVICE: UPLOAD INITIATED FOR: ${file.name} ===`);
2391
2344
  }
2392
2345
  /**
2393
2346
  * Get the file and contextId
@@ -2396,6 +2349,7 @@ class DocumentUploadService {
2396
2349
  */
2397
2350
  getUploadFileData(file, contextId) {
2398
2351
  if (file && contextId) {
2352
+ this.uploadedFile = file;
2399
2353
  this.contextId = contextId;
2400
2354
  }
2401
2355
  }
@@ -2417,56 +2371,13 @@ class DocumentUploadService {
2417
2371
  if (uploadedFile) {
2418
2372
  let formData = new FormData();
2419
2373
  formData.append(SHARED.FILE, uploadedFile, uploadedFile.name);
2420
- formData.append(SHARED.CONTEXT_ID, contextId || this.contextId);
2374
+ formData.append(SHARED.CONTEXT_ID, this.contextId);
2421
2375
  return formData;
2422
2376
  }
2423
2377
  else {
2424
2378
  return null;
2425
2379
  }
2426
2380
  }
2427
- /**
2428
- * Get upload progress for a specific file
2429
- * @param file - The file to get progress for
2430
- * @returns The upload progress percentage or undefined if not tracked
2431
- */
2432
- getUploadProgress(file) {
2433
- return this.uploadProgress.get(file);
2434
- }
2435
- /**
2436
- * Check if a file is currently being uploaded
2437
- * @param file - The file to check
2438
- * @returns True if the file is being uploaded
2439
- */
2440
- isFileUploading(file) {
2441
- return this.uploadProgress.has(file);
2442
- }
2443
- /**
2444
- * Get the current upload queue status
2445
- * @returns Object containing queue information
2446
- */
2447
- getQueueStatus() {
2448
- return {
2449
- isUploading: this.isUploading,
2450
- queueLength: this.uploadQueue.length,
2451
- totalFiles: this.uploadProgress.size
2452
- };
2453
- }
2454
- /**
2455
- * Clear the upload queue (useful for cleanup)
2456
- */
2457
- clearUploadQueue() {
2458
- this.uploadQueue = [];
2459
- this.isUploading = false;
2460
- this.uploadProgress.clear();
2461
- console.log('=== UPLOAD QUEUE CLEARED ===');
2462
- }
2463
- /**
2464
- * Get the number of files currently in the upload queue
2465
- * @returns Number of files waiting to be uploaded
2466
- */
2467
- getQueueLength() {
2468
- return this.uploadQueue.length;
2469
- }
2470
2381
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, deps: [{ token: DocumentService }, { token: DocumentStore }, { token: i3.MessageService }], target: i0.ɵɵFactoryTarget.Injectable });
2471
2382
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, providedIn: 'root' });
2472
2383
  }
@@ -2923,6 +2834,7 @@ class DocumentUploadComponent {
2923
2834
  businessService;
2924
2835
  formService;
2925
2836
  dataService;
2837
+ documentService;
2926
2838
  /** The context ID for the document upload operation */
2927
2839
  contextId = SHARED.EMPTY;
2928
2840
  /** Reference to the file upload component */
@@ -2977,7 +2889,7 @@ class DocumentUploadComponent {
2977
2889
  * @param formService - Service for form validation and handling
2978
2890
  * @param dataService - Service for data loading operations
2979
2891
  */
2980
- constructor(documentUpload, uploadService, config, fileFormatService, messageService, cdr, businessService, formService, dataService) {
2892
+ constructor(documentUpload, uploadService, config, fileFormatService, messageService, cdr, businessService, formService, dataService, documentService) {
2981
2893
  this.documentUpload = documentUpload;
2982
2894
  this.uploadService = uploadService;
2983
2895
  this.config = config;
@@ -2987,24 +2899,7 @@ class DocumentUploadComponent {
2987
2899
  this.businessService = businessService;
2988
2900
  this.formService = formService;
2989
2901
  this.dataService = dataService;
2990
- // Set up global upload completion listener for debugging
2991
- this.setupGlobalUploadListener();
2992
- }
2993
- /**
2994
- * Sets up a global listener for all upload completion events.
2995
- * This helps debug issues with multiple file uploads.
2996
- */
2997
- setupGlobalUploadListener() {
2998
- this.documentUpload.uploadCompleted
2999
- .pipe(takeUntil(this.destroy$))
3000
- .subscribe(({ file, response }) => {
3001
- console.log(`=== GLOBAL UPLOAD COMPLETION EVENT ===`);
3002
- console.log(`File: ${file?.name}`);
3003
- console.log(`Response:`, response);
3004
- console.log(`Current time: ${new Date().toISOString()}`);
3005
- // Log current upload status
3006
- this.logUploadStatus();
3007
- });
2902
+ this.documentService = documentService;
3008
2903
  }
3009
2904
  /**
3010
2905
  * Handles changes in assignment type selection.
@@ -3044,21 +2939,10 @@ class DocumentUploadComponent {
3044
2939
  * @param event - Event containing the selected files
3045
2940
  */
3046
2941
  onSelectedFiles(event) {
3047
- console.log('=== FILE SELECTION EVENT ===');
3048
- console.log('Number of files selected:', event.currentFiles.length);
3049
- console.log('Files:', event.currentFiles.map(f => ({ name: f.name, size: f.size })));
3050
- // Process each file immediately without delays
3051
2942
  event.currentFiles.forEach((file, index) => {
3052
- console.log(`Processing file ${index + 1}/${event.currentFiles.length}: ${file.name}`);
3053
2943
  this.handleTemplatedUpload(file);
3054
2944
  });
3055
- console.log('All files processed, clearing file uploader');
3056
2945
  this.fileUploader.clear();
3057
- // Log upload status after processing all files
3058
- setTimeout(() => {
3059
- console.log('=== STATUS AFTER PROCESSING ALL FILES ===');
3060
- this.logUploadStatus();
3061
- }, 1000);
3062
2946
  }
3063
2947
  /**
3064
2948
  * Loads the list of applicants for the current context.
@@ -3114,32 +2998,33 @@ class DocumentUploadComponent {
3114
2998
  * @param file - The file to be uploaded
3115
2999
  */
3116
3000
  handleTemplatedUpload(file) {
3117
- console.log(`=== STARTING UPLOAD FOR FILE: ${file.name} ===`);
3118
- if (!this.formService.validateContextId(this.contextId, 'Context ID is required for upload.')) {
3119
- console.error(`Context ID validation failed for file: ${file.name}`);
3001
+ if (!this.formService.validateContextId(this.contextId, 'Context ID is required for upload.'))
3002
+ return;
3003
+ const formsData = this.documentService.handleCreateFormData(file, this.contextId);
3004
+ if (!formsData) {
3005
+ this.messageService.add({ severity: SHARED.SEVERITY, summary: SHARED.UPLOAD_ERROR_SUMMERY, detail: SHARED.UPLOAD_ERROR_DETAILS });
3120
3006
  return;
3121
3007
  }
3122
- console.log(`File validation passed for: ${file.name}`);
3123
- console.log(`Context ID: ${this.contextId}`);
3124
- // Set initial progress
3125
3008
  this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_10);
3126
- console.log(`Progress set to 10% for file: ${file.name}`);
3127
- // Set up upload listener before starting upload
3128
- console.log(`Setting up upload listener for file: ${file.name}`);
3129
- this.setupFileUploadListener(file);
3130
- // Start the upload (now goes to queue)
3131
- console.log(`Adding file to upload queue: ${file.name}`);
3132
- this.documentUpload.handleTemplatedUpload(file, this.contextId);
3133
- // Create uploaded file object
3134
3009
  const formattedSize = this.businessService.formatFileSize(file.size, this.config);
3135
3010
  const uploadedFile = this.businessService.createUploadedFile(file, formattedSize);
3136
3011
  uploadedFile.progress = SHARED.UPLOAD_PROGRESS_10;
3137
3012
  this.uploadedFiles.push(uploadedFile);
3138
- console.log(`Uploaded file object created for: ${file.name}`);
3139
- console.log(`Total uploaded files count: ${this.uploadedFiles.length}`);
3140
- this.validateForm();
3141
- this.cdr.detectChanges();
3142
- console.log(`=== FILE ADDED TO UPLOAD QUEUE: ${file.name} ===`);
3013
+ this.uploadService.create(formsData).subscribe({
3014
+ next: (event) => {
3015
+ uploadedFile.uploadResponse = event;
3016
+ uploadedFile.progress = SHARED.UPLOAD_PROGRESS_100;
3017
+ uploadedFile.url = event?.url;
3018
+ uploadedFile.contentType = event?.contentType;
3019
+ this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_100);
3020
+ // this.uploadCompleted.emit({ file, response: event });
3021
+ this.cdr.detectChanges();
3022
+ this.onFormValidationChange.emit();
3023
+ },
3024
+ error: (error) => {
3025
+ this.messageService.add({ severity: SHARED.SEVERITY, summary: SHARED.UPLOAD_SUMMERY, detail: error?.message });
3026
+ }
3027
+ });
3143
3028
  }
3144
3029
  /**
3145
3030
  * Removes a document from the uploaded files list.
@@ -3171,99 +3056,6 @@ class DocumentUploadComponent {
3171
3056
  const isDisabled = this.businessService.isSaveButtonDisabled(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles, this.isSaving);
3172
3057
  return isDisabled;
3173
3058
  }
3174
- /**
3175
- * Gets the current upload queue status
3176
- * @returns Object containing queue information
3177
- */
3178
- getUploadQueueStatus() {
3179
- if (this.documentUpload.getQueueStatus) {
3180
- return this.documentUpload.getQueueStatus();
3181
- }
3182
- return { isUploading: false, queueLength: 0, totalFiles: 0 };
3183
- }
3184
- /**
3185
- * Gets the number of files currently in the upload queue
3186
- * @returns Number of files waiting to be uploaded
3187
- */
3188
- getUploadQueueLength() {
3189
- if (this.documentUpload.getQueueLength) {
3190
- return this.documentUpload.getQueueLength();
3191
- }
3192
- return 0;
3193
- }
3194
- /**
3195
- * Checks if there are files waiting in the upload queue
3196
- * @returns True if there are files waiting to be uploaded
3197
- */
3198
- hasFilesInQueue() {
3199
- return this.getUploadQueueLength() > 0;
3200
- }
3201
- /**
3202
- * Checks the upload service status for debugging purposes.
3203
- */
3204
- checkUploadServiceStatus() {
3205
- console.log('=== UPLOAD SERVICE STATUS ===');
3206
- console.log('Document upload service:', this.documentUpload);
3207
- console.log('Upload completed event emitter:', this.documentUpload.uploadCompleted);
3208
- // Check if the service has any active uploads
3209
- if (this.documentUpload.getUploadProgress) {
3210
- this.uploadedFiles.forEach(uploadedFile => {
3211
- const serviceProgress = this.documentUpload.getUploadProgress(uploadedFile.file);
3212
- const isUploading = this.documentUpload.isFileUploading(uploadedFile.file);
3213
- console.log(`File: ${uploadedFile.file.name}`);
3214
- console.log(` - Service progress: ${serviceProgress}`);
3215
- console.log(` - Service isUploading: ${isUploading}`);
3216
- });
3217
- }
3218
- console.log('=== END SERVICE STATUS ===');
3219
- }
3220
- /**
3221
- * Logs the current upload status for debugging purposes.
3222
- */
3223
- logUploadStatus() {
3224
- console.log('=== CURRENT UPLOAD STATUS ===');
3225
- console.log('Total uploaded files:', this.uploadedFiles.length);
3226
- console.log('File progress map size:', this.fileProgress.size);
3227
- this.uploadedFiles.forEach((uploadedFile, index) => {
3228
- const progress = this.fileProgress.get(uploadedFile.file);
3229
- console.log(`File ${index + 1}: ${uploadedFile.file.name}`);
3230
- console.log(` - Progress: ${progress}%`);
3231
- console.log(` - Uploaded file progress: ${uploadedFile.progress}%`);
3232
- console.log(` - Has response: ${!!uploadedFile.uploadResponse}`);
3233
- });
3234
- // Check for orphaned progress entries
3235
- const orphanedFiles = Array.from(this.fileProgress.keys()).filter(file => !this.uploadedFiles.some(uf => uf.file === file));
3236
- if (orphanedFiles.length > 0) {
3237
- console.warn('=== ORPHANED PROGRESS ENTRIES ===');
3238
- orphanedFiles.forEach(file => {
3239
- console.warn(`Orphaned file: ${file.name} with progress: ${this.fileProgress.get(file)}%`);
3240
- });
3241
- }
3242
- console.log('=== END UPLOAD STATUS ===');
3243
- }
3244
- /**
3245
- * Checks if all files have completed uploading.
3246
- * @returns True if all files have completed uploading, false otherwise
3247
- */
3248
- areAllFilesUploaded() {
3249
- if (this.uploadedFiles.length === 0)
3250
- return false;
3251
- return this.uploadedFiles.every(file => this.fileProgress.get(file.file) === SHARED.UPLOAD_PROGRESS_100);
3252
- }
3253
- /**
3254
- * Gets the currently uploading file (if any)
3255
- * @returns The file currently being uploaded or null
3256
- */
3257
- getCurrentlyUploadingFile() {
3258
- if (this.documentUpload.getQueueStatus) {
3259
- const status = this.documentUpload.getQueueStatus();
3260
- if (status.isUploading && this.uploadedFiles.length > 0) {
3261
- // Find the file that's currently being uploaded (has 10% progress)
3262
- return this.uploadedFiles.find(uf => this.fileProgress.get(uf.file) === SHARED.UPLOAD_PROGRESS_10)?.file || null;
3263
- }
3264
- }
3265
- return null;
3266
- }
3267
3059
  /**
3268
3060
  * Gets the upload progress for a specific file.
3269
3061
  * @param file - The file to get progress for
@@ -3302,22 +3094,8 @@ class DocumentUploadComponent {
3302
3094
  this.filteredApplicantList = [];
3303
3095
  this.categoryOptions = [];
3304
3096
  this.documentTypeOptions = [];
3305
- // Clear the upload queue
3306
- if (this.documentUpload.clearUploadQueue) {
3307
- this.documentUpload.clearUploadQueue();
3308
- }
3309
3097
  this.cdr.detectChanges();
3310
3098
  }
3311
- /**
3312
- * Clears the upload queue manually
3313
- */
3314
- clearUploadQueue() {
3315
- if (this.documentUpload.clearUploadQueue) {
3316
- this.documentUpload.clearUploadQueue();
3317
- console.log('Upload queue cleared manually');
3318
- this.cdr.detectChanges();
3319
- }
3320
- }
3321
3099
  /**
3322
3100
  * Resets form selections (applicant, category, document type).
3323
3101
  * Clears document type options.
@@ -3387,11 +3165,11 @@ class DocumentUploadComponent {
3387
3165
  this.onUploadSuccess.emit();
3388
3166
  }
3389
3167
  /**
3390
- * Handles save operation error.
3168
+ * Handles upload error.
3391
3169
  * Resets saving state.
3392
- * @param error - The error that occurred during save operation
3170
+ * @param error - The error that occurred during upload
3393
3171
  */
3394
- handleSaveError(error) {
3172
+ handleUploadError(error) {
3395
3173
  this.isSaving = false;
3396
3174
  }
3397
3175
  /**
@@ -3424,7 +3202,7 @@ class DocumentUploadComponent {
3424
3202
  .pipe(takeUntil(this.destroy$))
3425
3203
  .subscribe({
3426
3204
  next: (response) => this.handleUploadSuccess(response),
3427
- error: (error) => this.handleSaveError(error)
3205
+ error: (error) => this.handleUploadError(error)
3428
3206
  });
3429
3207
  }
3430
3208
  /**
@@ -3433,75 +3211,20 @@ class DocumentUploadComponent {
3433
3211
  * @param file - The file to monitor for upload completion
3434
3212
  */
3435
3213
  setupFileUploadListener(file) {
3436
- console.log(`=== SETTING UP UPLOAD LISTENER FOR: ${file.name} ===`);
3437
- // Create a unique identifier for this file to avoid conflicts
3438
- const fileId = `${file.name}-${file.size}-${file.lastModified}`;
3439
- console.log(`File ID created: ${fileId}`);
3440
- // Store the file ID in the file object for tracking
3441
- file.fileId = fileId;
3442
- // Set up a one-time listener for this specific file
3443
- const subscription = this.documentUpload.uploadCompleted
3444
- .pipe(takeUntil(this.destroy$))
3445
- .subscribe(({ file: uploadedFile, response }) => {
3446
- console.log(`=== UPLOAD COMPLETION EVENT RECEIVED ===`);
3447
- console.log(`Event file: ${uploadedFile?.name}`);
3448
- console.log(`Tracking file: ${file.name}`);
3449
- console.log(`File ID match: ${uploadedFile?.fileId === fileId}`);
3450
- console.log(`Direct file match: ${uploadedFile === file}`);
3451
- // Check if this is the file we're tracking
3452
- if (uploadedFile === file || uploadedFile.fileId === fileId) {
3453
- console.log(`=== MATCH FOUND - UPDATING PROGRESS FOR: ${file.name} ===`);
3454
- // Update progress to 100%
3214
+ this.documentUpload.uploadCompleted.pipe(takeUntil(this.destroy$)).subscribe(({ file: uploadedFile, response }) => {
3215
+ if (uploadedFile === file) {
3455
3216
  this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_100);
3456
- console.log(`Progress updated to 100% for file: ${file.name}`);
3457
- // Find and update the uploaded file object
3458
3217
  const uploadedFileObj = this.uploadedFiles.find(uf => uf.file === file);
3459
3218
  if (uploadedFileObj) {
3460
3219
  uploadedFileObj.uploadResponse = response;
3461
3220
  uploadedFileObj.progress = SHARED.UPLOAD_PROGRESS_100;
3462
3221
  uploadedFileObj.url = response?.url;
3463
3222
  uploadedFileObj.contentType = response?.contentType;
3464
- console.log(`Uploaded file object updated for: ${file.name}`);
3465
- }
3466
- else {
3467
- console.warn(`Could not find uploaded file object for: ${file.name}`);
3468
3223
  }
3469
- // Trigger change detection and emit validation change
3470
3224
  this.cdr.detectChanges();
3471
3225
  this.onFormValidationChange.emit();
3472
- // Unsubscribe from this specific file's upload completion
3473
- subscription.unsubscribe();
3474
- console.log(`Subscription unsubscribed for file: ${file.name}`);
3475
- console.log(`=== FILE UPLOAD COMPLETED SUCCESSFULLY: ${file.name} ===`);
3476
- }
3477
- else {
3478
- console.log(`Event not for this file: ${file.name}`);
3479
3226
  }
3480
3227
  });
3481
- console.log(`Upload listener setup completed for file: ${file.name}`);
3482
- }
3483
- /**
3484
- * Handles upload error for a specific file.
3485
- * @param file - The file that encountered an error
3486
- * @param errorMessage - The error message
3487
- */
3488
- handleUploadError(file, errorMessage) {
3489
- console.error(`Upload error for file: ${file.name}: ${errorMessage}`);
3490
- // Mark file as having an error
3491
- this.fileProgress.set(file, -1);
3492
- // Update the uploaded file object
3493
- const uploadedFileObj = this.uploadedFiles.find(uf => uf.file === file);
3494
- if (uploadedFileObj) {
3495
- uploadedFileObj.progress = -1;
3496
- }
3497
- // Trigger change detection
3498
- this.cdr.detectChanges();
3499
- // Show error message
3500
- this.messageService.add({
3501
- severity: 'error',
3502
- summary: 'Upload Failed',
3503
- detail: `Failed to upload ${file.name}: ${errorMessage}`
3504
- });
3505
3228
  }
3506
3229
  /**
3507
3230
  * Handles errors during data loading operations.
@@ -3543,13 +3266,13 @@ class DocumentUploadComponent {
3543
3266
  this.businessService.destroy();
3544
3267
  this.dataService.destroy();
3545
3268
  }
3546
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, deps: [{ token: DocumentUploadService }, { token: DocumentService }, { token: i3.PrimeNGConfig }, { token: FileFormatService }, { token: i3.MessageService }, { token: i0.ChangeDetectorRef }, { token: DocumentUploadBusinessService }, { token: DocumentUploadFormService }, { token: DocumentUploadDataService }], target: i0.ɵɵFactoryTarget.Component });
3547
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentUploadComponent, isStandalone: false, selector: "lib-document-upload", inputs: { contextId: "contextId" }, outputs: { onFormValidationChange: "onFormValidationChange", onUploadSuccess: "onUploadSuccess" }, viewQueries: [{ propertyName: "fileUploader", first: true, predicate: ["fileUploader"], descendants: true }], ngImport: i0, template: "<div class=\"document-upload-container\">\n <!-- Assignment Section -->\n <div class=\"assignment-section\">\n <h4>Assign to Applicant(s) or Application</h4>\n <div class=\"radio-group\">\n <div class=\"radio-item\">\n <p-radioButton \n name=\"assignmentType\" \n value=\"Applicant\" \n [(ngModel)]=\"selectedAssignmentType\"\n (onClick)=\"onAssignmentTypeChange()\"\n [inputId]=\"'applicant'\"\n ></p-radioButton>\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s)</label>\n </div>\n <div class=\"radio-item\">\n <p-radioButton \n name=\"assignmentType\" \n value=\"Application\" \n [(ngModel)]=\"selectedAssignmentType\"\n (onClick)=\"onAssignmentTypeChange()\"\n [inputId]=\"'application'\"\n ></p-radioButton>\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\n </div>\n </div>\n </div>\n\n <!-- Applicant Selection (only shown when Applicant is selected) -->\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\n <h4>Select Applicant(s)</h4>\n <div class=\"grid\">\n <div \n *ngFor=\"let applicant of filteredApplicantList\" \n class=\"applicant-item col-12 md:col-6\"\n >\n <p-radioButton \n name=\"selectedApplicant\"\n [value]=\"applicant._id\"\n [(ngModel)]=\"selectedApplicant\"\n [inputId]=\"'applicant-' + applicant._id\"\n (onClick)=\"onApplicantSelectionChange()\"\n ></p-radioButton>\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\n {{ applicant.name }}\n </label>\n </div>\n </div>\n </div>\n\n <!-- Category Selection -->\n <div class=\"category-section\">\n <h4>Category</h4>\n <p-dropdown\n [options]=\"categoryOptions\"\n [(ngModel)]=\"selectedCategory\"\n placeholder=\"Select Category type\"\n optionLabel=\"label\"\n optionValue=\"_id\"\n (onChange)=\"onCategoryChange()\"\n [disabled]=\"!categoryOptions.length\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n\n <!-- Document Type Selection -->\n <div class=\"document-type-section\">\n <h4>Document Type</h4>\n <p-dropdown\n [options]=\"documentTypeOptions\"\n [(ngModel)]=\"selectedDocumentType\"\n placeholder=\"Select Document type\"\n optionLabel=\"label\"\n optionValue=\"_id\"\n (onChange)=\"onDocumentTypeChange()\"\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n\n <!-- File Upload Section -->\n <div class=\"file-upload-section\">\n <h4>Upload Documents</h4>\n \n <!-- Debug Section -->\n <div class=\"debug-section mb-3\" style=\"background: #f0f0f0; padding: 10px; border-radius: 4px;\">\n <button type=\"button\" class=\"p-button p-button-sm p-button-outlined\" (click)=\"logUploadStatus()\">\n Debug: Log Upload Status\n </button>\n <button type=\"button\" class=\"p-button p-button-sm p-button-outlined ml-2\" (click)=\"checkUploadServiceStatus()\">\n Check Service Status\n </button>\n <button type=\"button\" class=\"p-button p-button-sm p-button-danger ml-2\" (click)=\"clearUploadQueue()\">\n Clear Upload Queue\n </button>\n <span class=\"ml-3 text-sm\">Files: {{ uploadedFiles.length }} | Progress Map: {{ fileProgress.size }}</span>\n <div class=\"mt-2 text-xs\">\n <div>All Files Uploaded: {{ areAllFilesUploaded() }}</div>\n <div>Save Button Disabled: {{ getSaveButtonDisabled() }}</div>\n <div>Upload Queue Length: {{ getUploadQueueLength() }}</div>\n <div>Currently Uploading: {{ getUploadQueueStatus().isUploading }}</div>\n <div *ngIf=\"getCurrentlyUploadingFile()\" style=\"color: blue; font-weight: bold;\">\n Current File: {{ getCurrentlyUploadingFile()?.name }}\n </div>\n <div *ngIf=\"hasFilesInQueue()\" style=\"color: orange; font-weight: bold;\">\n \u23F3 Files waiting in queue: {{ getUploadQueueLength() }}\n </div>\n </div>\n </div>\n \n <div class=\"grid\">\n <div class=\"col-12 md:col-12\">\n <p-fileUpload \n #fileUploader \n [multiple]=\"true\" \n [auto]=\"false\" \n accept=\"image/png,application/pdf\" \n maxFileSize=\"26214400\"\n (onSelect)=\"onSelectedFiles($event)\"\n >\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\n <div class=\"flex gap-2\">\n <p-button \n (onClick)=\"choose($event, chooseCallback)\" \n icon=\"pi pi-images\" \n [rounded]=\"true\"\n [outlined]=\"true\" \n />\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\n <div class=\"col-12 md:col-12 p-0\">\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\n <div class=\"documentImage\">\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\n class=\"object-contain\" />\n </div>\n <div class=\"flex w-full flex-column mt-2 ml-2\">\n <div class=\"flex justify-content-between\">\n <div style=\"font-weight: bold;font-size: 14px\">\n {{ uploadedFile.file.name }}\n </div>\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\n </div>\n <div class=\"flex justify-content-between mt-1\">\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \n {{ uploadedFile.formattedSize }}\n </div>\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \n {{ uploadedFile.progress }} % \n </div>\n </div>\n </div>\n </div>\n <div class=\"col-12 md:col-12 p-0\">\n <p-progressBar \n [value]=\"uploadedFile.progress\" \n [showValue]=\"false\" \n styleClass=\"h-1/2rem md:ml-auto relative\"\n [ngClass]=\"{ 'exceeded-progress-bar': uploadedFile.progress > 100 }\"\n >\n </p-progressBar>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\n (click)=\"triggerFileUpload()\">\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\n </div>\n </ng-template>\n <ng-template pTemplate=\"file\"> </ng-template>\n </p-fileUpload>\n </div>\n </div>\n </div>\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}.applicant-list{display:none}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i10.FileUpload, selector: "p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "component", type: i11.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i12.RadioButton, selector: "p-radioButton", inputs: ["value", "formControlName", "name", "disabled", "label", "variant", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "labelStyleClass", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i14.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], encapsulation: i0.ViewEncapsulation.None });
3269
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, deps: [{ token: DocumentUploadService }, { token: DocumentService }, { token: i3.PrimeNGConfig }, { token: FileFormatService }, { token: i3.MessageService }, { token: i0.ChangeDetectorRef }, { token: DocumentUploadBusinessService }, { token: DocumentUploadFormService }, { token: DocumentUploadDataService }, { token: DocumentUploadService }], target: i0.ɵɵFactoryTarget.Component });
3270
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentUploadComponent, isStandalone: false, selector: "lib-document-upload", inputs: { contextId: "contextId" }, outputs: { onFormValidationChange: "onFormValidationChange", onUploadSuccess: "onUploadSuccess" }, viewQueries: [{ propertyName: "fileUploader", first: true, predicate: ["fileUploader"], descendants: true }], ngImport: i0, template: "<div class=\"document-upload-container\">\r\n <!-- Assignment Section -->\r\n <div class=\"assignment-section\">\r\n <h4>Assign to Applicant(s) or Application</h4>\r\n <div class=\"radio-group\">\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Applicant\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'applicant'\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s)</label>\r\n </div>\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Application\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'application'\"\r\n ></p-radioButton>\r\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Applicant Selection (only shown when Applicant is selected) -->\r\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\r\n <h4>Select Applicant(s)</h4>\r\n <div class=\"grid\">\r\n <div \r\n *ngFor=\"let applicant of filteredApplicantList\" \r\n class=\"applicant-item col-12 md:col-6\"\r\n >\r\n <p-radioButton \r\n name=\"selectedApplicant\"\r\n [value]=\"applicant._id\"\r\n [(ngModel)]=\"selectedApplicant\"\r\n [inputId]=\"'applicant-' + applicant._id\"\r\n (onClick)=\"onApplicantSelectionChange()\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\r\n {{ applicant.name }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Category Selection -->\r\n <div class=\"category-section\">\r\n <h4>Category</h4>\r\n <p-dropdown\r\n [options]=\"categoryOptions\"\r\n [(ngModel)]=\"selectedCategory\"\r\n placeholder=\"Select Category type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onCategoryChange()\"\r\n [disabled]=\"!categoryOptions.length\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- Document Type Selection -->\r\n <div class=\"document-type-section\">\r\n <h4>Document Type</h4>\r\n <p-dropdown\r\n [options]=\"documentTypeOptions\"\r\n [(ngModel)]=\"selectedDocumentType\"\r\n placeholder=\"Select Document type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onDocumentTypeChange()\"\r\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- File Upload Section -->\r\n <div class=\"file-upload-section\">\r\n <h4>Upload Documents</h4>\r\n <div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload \r\n #fileUploader \r\n [multiple]=\"true\" \r\n [auto]=\"false\" \r\n accept=\"image/png,application/pdf\" \r\n maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\"\r\n >\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button \r\n (onClick)=\"choose($event, chooseCallback)\" \r\n icon=\"pi pi-images\" \r\n [rounded]=\"true\"\r\n [outlined]=\"true\" \r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\"font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \r\n {{ uploadedFile.formattedSize }}\r\n </div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \r\n {{ uploadedFile.progress }} % \r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar \r\n [value]=\"uploadedFile.progress\" \r\n [showValue]=\"false\" \r\n styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': uploadedFile.progress > 100 }\"\r\n >\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.upload-status{margin-bottom:1rem;padding:.75rem;background-color:#f8f9fa;border-radius:.5rem;border-left:4px solid #0F8BFD}.upload-status .status-message{display:flex;align-items:center;font-size:.9rem;color:#495057}.upload-status .status-message .pi{font-size:1rem}.upload-status .status-message .pi.pi-spinner{color:#0f8bfd}.upload-status .status-message .pi.pi-check-circle{color:#28a745}.upload-status .status-message .pi.pi-clock{color:#ffc107}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-progressbar.error-progress-bar .p-progressbar-value{background-color:#dc3545!important}:host ::ng-deep .p-progressbar.success-progress-bar .p-progressbar-value{background-color:#28a745!important}:host ::ng-deep .p-progressbar.exceeded-progress-bar .p-progressbar-value{background-color:#ffc107!important}.applicant-list{display:none}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i10.FileUpload, selector: "p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "component", type: i11.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i12.RadioButton, selector: "p-radioButton", inputs: ["value", "formControlName", "name", "disabled", "label", "variant", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "labelStyleClass", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i14.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], encapsulation: i0.ViewEncapsulation.None });
3548
3271
  }
3549
3272
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, decorators: [{
3550
3273
  type: Component,
3551
- args: [{ selector: 'lib-document-upload', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"document-upload-container\">\n <!-- Assignment Section -->\n <div class=\"assignment-section\">\n <h4>Assign to Applicant(s) or Application</h4>\n <div class=\"radio-group\">\n <div class=\"radio-item\">\n <p-radioButton \n name=\"assignmentType\" \n value=\"Applicant\" \n [(ngModel)]=\"selectedAssignmentType\"\n (onClick)=\"onAssignmentTypeChange()\"\n [inputId]=\"'applicant'\"\n ></p-radioButton>\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s)</label>\n </div>\n <div class=\"radio-item\">\n <p-radioButton \n name=\"assignmentType\" \n value=\"Application\" \n [(ngModel)]=\"selectedAssignmentType\"\n (onClick)=\"onAssignmentTypeChange()\"\n [inputId]=\"'application'\"\n ></p-radioButton>\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\n </div>\n </div>\n </div>\n\n <!-- Applicant Selection (only shown when Applicant is selected) -->\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\n <h4>Select Applicant(s)</h4>\n <div class=\"grid\">\n <div \n *ngFor=\"let applicant of filteredApplicantList\" \n class=\"applicant-item col-12 md:col-6\"\n >\n <p-radioButton \n name=\"selectedApplicant\"\n [value]=\"applicant._id\"\n [(ngModel)]=\"selectedApplicant\"\n [inputId]=\"'applicant-' + applicant._id\"\n (onClick)=\"onApplicantSelectionChange()\"\n ></p-radioButton>\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\n {{ applicant.name }}\n </label>\n </div>\n </div>\n </div>\n\n <!-- Category Selection -->\n <div class=\"category-section\">\n <h4>Category</h4>\n <p-dropdown\n [options]=\"categoryOptions\"\n [(ngModel)]=\"selectedCategory\"\n placeholder=\"Select Category type\"\n optionLabel=\"label\"\n optionValue=\"_id\"\n (onChange)=\"onCategoryChange()\"\n [disabled]=\"!categoryOptions.length\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n\n <!-- Document Type Selection -->\n <div class=\"document-type-section\">\n <h4>Document Type</h4>\n <p-dropdown\n [options]=\"documentTypeOptions\"\n [(ngModel)]=\"selectedDocumentType\"\n placeholder=\"Select Document type\"\n optionLabel=\"label\"\n optionValue=\"_id\"\n (onChange)=\"onDocumentTypeChange()\"\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n\n <!-- File Upload Section -->\n <div class=\"file-upload-section\">\n <h4>Upload Documents</h4>\n \n <!-- Debug Section -->\n <div class=\"debug-section mb-3\" style=\"background: #f0f0f0; padding: 10px; border-radius: 4px;\">\n <button type=\"button\" class=\"p-button p-button-sm p-button-outlined\" (click)=\"logUploadStatus()\">\n Debug: Log Upload Status\n </button>\n <button type=\"button\" class=\"p-button p-button-sm p-button-outlined ml-2\" (click)=\"checkUploadServiceStatus()\">\n Check Service Status\n </button>\n <button type=\"button\" class=\"p-button p-button-sm p-button-danger ml-2\" (click)=\"clearUploadQueue()\">\n Clear Upload Queue\n </button>\n <span class=\"ml-3 text-sm\">Files: {{ uploadedFiles.length }} | Progress Map: {{ fileProgress.size }}</span>\n <div class=\"mt-2 text-xs\">\n <div>All Files Uploaded: {{ areAllFilesUploaded() }}</div>\n <div>Save Button Disabled: {{ getSaveButtonDisabled() }}</div>\n <div>Upload Queue Length: {{ getUploadQueueLength() }}</div>\n <div>Currently Uploading: {{ getUploadQueueStatus().isUploading }}</div>\n <div *ngIf=\"getCurrentlyUploadingFile()\" style=\"color: blue; font-weight: bold;\">\n Current File: {{ getCurrentlyUploadingFile()?.name }}\n </div>\n <div *ngIf=\"hasFilesInQueue()\" style=\"color: orange; font-weight: bold;\">\n \u23F3 Files waiting in queue: {{ getUploadQueueLength() }}\n </div>\n </div>\n </div>\n \n <div class=\"grid\">\n <div class=\"col-12 md:col-12\">\n <p-fileUpload \n #fileUploader \n [multiple]=\"true\" \n [auto]=\"false\" \n accept=\"image/png,application/pdf\" \n maxFileSize=\"26214400\"\n (onSelect)=\"onSelectedFiles($event)\"\n >\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\n <div class=\"flex gap-2\">\n <p-button \n (onClick)=\"choose($event, chooseCallback)\" \n icon=\"pi pi-images\" \n [rounded]=\"true\"\n [outlined]=\"true\" \n />\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\n <div class=\"col-12 md:col-12 p-0\">\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\n <div class=\"documentImage\">\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\n class=\"object-contain\" />\n </div>\n <div class=\"flex w-full flex-column mt-2 ml-2\">\n <div class=\"flex justify-content-between\">\n <div style=\"font-weight: bold;font-size: 14px\">\n {{ uploadedFile.file.name }}\n </div>\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\n </div>\n <div class=\"flex justify-content-between mt-1\">\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \n {{ uploadedFile.formattedSize }}\n </div>\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \n {{ uploadedFile.progress }} % \n </div>\n </div>\n </div>\n </div>\n <div class=\"col-12 md:col-12 p-0\">\n <p-progressBar \n [value]=\"uploadedFile.progress\" \n [showValue]=\"false\" \n styleClass=\"h-1/2rem md:ml-auto relative\"\n [ngClass]=\"{ 'exceeded-progress-bar': uploadedFile.progress > 100 }\"\n >\n </p-progressBar>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\n (click)=\"triggerFileUpload()\">\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\n </div>\n </ng-template>\n <ng-template pTemplate=\"file\"> </ng-template>\n </p-fileUpload>\n </div>\n </div>\n </div>\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}.applicant-list{display:none}\n"] }]
3552
- }], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentService }, { type: i3.PrimeNGConfig }, { type: FileFormatService }, { type: i3.MessageService }, { type: i0.ChangeDetectorRef }, { type: DocumentUploadBusinessService }, { type: DocumentUploadFormService }, { type: DocumentUploadDataService }], propDecorators: { contextId: [{
3274
+ args: [{ selector: 'lib-document-upload', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"document-upload-container\">\r\n <!-- Assignment Section -->\r\n <div class=\"assignment-section\">\r\n <h4>Assign to Applicant(s) or Application</h4>\r\n <div class=\"radio-group\">\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Applicant\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'applicant'\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s)</label>\r\n </div>\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Application\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'application'\"\r\n ></p-radioButton>\r\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Applicant Selection (only shown when Applicant is selected) -->\r\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\r\n <h4>Select Applicant(s)</h4>\r\n <div class=\"grid\">\r\n <div \r\n *ngFor=\"let applicant of filteredApplicantList\" \r\n class=\"applicant-item col-12 md:col-6\"\r\n >\r\n <p-radioButton \r\n name=\"selectedApplicant\"\r\n [value]=\"applicant._id\"\r\n [(ngModel)]=\"selectedApplicant\"\r\n [inputId]=\"'applicant-' + applicant._id\"\r\n (onClick)=\"onApplicantSelectionChange()\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\r\n {{ applicant.name }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Category Selection -->\r\n <div class=\"category-section\">\r\n <h4>Category</h4>\r\n <p-dropdown\r\n [options]=\"categoryOptions\"\r\n [(ngModel)]=\"selectedCategory\"\r\n placeholder=\"Select Category type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onCategoryChange()\"\r\n [disabled]=\"!categoryOptions.length\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- Document Type Selection -->\r\n <div class=\"document-type-section\">\r\n <h4>Document Type</h4>\r\n <p-dropdown\r\n [options]=\"documentTypeOptions\"\r\n [(ngModel)]=\"selectedDocumentType\"\r\n placeholder=\"Select Document type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onDocumentTypeChange()\"\r\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- File Upload Section -->\r\n <div class=\"file-upload-section\">\r\n <h4>Upload Documents</h4>\r\n <div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload \r\n #fileUploader \r\n [multiple]=\"true\" \r\n [auto]=\"false\" \r\n accept=\"image/png,application/pdf\" \r\n maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\"\r\n >\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button \r\n (onClick)=\"choose($event, chooseCallback)\" \r\n icon=\"pi pi-images\" \r\n [rounded]=\"true\"\r\n [outlined]=\"true\" \r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\"font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \r\n {{ uploadedFile.formattedSize }}\r\n </div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \r\n {{ uploadedFile.progress }} % \r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar \r\n [value]=\"uploadedFile.progress\" \r\n [showValue]=\"false\" \r\n styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': uploadedFile.progress > 100 }\"\r\n >\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.upload-status{margin-bottom:1rem;padding:.75rem;background-color:#f8f9fa;border-radius:.5rem;border-left:4px solid #0F8BFD}.upload-status .status-message{display:flex;align-items:center;font-size:.9rem;color:#495057}.upload-status .status-message .pi{font-size:1rem}.upload-status .status-message .pi.pi-spinner{color:#0f8bfd}.upload-status .status-message .pi.pi-check-circle{color:#28a745}.upload-status .status-message .pi.pi-clock{color:#ffc107}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-progressbar.error-progress-bar .p-progressbar-value{background-color:#dc3545!important}:host ::ng-deep .p-progressbar.success-progress-bar .p-progressbar-value{background-color:#28a745!important}:host ::ng-deep .p-progressbar.exceeded-progress-bar .p-progressbar-value{background-color:#ffc107!important}.applicant-list{display:none}\n"] }]
3275
+ }], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentService }, { type: i3.PrimeNGConfig }, { type: FileFormatService }, { type: i3.MessageService }, { type: i0.ChangeDetectorRef }, { type: DocumentUploadBusinessService }, { type: DocumentUploadFormService }, { type: DocumentUploadDataService }, { type: DocumentUploadService }], propDecorators: { contextId: [{
3553
3276
  type: Input
3554
3277
  }], fileUploader: [{
3555
3278
  type: ViewChild,