cat-documents-ng 0.2.66 → 0.2.67
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
|
-
*
|
|
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
|
-
|
|
2272
|
+
uploadedFile;
|
|
2280
2273
|
/**
|
|
2281
2274
|
* Represent contextId
|
|
2282
2275
|
* @type {string}
|
|
@@ -2310,47 +2303,15 @@ 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}`);
|
|
2349
2311
|
this.documentUploadStore.setMessage([{
|
|
2350
2312
|
severity: 'info',
|
|
2351
|
-
detail:
|
|
2313
|
+
detail: 'Uploading document...'
|
|
2352
2314
|
}]);
|
|
2353
|
-
console.log(`Calling document service create method for file: ${file.name}`);
|
|
2354
2315
|
this.documentService.create(formsData)
|
|
2355
2316
|
.subscribe({
|
|
2356
2317
|
/**
|
|
@@ -2359,19 +2320,15 @@ class DocumentUploadService {
|
|
|
2359
2320
|
* @returns {void}
|
|
2360
2321
|
*/
|
|
2361
2322
|
next: (event) => {
|
|
2362
|
-
console.log(`=== UPLOAD SUCCESS FOR FILE: ${file.name} ===`);
|
|
2363
|
-
console.log(`Response received:`, event);
|
|
2364
2323
|
this.documentUploadStore.setUploadedDocumentFiles(event);
|
|
2365
2324
|
this.documentUploadStore.setMessage([{
|
|
2366
2325
|
severity: SHARED.SUCCESS_SEVERITY,
|
|
2367
|
-
detail:
|
|
2326
|
+
detail: SHARED.UPLOAD_SUCCESS
|
|
2368
2327
|
}]);
|
|
2369
|
-
console.log(`Emitting uploadCompleted event for file: ${file.name}`);
|
|
2370
2328
|
this.uploadCompleted.emit({ file: file, response: event });
|
|
2371
|
-
this.
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
this.processUploadQueue();
|
|
2329
|
+
if (this.uploadedFile) {
|
|
2330
|
+
// You can emit an event here to update the UI progress if needed
|
|
2331
|
+
}
|
|
2375
2332
|
},
|
|
2376
2333
|
/**
|
|
2377
2334
|
* Handles the error event during file upload.
|
|
@@ -2379,15 +2336,10 @@ class DocumentUploadService {
|
|
|
2379
2336
|
* @param {any} error - The error object returned by the upload service.
|
|
2380
2337
|
*/
|
|
2381
2338
|
error: (error) => {
|
|
2382
|
-
console.
|
|
2383
|
-
console.error('Error details:', error);
|
|
2339
|
+
console.log('Upload service: Upload error for file:', file.name, 'Error:', error);
|
|
2384
2340
|
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
2341
|
},
|
|
2389
2342
|
});
|
|
2390
|
-
console.log(`=== DOCUMENT UPLOAD SERVICE: UPLOAD INITIATED FOR: ${file.name} ===`);
|
|
2391
2343
|
}
|
|
2392
2344
|
/**
|
|
2393
2345
|
* Get the file and contextId
|
|
@@ -2396,6 +2348,7 @@ class DocumentUploadService {
|
|
|
2396
2348
|
*/
|
|
2397
2349
|
getUploadFileData(file, contextId) {
|
|
2398
2350
|
if (file && contextId) {
|
|
2351
|
+
this.uploadedFile = file;
|
|
2399
2352
|
this.contextId = contextId;
|
|
2400
2353
|
}
|
|
2401
2354
|
}
|
|
@@ -2424,49 +2377,6 @@ class DocumentUploadService {
|
|
|
2424
2377
|
return null;
|
|
2425
2378
|
}
|
|
2426
2379
|
}
|
|
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
2380
|
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
2381
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, providedIn: 'root' });
|
|
2472
2382
|
}
|
|
@@ -2987,24 +2897,6 @@ class DocumentUploadComponent {
|
|
|
2987
2897
|
this.businessService = businessService;
|
|
2988
2898
|
this.formService = formService;
|
|
2989
2899
|
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
|
-
});
|
|
3008
2900
|
}
|
|
3009
2901
|
/**
|
|
3010
2902
|
* Handles changes in assignment type selection.
|
|
@@ -3044,21 +2936,11 @@ class DocumentUploadComponent {
|
|
|
3044
2936
|
* @param event - Event containing the selected files
|
|
3045
2937
|
*/
|
|
3046
2938
|
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
2939
|
event.currentFiles.forEach((file, index) => {
|
|
3052
|
-
console.log(
|
|
2940
|
+
console.log('1 file', file);
|
|
3053
2941
|
this.handleTemplatedUpload(file);
|
|
3054
2942
|
});
|
|
3055
|
-
console.log('All files processed, clearing file uploader');
|
|
3056
2943
|
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
2944
|
}
|
|
3063
2945
|
/**
|
|
3064
2946
|
* Loads the list of applicants for the current context.
|
|
@@ -3114,32 +2996,16 @@ class DocumentUploadComponent {
|
|
|
3114
2996
|
* @param file - The file to be uploaded
|
|
3115
2997
|
*/
|
|
3116
2998
|
handleTemplatedUpload(file) {
|
|
3117
|
-
|
|
3118
|
-
if (!this.formService.validateContextId(this.contextId, 'Context ID is required for upload.')) {
|
|
3119
|
-
console.error(`Context ID validation failed for file: ${file.name}`);
|
|
2999
|
+
if (!this.formService.validateContextId(this.contextId, 'Context ID is required for upload.'))
|
|
3120
3000
|
return;
|
|
3121
|
-
}
|
|
3122
|
-
console.log(`File validation passed for: ${file.name}`);
|
|
3123
|
-
console.log(`Context ID: ${this.contextId}`);
|
|
3124
|
-
// Set initial progress
|
|
3125
3001
|
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
3002
|
this.setupFileUploadListener(file);
|
|
3130
|
-
// Start the upload (now goes to queue)
|
|
3131
|
-
console.log(`Adding file to upload queue: ${file.name}`);
|
|
3132
3003
|
this.documentUpload.handleTemplatedUpload(file, this.contextId);
|
|
3133
|
-
// Create uploaded file object
|
|
3134
3004
|
const formattedSize = this.businessService.formatFileSize(file.size, this.config);
|
|
3135
3005
|
const uploadedFile = this.businessService.createUploadedFile(file, formattedSize);
|
|
3136
3006
|
uploadedFile.progress = SHARED.UPLOAD_PROGRESS_10;
|
|
3137
3007
|
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
3008
|
this.validateForm();
|
|
3141
|
-
this.cdr.detectChanges();
|
|
3142
|
-
console.log(`=== FILE ADDED TO UPLOAD QUEUE: ${file.name} ===`);
|
|
3143
3009
|
}
|
|
3144
3010
|
/**
|
|
3145
3011
|
* Removes a document from the uploaded files list.
|
|
@@ -3171,99 +3037,6 @@ class DocumentUploadComponent {
|
|
|
3171
3037
|
const isDisabled = this.businessService.isSaveButtonDisabled(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles, this.isSaving);
|
|
3172
3038
|
return isDisabled;
|
|
3173
3039
|
}
|
|
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
3040
|
/**
|
|
3268
3041
|
* Gets the upload progress for a specific file.
|
|
3269
3042
|
* @param file - The file to get progress for
|
|
@@ -3302,22 +3075,8 @@ class DocumentUploadComponent {
|
|
|
3302
3075
|
this.filteredApplicantList = [];
|
|
3303
3076
|
this.categoryOptions = [];
|
|
3304
3077
|
this.documentTypeOptions = [];
|
|
3305
|
-
// Clear the upload queue
|
|
3306
|
-
if (this.documentUpload.clearUploadQueue) {
|
|
3307
|
-
this.documentUpload.clearUploadQueue();
|
|
3308
|
-
}
|
|
3309
3078
|
this.cdr.detectChanges();
|
|
3310
3079
|
}
|
|
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
3080
|
/**
|
|
3322
3081
|
* Resets form selections (applicant, category, document type).
|
|
3323
3082
|
* Clears document type options.
|
|
@@ -3387,11 +3146,11 @@ class DocumentUploadComponent {
|
|
|
3387
3146
|
this.onUploadSuccess.emit();
|
|
3388
3147
|
}
|
|
3389
3148
|
/**
|
|
3390
|
-
* Handles
|
|
3149
|
+
* Handles upload error.
|
|
3391
3150
|
* Resets saving state.
|
|
3392
|
-
* @param error - The error that occurred during
|
|
3151
|
+
* @param error - The error that occurred during upload
|
|
3393
3152
|
*/
|
|
3394
|
-
|
|
3153
|
+
handleUploadError(error) {
|
|
3395
3154
|
this.isSaving = false;
|
|
3396
3155
|
}
|
|
3397
3156
|
/**
|
|
@@ -3424,7 +3183,7 @@ class DocumentUploadComponent {
|
|
|
3424
3183
|
.pipe(takeUntil(this.destroy$))
|
|
3425
3184
|
.subscribe({
|
|
3426
3185
|
next: (response) => this.handleUploadSuccess(response),
|
|
3427
|
-
error: (error) => this.
|
|
3186
|
+
error: (error) => this.handleUploadError(error)
|
|
3428
3187
|
});
|
|
3429
3188
|
}
|
|
3430
3189
|
/**
|
|
@@ -3433,75 +3192,22 @@ class DocumentUploadComponent {
|
|
|
3433
3192
|
* @param file - The file to monitor for upload completion
|
|
3434
3193
|
*/
|
|
3435
3194
|
setupFileUploadListener(file) {
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
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%
|
|
3195
|
+
this.documentUpload.uploadCompleted.pipe(takeUntil(this.destroy$)).subscribe(({ file: uploadedFile, response }) => {
|
|
3196
|
+
console.log('2 file', file);
|
|
3197
|
+
if (uploadedFile === file) {
|
|
3198
|
+
console.log('3 file', file);
|
|
3455
3199
|
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
3200
|
const uploadedFileObj = this.uploadedFiles.find(uf => uf.file === file);
|
|
3459
3201
|
if (uploadedFileObj) {
|
|
3460
3202
|
uploadedFileObj.uploadResponse = response;
|
|
3461
3203
|
uploadedFileObj.progress = SHARED.UPLOAD_PROGRESS_100;
|
|
3462
3204
|
uploadedFileObj.url = response?.url;
|
|
3463
3205
|
uploadedFileObj.contentType = response?.contentType;
|
|
3464
|
-
console.log(`Uploaded file object updated for: ${file.name}`);
|
|
3465
3206
|
}
|
|
3466
|
-
else {
|
|
3467
|
-
console.warn(`Could not find uploaded file object for: ${file.name}`);
|
|
3468
|
-
}
|
|
3469
|
-
// Trigger change detection and emit validation change
|
|
3470
3207
|
this.cdr.detectChanges();
|
|
3471
3208
|
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
3209
|
}
|
|
3480
3210
|
});
|
|
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
3211
|
}
|
|
3506
3212
|
/**
|
|
3507
3213
|
* Handles errors during data loading operations.
|
|
@@ -3544,11 +3250,11 @@ class DocumentUploadComponent {
|
|
|
3544
3250
|
this.dataService.destroy();
|
|
3545
3251
|
}
|
|
3546
3252
|
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 });
|
|
3253
|
+
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 <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 });
|
|
3548
3254
|
}
|
|
3549
3255
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, decorators: [{
|
|
3550
3256
|
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"] }]
|
|
3257
|
+
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 <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
3258
|
}], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentService }, { type: i3.PrimeNGConfig }, { type: FileFormatService }, { type: i3.MessageService }, { type: i0.ChangeDetectorRef }, { type: DocumentUploadBusinessService }, { type: DocumentUploadFormService }, { type: DocumentUploadDataService }], propDecorators: { contextId: [{
|
|
3553
3259
|
type: Input
|
|
3554
3260
|
}], fileUploader: [{
|