cat-documents-ng 0.2.82 → 0.2.84
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.
|
@@ -1299,7 +1299,8 @@ class DocumentService {
|
|
|
1299
1299
|
* @returns {Observable<any>} Observable that emits the newly created document.
|
|
1300
1300
|
*/
|
|
1301
1301
|
create(entity) {
|
|
1302
|
-
|
|
1302
|
+
const headers = { 'Authorization': 'Bearer 290e45d6-d083-48b8-9798-3056db2ce364' };
|
|
1303
|
+
return this.http.post(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD_FILE}`, entity, { headers }).pipe(tap((newEntity) => this.documentStore.add(newEntity)));
|
|
1303
1304
|
}
|
|
1304
1305
|
/**
|
|
1305
1306
|
* Fetches all documents from the backend.
|
|
@@ -1710,7 +1711,7 @@ class DocumentHttpService {
|
|
|
1710
1711
|
* @returns {Observable<any>} Observable that emits the transformed data for dropdown options.
|
|
1711
1712
|
*/
|
|
1712
1713
|
getDocumentCatagories(contextId) {
|
|
1713
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1714
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1714
1715
|
return this.http.get(`${this.apiUrl}${URLS.DOCUMENTS_CATAGORIES}/${contextId}`, { headers }).pipe(tap((response) => {
|
|
1715
1716
|
// Store only the categories array, not the entire response
|
|
1716
1717
|
if (response && response.categories) {
|
|
@@ -1769,7 +1770,7 @@ class DocumentHttpService {
|
|
|
1769
1770
|
* @returns {Observable<DocumentModel>} An observable that emits the updated DocumentModel.
|
|
1770
1771
|
*/
|
|
1771
1772
|
updateDocumentName(documentId, payload) {
|
|
1772
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1773
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1773
1774
|
return this.http.put(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD}/${documentId}`, payload, { headers }).pipe(catchError((error) => {
|
|
1774
1775
|
return throwError(() => new Error(error));
|
|
1775
1776
|
}));
|
|
@@ -1782,7 +1783,7 @@ class DocumentHttpService {
|
|
|
1782
1783
|
getUserListByContextId(contextId) {
|
|
1783
1784
|
if (!contextId)
|
|
1784
1785
|
return EMPTY;
|
|
1785
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1786
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1786
1787
|
return this.http.get(`${this.apiUrl}${URLS.USERLIST}${contextId}`, { headers }).pipe(tap((userList) => {
|
|
1787
1788
|
this.documentStore.setUserList(userList);
|
|
1788
1789
|
}), catchError((error) => {
|
|
@@ -1808,7 +1809,7 @@ class DocumentHttpService {
|
|
|
1808
1809
|
if (categoryId) {
|
|
1809
1810
|
params = params.set(SHARED.CATEGORY, categoryId);
|
|
1810
1811
|
}
|
|
1811
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1812
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1812
1813
|
return this.http.get(url, { params, headers }).pipe(tap((statusData) => {
|
|
1813
1814
|
this.documentStore.setStatusData(statusData);
|
|
1814
1815
|
}), catchError((error) => {
|
|
@@ -1839,7 +1840,7 @@ class DocumentHttpService {
|
|
|
1839
1840
|
if (searchKey) {
|
|
1840
1841
|
params = params.set(SHARED.SEARCH_KEY, searchKey);
|
|
1841
1842
|
}
|
|
1842
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1843
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1843
1844
|
return this.http.get(`${this.apiUrl}${URLS.GETALL}/${contextId}`, { params, headers }).pipe(tap((response) => {
|
|
1844
1845
|
if (response.documents) {
|
|
1845
1846
|
this.documentStore.setDocumentList(response.documents);
|
|
@@ -1852,7 +1853,7 @@ class DocumentHttpService {
|
|
|
1852
1853
|
if (!documentId) {
|
|
1853
1854
|
return of([]);
|
|
1854
1855
|
}
|
|
1855
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1856
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1856
1857
|
return this.http.get(`${this.apiUrl}${URLS.DOCUMENT_HISTORY}${documentId}`, { headers });
|
|
1857
1858
|
}
|
|
1858
1859
|
/**
|
|
@@ -1863,7 +1864,7 @@ class DocumentHttpService {
|
|
|
1863
1864
|
getCategoriesBySource(source) {
|
|
1864
1865
|
if (!source)
|
|
1865
1866
|
return EMPTY;
|
|
1866
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1867
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1867
1868
|
return this.http.get(`${this.apiUrl}${URLS.GET_CATEGORIES_BY_SOURCE}${source}`, { headers }).pipe(catchError((error) => {
|
|
1868
1869
|
return throwError(() => new Error(error));
|
|
1869
1870
|
}));
|
|
@@ -1876,7 +1877,7 @@ class DocumentHttpService {
|
|
|
1876
1877
|
getDocumentTypesByCategory(categoryId) {
|
|
1877
1878
|
if (!categoryId)
|
|
1878
1879
|
return EMPTY;
|
|
1879
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1880
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1880
1881
|
return this.http.get(`${this.apiUrl}${URLS.GET_DOCUMENT_TYPES_BY_CATEGORY}${categoryId}`, { headers }).pipe(catchError((error) => {
|
|
1881
1882
|
return throwError(() => new Error(error));
|
|
1882
1883
|
}));
|
|
@@ -1887,7 +1888,7 @@ class DocumentHttpService {
|
|
|
1887
1888
|
* @returns {Observable<any>} Observable that emits the upload response.
|
|
1888
1889
|
*/
|
|
1889
1890
|
uploadFile(formData) {
|
|
1890
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1891
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1891
1892
|
return this.http.post(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD_FILE}`, formData, { headers }).pipe(catchError((error) => {
|
|
1892
1893
|
return throwError(() => new Error(error));
|
|
1893
1894
|
}));
|
|
@@ -1898,7 +1899,7 @@ class DocumentHttpService {
|
|
|
1898
1899
|
* @returns {Observable<any>} Observable that emits the save response.
|
|
1899
1900
|
*/
|
|
1900
1901
|
saveDocumentUpload(payload) {
|
|
1901
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1902
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1902
1903
|
return this.http.post(`${this.apiUrl}${URLS.SAVE_DOCUMENT_UPLOAD}`, payload, { headers }).pipe(catchError((error) => {
|
|
1903
1904
|
return throwError(() => new Error(error));
|
|
1904
1905
|
}));
|
|
@@ -1914,7 +1915,7 @@ class DocumentHttpService {
|
|
|
1914
1915
|
const payload = {
|
|
1915
1916
|
statusUpdateDescription: statusUpdateDescription
|
|
1916
1917
|
};
|
|
1917
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1918
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1918
1919
|
return this.http.put(`${this.apiUrl}${URLS.UPDATE_DOCUMENT_STATUS}${documentId}/${status}`, payload, { headers }).pipe(tap((response) => {
|
|
1919
1920
|
if (response && response.status) {
|
|
1920
1921
|
const normalizedStatus = this.normalizeStatus(response.status);
|
|
@@ -1948,7 +1949,7 @@ class DocumentHttpService {
|
|
|
1948
1949
|
* @returns {Observable<any>} Observable that emits the delete response
|
|
1949
1950
|
*/
|
|
1950
1951
|
deleteDocument(documentId, contextId) {
|
|
1951
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1952
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 290e45d6-d083-48b8-9798-3056db2ce364` });
|
|
1952
1953
|
return this.http.delete(`${this.apiUrl}${URLS.DELETE_DOCUMENT}${documentId}`, { headers }).pipe(tap(() => {
|
|
1953
1954
|
this.getDocumentCatagories(contextId).subscribe();
|
|
1954
1955
|
this.getUserListByContextId(contextId).subscribe();
|
|
@@ -2888,46 +2889,57 @@ class DocumentUploadComponent {
|
|
|
2888
2889
|
onApplicantSelectionChange() { this.validateAndEmit(); }
|
|
2889
2890
|
/**
|
|
2890
2891
|
* Handles file selection from the file upload component.
|
|
2891
|
-
*
|
|
2892
|
+
* Processes all selected files in parallel for templated upload.
|
|
2892
2893
|
* @param event - Event containing the selected files
|
|
2893
2894
|
*/
|
|
2894
2895
|
async onSelectedFiles(event) {
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
for (let i = 0; i < event.currentFiles.length; i++) {
|
|
2914
|
-
const file = event.currentFiles[i];
|
|
2915
|
-
const actualIndex = startIndex + i; // Calculate the actual index in the array
|
|
2916
|
-
try {
|
|
2917
|
-
await this.handleTemplatedUpload(file, actualIndex);
|
|
2918
|
-
}
|
|
2919
|
-
catch (error) {
|
|
2920
|
-
console.error(`Failed to upload file ${i + 1}/${event.currentFiles.length}: ${file.name}`, error);
|
|
2921
|
-
if (this.uploadedFiles[actualIndex]) {
|
|
2922
|
-
this.uploadedFiles[actualIndex].hasError = true;
|
|
2923
|
-
this.uploadedFiles[actualIndex].isUploading = false;
|
|
2924
|
-
this.uploadedFiles[actualIndex].progress = -1;
|
|
2896
|
+
if (!event.currentFiles.length)
|
|
2897
|
+
return;
|
|
2898
|
+
try {
|
|
2899
|
+
// Create upload promises for all files
|
|
2900
|
+
const uploadPromises = event.currentFiles.map(file => this.handleTemplatedUpload(file));
|
|
2901
|
+
// Execute all uploads in parallel
|
|
2902
|
+
const results = await Promise.allSettled(uploadPromises);
|
|
2903
|
+
// Process results and handle any failures
|
|
2904
|
+
let successCount = 0;
|
|
2905
|
+
let failureCount = 0;
|
|
2906
|
+
results.forEach((result, index) => {
|
|
2907
|
+
const file = event.currentFiles[index];
|
|
2908
|
+
if (result.status === 'fulfilled') {
|
|
2909
|
+
successCount++;
|
|
2910
|
+
}
|
|
2911
|
+
else {
|
|
2912
|
+
failureCount++;
|
|
2913
|
+
console.error(`Failed to upload file ${index + 1}/${event.currentFiles.length}: ${file.name}`, result.reason);
|
|
2925
2914
|
}
|
|
2915
|
+
});
|
|
2916
|
+
// Show summary message if there were failures
|
|
2917
|
+
if (failureCount > 0) {
|
|
2918
|
+
this.messageService.add({
|
|
2919
|
+
severity: 'warn',
|
|
2920
|
+
summary: 'Upload Summary',
|
|
2921
|
+
detail: `${successCount} file(s) uploaded successfully, ${failureCount} file(s) failed.`
|
|
2922
|
+
});
|
|
2923
|
+
}
|
|
2924
|
+
else if (successCount > 0) {
|
|
2925
|
+
this.messageService.add({
|
|
2926
|
+
severity: 'success',
|
|
2927
|
+
summary: 'Upload Complete',
|
|
2928
|
+
detail: `All ${successCount} file(s) uploaded successfully.`
|
|
2929
|
+
});
|
|
2926
2930
|
}
|
|
2927
2931
|
}
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2932
|
+
catch (error) {
|
|
2933
|
+
console.error('Unexpected error during file uploads:', error);
|
|
2934
|
+
this.messageService.add({
|
|
2935
|
+
severity: 'error',
|
|
2936
|
+
summary: 'Upload Error',
|
|
2937
|
+
detail: 'An unexpected error occurred during file uploads.'
|
|
2938
|
+
});
|
|
2939
|
+
}
|
|
2940
|
+
finally {
|
|
2941
|
+
this.fileUploader.clear();
|
|
2942
|
+
}
|
|
2931
2943
|
}
|
|
2932
2944
|
/**
|
|
2933
2945
|
* Loads the list of applicants for the current context.
|
|
@@ -2979,64 +2991,42 @@ class DocumentUploadComponent {
|
|
|
2979
2991
|
}
|
|
2980
2992
|
/**
|
|
2981
2993
|
* Handles templated upload for a single file.
|
|
2982
|
-
* Sets up progress tracking and upload listener for the file.
|
|
2983
2994
|
* @param file - The file to be uploaded
|
|
2984
|
-
* @param index - The index of the file in the uploadedFiles array
|
|
2985
2995
|
*/
|
|
2986
|
-
async handleTemplatedUpload(file
|
|
2996
|
+
async handleTemplatedUpload(file) {
|
|
2987
2997
|
if (!this.formService.validateContextId(this.contextId, 'Context ID is required for upload.'))
|
|
2988
2998
|
return;
|
|
2989
|
-
//
|
|
2990
|
-
this.
|
|
2999
|
+
// Add file with initial state
|
|
3000
|
+
const fileIndex = this.uploadedFiles.length;
|
|
3001
|
+
this.uploadedFiles.push({
|
|
3002
|
+
file,
|
|
3003
|
+
formattedSize: this.businessService.formatFileSize(file.size, this.config),
|
|
3004
|
+
progress: SHARED.UPLOAD_PROGRESS_10,
|
|
3005
|
+
uploadResponse: { fileName: file.name, contentType: file.type, url: '', size: this.businessService.formatFileSize(file.size, this.config) },
|
|
3006
|
+
url: undefined,
|
|
3007
|
+
});
|
|
3008
|
+
this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_10);
|
|
2991
3009
|
try {
|
|
2992
3010
|
const response = await this.documentUploadService.uploadFile(file, this.contextId);
|
|
2993
|
-
// Update
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
progress: 100,
|
|
3011
|
+
// Update file with completed state
|
|
3012
|
+
this.uploadedFiles[fileIndex] = {
|
|
3013
|
+
...this.uploadedFiles[fileIndex],
|
|
3014
|
+
progress: SHARED.UPLOAD_PROGRESS_100,
|
|
2998
3015
|
uploadResponse: response,
|
|
2999
3016
|
url: response.url,
|
|
3000
3017
|
contentType: response.contentType,
|
|
3001
3018
|
fileName: response.fileName,
|
|
3002
|
-
size: response.size
|
|
3003
|
-
isUploading: false,
|
|
3004
|
-
hasError: false
|
|
3019
|
+
size: response.size
|
|
3005
3020
|
};
|
|
3006
|
-
|
|
3007
|
-
this.
|
|
3008
|
-
this.
|
|
3009
|
-
this.cdr.detectChanges();
|
|
3021
|
+
this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_100);
|
|
3022
|
+
this.validateForm();
|
|
3023
|
+
this.onFormValidationChange.emit();
|
|
3010
3024
|
}
|
|
3011
3025
|
catch (error) {
|
|
3012
|
-
|
|
3013
|
-
this.uploadedFiles[index].hasError = true;
|
|
3014
|
-
this.uploadedFiles[index].isUploading = false;
|
|
3015
|
-
this.uploadedFiles[index].progress = 0;
|
|
3016
|
-
this.fileProgress.set(file, 0);
|
|
3017
|
-
this.cdr.detectChanges();
|
|
3026
|
+
this.fileProgress.set(file, -1);
|
|
3018
3027
|
console.error('Upload failed:', error);
|
|
3019
3028
|
}
|
|
3020
3029
|
}
|
|
3021
|
-
/**
|
|
3022
|
-
* Starts smooth progress animation for a file upload from 0 to 90.
|
|
3023
|
-
* @param file - The file being uploaded
|
|
3024
|
-
* @param index - The index of the file in uploadedFiles array
|
|
3025
|
-
*/
|
|
3026
|
-
startSmoothProgress(file, index) {
|
|
3027
|
-
let progress = 0;
|
|
3028
|
-
const progressInterval = setInterval(() => {
|
|
3029
|
-
if (progress < 90) {
|
|
3030
|
-
progress += 2; // Smooth increment of 2%
|
|
3031
|
-
this.uploadedFiles[index].progress = progress;
|
|
3032
|
-
this.fileProgress.set(file, progress);
|
|
3033
|
-
this.cdr.detectChanges();
|
|
3034
|
-
}
|
|
3035
|
-
else {
|
|
3036
|
-
clearInterval(progressInterval);
|
|
3037
|
-
}
|
|
3038
|
-
}, 100); // Update every 100ms for smooth progress
|
|
3039
|
-
}
|
|
3040
3030
|
/**
|
|
3041
3031
|
* Removes a document from the uploaded files list.
|
|
3042
3032
|
* Updates progress tracking and validates form.
|
|
@@ -3044,11 +3034,8 @@ class DocumentUploadComponent {
|
|
|
3044
3034
|
* @param index - The index of the file in the uploaded files array
|
|
3045
3035
|
*/
|
|
3046
3036
|
handleDocumentRemove(file, index) {
|
|
3047
|
-
// Clean up progress tracking
|
|
3048
|
-
this.fileProgress.delete(file);
|
|
3049
|
-
// Remove from uploaded files array
|
|
3050
3037
|
this.uploadedFiles.splice(index, 1);
|
|
3051
|
-
|
|
3038
|
+
this.fileProgress.delete(file);
|
|
3052
3039
|
this.validateAndEmit();
|
|
3053
3040
|
this.cdr.detectChanges();
|
|
3054
3041
|
}
|
|
@@ -3075,10 +3062,7 @@ class DocumentUploadComponent {
|
|
|
3075
3062
|
* @param file - The file to get progress for
|
|
3076
3063
|
* @returns The upload progress percentage (0-100)
|
|
3077
3064
|
*/
|
|
3078
|
-
getProgress(file) {
|
|
3079
|
-
const progress = this.fileProgress.get(file);
|
|
3080
|
-
return progress !== undefined ? progress : 0;
|
|
3081
|
-
}
|
|
3065
|
+
getProgress(file) { return this.fileProgress.get(file) || 0; }
|
|
3082
3066
|
/**
|
|
3083
3067
|
* Checks if a file is currently uploading.
|
|
3084
3068
|
* @param file - The file to check
|
|
@@ -3086,66 +3070,20 @@ class DocumentUploadComponent {
|
|
|
3086
3070
|
*/
|
|
3087
3071
|
isFileUploading(file) {
|
|
3088
3072
|
const progress = this.fileProgress.get(file);
|
|
3089
|
-
return progress !== undefined && progress > 0 && progress <
|
|
3073
|
+
return progress !== undefined && progress > 0 && progress < SHARED.UPLOAD_PROGRESS_100;
|
|
3090
3074
|
}
|
|
3091
3075
|
/**
|
|
3092
3076
|
* Checks if a file has been successfully uploaded.
|
|
3093
3077
|
* @param file - The file to check
|
|
3094
3078
|
* @returns True if the file is uploaded, false otherwise
|
|
3095
3079
|
*/
|
|
3096
|
-
isFileUploaded(file) { return this.fileProgress.get(file) ===
|
|
3080
|
+
isFileUploaded(file) { return this.fileProgress.get(file) === SHARED.UPLOAD_PROGRESS_100; }
|
|
3097
3081
|
/**
|
|
3098
3082
|
* Checks if a file upload encountered an error.
|
|
3099
3083
|
* @param file - The file to check
|
|
3100
3084
|
* @returns True if the file has an error, false otherwise
|
|
3101
3085
|
*/
|
|
3102
|
-
isFileError(file) {
|
|
3103
|
-
const progress = this.fileProgress.get(file);
|
|
3104
|
-
const uploadedFile = this.uploadedFiles.find(uf => uf.file === file);
|
|
3105
|
-
return progress === 0 && uploadedFile?.hasError === true;
|
|
3106
|
-
}
|
|
3107
|
-
/**
|
|
3108
|
-
* Gets the number of files currently uploading.
|
|
3109
|
-
* @returns The count of files currently being uploaded
|
|
3110
|
-
*/
|
|
3111
|
-
getUploadingCount() {
|
|
3112
|
-
return this.uploadedFiles.filter(file => file.isUploading).length;
|
|
3113
|
-
}
|
|
3114
|
-
/**
|
|
3115
|
-
* Gets the number of files that have been successfully uploaded.
|
|
3116
|
-
* @returns The count of successfully uploaded files
|
|
3117
|
-
*/
|
|
3118
|
-
getUploadedCount() {
|
|
3119
|
-
return this.uploadedFiles.filter(file => file.progress === 100 && !file.hasError).length;
|
|
3120
|
-
}
|
|
3121
|
-
/**
|
|
3122
|
-
* Gets the number of files that failed to upload.
|
|
3123
|
-
* @returns The count of failed uploads
|
|
3124
|
-
*/
|
|
3125
|
-
getFailedCount() {
|
|
3126
|
-
return this.uploadedFiles.filter(file => file.hasError).length;
|
|
3127
|
-
}
|
|
3128
|
-
/**
|
|
3129
|
-
* Gets the total number of files in the upload queue.
|
|
3130
|
-
* @returns The total count of files (uploading + uploaded + failed)
|
|
3131
|
-
*/
|
|
3132
|
-
getTotalCount() {
|
|
3133
|
-
return this.uploadedFiles.length;
|
|
3134
|
-
}
|
|
3135
|
-
/**
|
|
3136
|
-
* Checks if there are any files currently uploading.
|
|
3137
|
-
* @returns True if any files are uploading, false otherwise
|
|
3138
|
-
*/
|
|
3139
|
-
hasUploadingFiles() {
|
|
3140
|
-
return this.getUploadingCount() > 0;
|
|
3141
|
-
}
|
|
3142
|
-
/**
|
|
3143
|
-
* Checks if all files have completed (either uploaded or failed).
|
|
3144
|
-
* @returns True if all files have completed, false otherwise
|
|
3145
|
-
*/
|
|
3146
|
-
allFilesCompleted() {
|
|
3147
|
-
return this.getTotalCount() > 0 && this.getUploadingCount() === 0;
|
|
3148
|
-
}
|
|
3086
|
+
isFileError(file) { return this.fileProgress.get(file) === -1; }
|
|
3149
3087
|
/**
|
|
3150
3088
|
* Resets the form to its initial state.
|
|
3151
3089
|
* Clears all selections, uploaded files, and progress tracking.
|
|
@@ -3157,7 +3095,6 @@ class DocumentUploadComponent {
|
|
|
3157
3095
|
this.filteredApplicantList = [];
|
|
3158
3096
|
this.categoryOptions = [];
|
|
3159
3097
|
this.documentTypeOptions = [];
|
|
3160
|
-
this.uploadedFiles = [];
|
|
3161
3098
|
this.cdr.detectChanges();
|
|
3162
3099
|
}
|
|
3163
3100
|
/**
|
|
@@ -3310,11 +3247,11 @@ class DocumentUploadComponent {
|
|
|
3310
3247
|
this.dataService.destroy();
|
|
3311
3248
|
}
|
|
3312
3249
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, deps: [{ token: DocumentUploadService }, { token: i3.PrimeNGConfig }, { token: FileFormatService }, { token: i3.MessageService }, { token: i0.ChangeDetectorRef }, { token: DocumentUploadBusinessService }, { token: DocumentUploadFormService }, { token: DocumentUploadDataService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3313
|
-
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 <!-- Upload Status Summary -->\n <div class=\"upload-status-summary\" *ngIf=\"getTotalCount() > 0\">\n <div class=\"status-grid\">\n <div class=\"status-item\">\n <span class=\"status-label\">Total Files:</span>\n <span class=\"status-value\">{{ getTotalCount() }}</span>\n </div>\n <div class=\"status-item\" *ngIf=\"getUploadingCount() > 0\">\n <span class=\"status-label\">Uploading:</span>\n <span class=\"status-value uploading\">{{ getUploadingCount() }}</span>\n </div>\n <div class=\"status-item\" *ngIf=\"getUploadedCount() > 0\">\n <span class=\"status-label\">Uploaded:</span>\n <span class=\"status-value uploaded\">{{ getUploadedCount() }}</span>\n </div>\n <div class=\"status-item\" *ngIf=\"getFailedCount() > 0\">\n <span class=\"status-label\">Failed:</span>\n <span class=\"status-value failed\">{{ getFailedCount() }}</span>\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=\"true\" \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.fileName || 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;\" \n [ngClass]=\"{\n 'text-green-500': uploadedFile.progress === 100 && !uploadedFile.hasError,\n 'text-blue-500': uploadedFile.isUploading,\n 'text-red-500': uploadedFile.hasError\n }\">\n <i [class]=\"{\n 'pi pi-verified': uploadedFile.progress === 100 && !uploadedFile.hasError,\n 'pi pi-spin pi-spinner': uploadedFile.isUploading,\n 'pi pi-exclamation-triangle': uploadedFile.hasError\n }\"></i>\n {{ uploadedFile.formattedSize }}\n </div>\n <div class=\"white-space-nowrap\" \n [ngClass]=\"{\n 'text-green-500': uploadedFile.progress === 100 && !uploadedFile.hasError,\n 'text-blue-500': uploadedFile.isUploading,\n 'text-red-500': uploadedFile.hasError\n }\" \n style=\"font-family: 14px;\"> \n <span *ngIf=\"uploadedFile.hasError\">Upload Failed</span>\n <span *ngIf=\"!uploadedFile.hasError && uploadedFile.progress === 100\">Uploaded</span>\n <span *ngIf=\"!uploadedFile.hasError && uploadedFile.progress < 100\">{{ uploadedFile.progress }}%</span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-12 md:col-12 p-0\">\n <p-progressBar \n [value]=\"uploadedFile.hasError ? 0 : uploadedFile.progress\" \n [showValue]=\"false\" \n styleClass=\"h-1/2rem md:ml-auto relative\"\n [ngClass]=\"{\n 'exceeded-progress-bar': uploadedFile.progress > 100,\n 'error-progress-bar': uploadedFile.hasError\n }\"\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}.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}.upload-status-summary{background-color:#f8f9fa;border-radius:.5rem;padding:1rem;margin-bottom:1rem;border:1px solid #e9ecef}.upload-status-summary .status-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:1rem;align-items:center}.upload-status-summary .status-item{display:flex;flex-direction:column;align-items:center;text-align:center}.upload-status-summary .status-item .status-label{font-size:.8rem;color:#6c757d;margin-bottom:.25rem;font-weight:500}.upload-status-summary .status-item .status-value{font-size:1.5rem;font-weight:600;color:#212529}.upload-status-summary .status-item .status-value.uploading{color:#0f8bfd}.upload-status-summary .status-item .status-value.uploaded{color:#28a745}.upload-status-summary .status-item .status-value.failed{color:#dc3545}.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}.error-progress-bar .p-progressbar-value{background-color:#dc3545!important}.text-green-500{color:#28a745!important}.text-blue-500{color:#0f8bfd!important}.text-red-500{color:#dc3545!important}.pi-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\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: i9.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: i10.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i11.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: i13.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 });
|
|
3250
|
+
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=\"true\" \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 && 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}.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: i9.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: i10.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i11.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: i13.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 });
|
|
3314
3251
|
}
|
|
3315
3252
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, decorators: [{
|
|
3316
3253
|
type: Component,
|
|
3317
|
-
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 <!-- Upload Status Summary -->\n <div class=\"upload-status-summary\" *ngIf=\"getTotalCount() > 0\">\n <div class=\"status-grid\">\n <div class=\"status-item\">\n <span class=\"status-label\">Total Files:</span>\n <span class=\"status-value\">{{ getTotalCount() }}</span>\n </div>\n <div class=\"status-item\" *ngIf=\"getUploadingCount() > 0\">\n <span class=\"status-label\">Uploading:</span>\n <span class=\"status-value uploading\">{{ getUploadingCount() }}</span>\n </div>\n <div class=\"status-item\" *ngIf=\"getUploadedCount() > 0\">\n <span class=\"status-label\">Uploaded:</span>\n <span class=\"status-value uploaded\">{{ getUploadedCount() }}</span>\n </div>\n <div class=\"status-item\" *ngIf=\"getFailedCount() > 0\">\n <span class=\"status-label\">Failed:</span>\n <span class=\"status-value failed\">{{ getFailedCount() }}</span>\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=\"true\" \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.fileName || 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;\" \n [ngClass]=\"{\n 'text-green-500': uploadedFile.progress === 100 && !uploadedFile.hasError,\n 'text-blue-500': uploadedFile.isUploading,\n 'text-red-500': uploadedFile.hasError\n }\">\n <i [class]=\"{\n 'pi pi-verified': uploadedFile.progress === 100 && !uploadedFile.hasError,\n 'pi pi-spin pi-spinner': uploadedFile.isUploading,\n 'pi pi-exclamation-triangle': uploadedFile.hasError\n }\"></i>\n {{ uploadedFile.formattedSize }}\n </div>\n <div class=\"white-space-nowrap\" \n [ngClass]=\"{\n 'text-green-500': uploadedFile.progress === 100 && !uploadedFile.hasError,\n 'text-blue-500': uploadedFile.isUploading,\n 'text-red-500': uploadedFile.hasError\n }\" \n style=\"font-family: 14px;\"> \n <span *ngIf=\"uploadedFile.hasError\">Upload Failed</span>\n <span *ngIf=\"!uploadedFile.hasError && uploadedFile.progress === 100\">Uploaded</span>\n <span *ngIf=\"!uploadedFile.hasError && uploadedFile.progress < 100\">{{ uploadedFile.progress }}%</span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-12 md:col-12 p-0\">\n <p-progressBar \n [value]=\"uploadedFile.hasError ? 0 : uploadedFile.progress\" \n [showValue]=\"false\" \n styleClass=\"h-1/2rem md:ml-auto relative\"\n [ngClass]=\"{\n 'exceeded-progress-bar': uploadedFile.progress > 100,\n 'error-progress-bar': uploadedFile.hasError\n }\"\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}.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}.upload-status-summary{background-color:#f8f9fa;border-radius:.5rem;padding:1rem;margin-bottom:1rem;border:1px solid #e9ecef}.upload-status-summary .status-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:1rem;align-items:center}.upload-status-summary .status-item{display:flex;flex-direction:column;align-items:center;text-align:center}.upload-status-summary .status-item .status-label{font-size:.8rem;color:#6c757d;margin-bottom:.25rem;font-weight:500}.upload-status-summary .status-item .status-value{font-size:1.5rem;font-weight:600;color:#212529}.upload-status-summary .status-item .status-value.uploading{color:#0f8bfd}.upload-status-summary .status-item .status-value.uploaded{color:#28a745}.upload-status-summary .status-item .status-value.failed{color:#dc3545}.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}.error-progress-bar .p-progressbar-value{background-color:#dc3545!important}.text-green-500{color:#28a745!important}.text-blue-500{color:#0f8bfd!important}.text-red-500{color:#dc3545!important}.pi-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
3254
|
+
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=\"true\" \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 && 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}.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"] }]
|
|
3318
3255
|
}], ctorParameters: () => [{ type: DocumentUploadService }, { type: i3.PrimeNGConfig }, { type: FileFormatService }, { type: i3.MessageService }, { type: i0.ChangeDetectorRef }, { type: DocumentUploadBusinessService }, { type: DocumentUploadFormService }, { type: DocumentUploadDataService }], propDecorators: { contextId: [{
|
|
3319
3256
|
type: Input
|
|
3320
3257
|
}], fileUploader: [{
|