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
|
-
*
|
|
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,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
|
-
|
|
2311
|
+
// Update progress to show upload starting
|
|
2349
2312
|
this.documentUploadStore.setMessage([{
|
|
2350
2313
|
severity: 'info',
|
|
2351
|
-
detail:
|
|
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:
|
|
2327
|
+
detail: SHARED.UPLOAD_SUCCESS
|
|
2368
2328
|
}]);
|
|
2369
|
-
|
|
2329
|
+
// Emit upload completion event with file and response
|
|
2370
2330
|
this.uploadCompleted.emit({ file: file, response: event });
|
|
2371
|
-
this.
|
|
2372
|
-
|
|
2373
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
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
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
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
|
|
3168
|
+
* Handles upload error.
|
|
3391
3169
|
* Resets saving state.
|
|
3392
|
-
* @param error - The error that occurred during
|
|
3170
|
+
* @param error - The error that occurred during upload
|
|
3393
3171
|
*/
|
|
3394
|
-
|
|
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.
|
|
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
|
-
|
|
3437
|
-
|
|
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,
|